docs(readme): about the package
This commit is contained in:
162
README.md
162
README.md
@@ -1,16 +1,170 @@
|
|||||||
# 
|
# 
|
||||||
|
|
||||||
|
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
|
## Licenses
|
||||||
|
|
||||||
Copyright © 2025-present Gustavo "Guz" L. de Mello & The Lored.dev Contributors
|
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
|
Documentation of the package APIs and usage, may it be either in code comments, this `README.md` file,
|
||||||
(CC BY-SA 4.0)](https://creativecommons.org/licenses/by-sa/4.0/) license, it features the
|
under the `docs/` directory, or in HTML form, is licensed under [Creative Commons 4.0 Attribution Share-Alike
|
||||||
[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.
|
(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.
|
[^1]: A working link for Renée French's website or socials was unavailable at the time of writing.
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user