https://github.com/paologaleotti/gleamkit
Experimental starter for Gleam web services
https://github.com/paologaleotti/gleamkit
api backend gleam http starter template
Last synced: 6 months ago
JSON representation
Experimental starter for Gleam web services
- Host: GitHub
- URL: https://github.com/paologaleotti/gleamkit
- Owner: paologaleotti
- License: mit
- Created: 2024-06-26T18:34:48.000Z (almost 2 years ago)
- Default Branch: main
- Last Pushed: 2024-09-29T16:53:16.000Z (over 1 year ago)
- Last Synced: 2025-02-05T08:51:06.070Z (over 1 year ago)
- Topics: api, backend, gleam, http, starter, template
- Language: Gleam
- Homepage:
- Size: 52.7 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# gleamkit
> WIP: Very early development, missing consistency and features

This experimental repo is a starter kit for writing **HTTP APIs in Gleam** based on `wisp`,
aiming to provide a simple and opinionated setup that is **production-ready**
(even though Gleam is still a very cutting edge language).
I am aware that Gleam has the "start simple, refactor later" philosophy (just like Golang).
This starter is inspired by my own [blaze](https://github.com/paologaleotti/blaze),
only giving the user the essentials for real, production use without going crazy on the structure.
## Features
- Simple, opinionated, production ready structure
- Pattern matching based routing
- Handy body decoding and validation
- Automatic human readable errors on decoding failures
- Custom HTTP API error handling
- Request and reply utilities
- Env variables and app context configuration
## Snippets
Routing:
```gleam
pub fn handle_request(req: Request, _ctx: AppContext) -> Response {
use req <- middleware.default_middleware(req)
use req <- cors.wisp_middleware(req, default_cors())
case req.method, wisp.path_segments(req) {
Get, [] -> ok()
Get, ["todos"] -> todos.handle_get_todos()
Post, ["todos"] -> todos.handle_create_todo(req)
Get, ["todos", id] -> todos.handle_get_todo(req, id)
_, _ -> route_not_found()
}
}
```
Body validation with automatic validation errors (found in `common/core` module):
```gleam
pub fn handle_create_todo(req: Request) -> Response {
// Handy direct decoding with custom error handling
use new_todo <- decode_body(req, todos.decode_new_todo)
let res = todos.Todo(4, new_todo.title, False)
// Reply with status code and JSON data
reply_data(201, todos.encode_todo(res))
}
```
Easy API custom error handling:
```gleam
pub fn handle_get_todo(_req: Request, id: String) -> Response {
// Early reply utility function to handle errors
use todo_id <- unpack_or_reply(int.parse(id), fn(_) {
// Reply with a detailed API error
reply_error_detailed(BadRequest, "Invalid todo ID")
})
let item = list.find(todos, fn(t) { t.id == todo_id })
// Match on the result and reply with data or API error
case item {
Ok(item) -> reply_data(200, todos.encode_todo(item))
Error(_) -> reply_error(NotFound)
}
}
```
Default HTTP errors (like NotFound) can be found in `common/errors` module, and you can append a detail message to them using the `reply_error_detailed` function.
## Build and run
```sh
make # Build the project
make run # Run the service
```