From 38a1ab4ff1b32196b800cd29f16561d409fbfd5a Mon Sep 17 00:00:00 2001 From: "Gustavo \"Guz\" L de Mello" Date: Tue, 26 Aug 2025 16:03:13 -0300 Subject: [PATCH] docs(readme): about the package --- README.md | 162 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 158 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 3603712..097a119 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,170 @@ # ![Smalltrip](./docs/assets/logo.svg) +A small package to help on your routes, fully compatible to Go's standard library +[`net/http`](https://pkg.go.dev/net/http). +```go +package main + +import ( + "encoding/json" + "net/http" + "os" + "slog" + "time" + + "forge.capytal.company/loreddev/smalltrip" + "forge.capytal.company/loreddev/smalltrip/middleware" + "forge.capytal.company/loreddev/smalltrip/multiplexer" + "forge.capytal.company/loreddev/smalltrip/problem" +) + +func main() { + mux := multiplexer.New() + + mux = problem.Multiplexer(mux) + + mux = multiplexer.WithPatternRules(mux, + multiplexer.EnsureMethod(), + multiplexer.EnsureStrictEnd(), + multiplexer.EnsureTrailingSlash(), + ) + + log := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelInfo})) + + router := smalltrip.NewRouter(smalltrip.WithMultiplexer(mux)) + + router.Use(middleware.Logger(log.WithGroup("requests"))) + router.Use(middleware.Cache(middleware.CacheMaxAge(time.Second * 10))) + + router.HandleFunc("GET /hello/{$}", func(w http.ResponseWriter, r *http.Request) { + data := struct { + Message string `json:"message"` + }{ + Message: "Hello, World", + } + + b, err := json.Marshal(data) + if err != nil { + problem.NewInternalServerError(err).ServeHTTP(w, r) + return + } + + w.WriteHeader(http.StatusOK) + _, err = w.Write(b) + if err != nil { + problem.NewInternalServerError(err).ServeHTTP(w, r) + return + } + }) + + srv := http.Server{ + Addr: "localhost:8080", + Handler: router, + } + + // Start server... +} +``` + +> [!WARNING] +> **Here be dragons.** +> +> Smalltrip is still in very early development and is still a Work In Progress (WIP). +> It is being dog-feed on [Capytal's](https://forge.capytal.company/capytalcode) and +> [Lored's](https://forge.capytal.company/loreddev) projects, and most (if not all) +> of the development is focused on creating features for said projects as they are needed. +> +> Expect bugs, incomplete documentation, and breaking changes if you are going to +> use this package. + +## About + +Smalltrip is, as the name implies, a small Go (Golang) package focused on helping your HTTP routing, +request validation, responses building, and error handling. The way it accomplishes this +objective is by extending the standard library's `net/http` package and providing utility +functions, middleware and APIs to better structure how routes are made and managed. + +### Features + +- Fully compatible and built on top the standard library's `net/http`; +- Utility APIs to improve code structure and reduce repetition: + - Rules and options for [`http.ServerMux`](https://pkg.go.dev/net/http#ServeMux) patterns; + - Router API with support for `func(http.Handler) http.Handler` middlewares; + - Out-of-the-box middlewares for logging, panic recovering, caching, etc.; + - Error handling structs, following [RFC 9457 "Problems Details for HTTP APIs"](https://datatracker.ietf.org/doc/rfc9457); + - Ready-for-use 400s and 500s error codes, with parameters for required response headers; + - Defined interfaces for common patterns and standard library structs. +- Small code footprint and vendor lock-in; +- Customizable behaviour of APIs via functional options; +- Extendable via interfaces and dependency-injection; +- ~~**W.I.P.** Fully documented API.~~ + +### Why Another Package? + +Most web frameworks and libraries in the Go ecosystem focus on creating a full overhaul on +how requests are handled, at least compared to what the language provides out-of-the-box. This +overhaul is normally done by completely ignoring the standard library's conventions and APIs, +using multiple dependencies, and/or abstracting all request handling behind some sort of context +structure. + +We prefer to keep our projects as most dependency-free as possible and use the most of the language +conventions as possible, minimizing the amount of vendor lock-in that they have. That's why Go +has become our language of choice in the first place, since it's standard library already gives +so much, that we don't need to rely on other packages to do solve most problems. + +However, the `net/http` package is not perfect, since it is in the standard library, it can't +give a lot of "convenience APIs" which would cause disagreement on the community as a whole. Most +of the APIs provided are a small abstraction on top of the HTTP protocol, which means subjects +such as error handling, middlewares, caching, logging, etc. are meant to the developer to choose how +to handle. In small projects this is fine and manually setting up HTTP error status codes in each request, +setting up common headers, and checking up [`http.ServerMux`](https://pkg.go.dev/net/http#ServeMux) patterns +isn't too big of a deal. But as projects grows and more developers contribute, the unstructured +nature of `net/http` starts to be a problem and conventions, abstractions and utility functions +will need to be created to make sure every HTTP handler has a similar structure. + +Also, since the standard package is just an abstraction on top of the HTTP specification, other +useful W3C recommendations, proposed standards, and common web development conventions aren't backed-in. +Which means things such as, for example, [RFC 9457 "Problem Details for HTTP APIs"](https://datatracker.ietf.org/doc/rfc9457), +needs to be hard-coded in each request or have an abstraction implemented from scratch. + +Smalltrip is Lored's (and Capytal's) decisions of said conventions, abstractions, utility functions and +response to the standard library's shortcomings. **It is then, by nature, very opinionated.** + +### Should I Use This? + +As mentioned above and as the time of writing, **this package is still in a unstable state and we +not recommend using it on any production code**. You may play with the package or use in non-critical +projects and code, mostly so you don't need to write middleware support, error handling, etc. as +a heads-up. Also you could use it as inspiration for your own conventions on top of the `net/http` +package. + +We use on our own projects, because we can easily just fix or change the API without having to worry +about breaking changes, updating, or how it will affect other users. This is mostly a source-available +project with a permissive license, not a open-source project with community support and contributing +at it's core. **Breaking changes will be introduced if it means a better experience on for our developers +and needs**. See the ["Contributing" section](#contributing) for more details. + +> [!TIP] +> If you still want to use it, we recommend using it by copying the parts of source code you want +> to use directly to your project, or vendor it under your organization by forking this repository and +> making any changes you deemed necessary. This way you have a more stable experience and don't need +> to worry about managing unstable versions, breaking changes, and incomplete APIs. ## Licenses Copyright © 2025-present Gustavo "Guz" L. de Mello & The Lored.dev Contributors -Source-code is licensed and distributed under the [Apache License (Version 2.0)](./LICENSE). +Source-code and code samples are licensed and distributed under the [Apache License (Version 2.0)](./LICENSE). -The "Smalltrip.go" logo is licensed under the [Creative Commons 4.0 Attribution Share-Alike -(CC BY-SA 4.0)](https://creativecommons.org/licenses/by-sa/4.0/) license, it features the -[Go Gopher](https://go.dev/blog/gopher) designed by [Renee French](https://wikipedia.org/wiki/Ren%C3%A9e_French)[^1] and licensed under the [Creative Commons 4.0 Attributions (CC BY 4.0)](https://creativecommons.org/licenses/by/4.0/) license. +Documentation of the package APIs and usage, may it be either in code comments, this `README.md` file, +under the `docs/` directory, or in HTML form, is licensed under [Creative Commons 4.0 Attribution Share-Alike +(CC BY-SA 4.0)](https://creativecommons.org/licenses/by-sa/4.0/). + +The "Smalltrip.go" logo is licensed under the Creative Commons 4.0 Attribution Share-Alike +(CC BY-SA 4.0) license also, it features the [Go Gopher](https://go.dev/blog/gopher) designed by +[Renee French](https://wikipedia.org/wiki/Ren%C3%A9e_French)[^1] and licensed under the +[Creative Commons 4.0 Attributions (CC BY 4.0)](https://creativecommons.org/licenses/by/4.0/) license. [^1]: A working link for RenĂ©e French's website or socials was unavailable at the time of writing.