dolanor / rip

REST in peace
BSD 3-Clause "New" or "Revised" License
68 stars 0 forks source link

RIP ⚰ Go Reference Go Report Card

REST in peace

gopher resting in peace

Why?

Creating RESTful API in Go is in a way simple and fun in the first time, but also repetitive and error prone the more resources you handle.
Copy pasting nearly the same code for each resource you want to GET or POST to except for the request and response types is not that cool, and interface{} neither.
Let's get the best of both worlds with GENERICS 🎆 everybody screams 😱

How?

The idea would be to use the classic net/http package with handlers created from Go types.

http.HandleFunc(rip.HandleEntities("/users", NewUserProvider(), nil)

and it would generate all the necessary boilerplate to have some sane (IMO) HTTP routes.

// HandleEntities associates an urlPath with an entity provider, and handles all HTTP requests in a RESTful way:
//
//  POST   /entities/    : creates the entity
//  GET    /entities/:id : get the entity
//  PUT    /entities/:id : updates the entity (needs to pass the full entity data)
//  DELETE /entities/:id : deletes the entity
//  GET    /entities/    : lists the entities (accepts page and page_size query param)
//
// It also handles fields
//
//  GET    /entities/:id/name : get only the name field of the entity
//  PUT    /entities/:id/name : updates only the name entity field

given that UserProvider implements the rip.EntityProvider interface

type EntityProvider[Ent Entity] interface {
    Create(ctx context.Context, ent Ent) (Ent, error)
    Get(ctx context.Context, id Entity) (Ent, error)
    Update(ctx context.Context, ent Ent) error
    Delete(ctx context.Context, id Entity) error
    List(ctx context.Context, offset, limit int) ([]Ent, error)
}

⚠️: Disclaimer, the API is not stable yet, use or contribute at your own risks

* Final code may differ from actual shown footage

Play with it

go run github.com/dolanor/rip/examples/srv-example@latest
// open your browser to http://localhost:8888/users/ and start editing users

Features

Encoding

You can add your own encoding for your own mime type (I plan on adding some domain type encoding for specific entities, see #13). It is quite easy to create if your encoding API follows generic standard library encoding packages like encoding/json. Here is how encoding/json codec is implemented for RIP

Talks

I gave a talk at GoLab 2023. I presented it again at FOSDEM 2024.

The slides are in my talks repository

(The FOSDEM talk present the more up-to-date API (per-route handler options), demo video (instead of live coding), + a live 3D demo, BUT, I couldn't display my note, so a lot of hesitation and parasite words, sorry about that)

TODO

Thanks