River

River is a simple and lightweight REST server
Alternatives To River
Project NameStarsDownloadsRepos Using ThisPackages Using ThisMost Recent CommitTotal ReleasesLatest ReleaseOpen IssuesLicenseLanguage
Django Rest Swagger2,5162,031412 years ago50April 30, 2018168bsd-2-clausePython
Swagger Documentation Generator for Django REST Framework: deprecated
Djangorestframework Camel Case5219316a month ago16December 14, 202126otherPython
Camel case JSON support for Django REST framework.
Django Rest Framework Csv286228112 years ago12May 16, 202127bsd-2-clausePython
CSV Tools for Django REST Framework
Drf Ujson Renderer118
94 years ago2April 07, 201511mitPython
Django Rest Framework renderer using ujson
Djburger77
3 years ago11September 07, 20183lgpl-3.0Python
Framework for safe and maintainable web-projects.
Django Rest Framework Msgpack76
44 years ago3April 22, 20176otherPython
MessagePack support for Django REST framework
River31
7 years agoOctober 05, 20214apache-2.0Go
River is a simple and lightweight REST server
Drf_ujson228
4 months ago4mitPython
JSON parser and renderer using ujson for Django Rest Framework
Django_restframework_apiview24
2 years ago2lgpl-3.0Python
Django REST_framework APIView
Rest Framework Latex23
3 years ago10January 23, 20185mitPython
A LaTeX renderer for Django REST Framework
Alternatives To River
Select To Compare


Alternative Project Comparisons
Readme

river

River is a simple and lightweight REST server.

Getting Started

rv := river.New()

Use middlewares

rv.Use(river.Logger()) 

Create endpoints

e := river.NewEndpoint(). 
    Get("/:id", func(c *river.Context){
        id := c.Param("id")
        ... // fetch data with id
        c.Render(200, data)
    }).
    Post("/", func(c *river.Context){
        ... // process c.Body and store in db
        c.Render(201, data)
    })
    ...

e.Use(MyMiddleware) // endpoint specific middleware

Handle endpoints

rv.Handle("/user", e) 

Run

rv.Run(":8080")

Check example code for more.

Approach

  • An endpoint is a REST endpoint with handlers for supported methods.
  • All endpoints are handled by a River instance.
  • Outputs are rendered via a preset or custom Renderer.
  • Middlewares and Renderers can be global or specific to an endpoint.

Request Flow

Basic flow

Request -> Middlewares -> Endpoint -> Renderer

Full flow

                    Request
                       |
                       |  
                     Router
                    /     \                  
                   /       \
                  /         \
              Found      Not Found / Method Not Allowed
                 \          /
                  \        /
                   \      /
              Global Middlewares
                   /      \
                  /        \
 Endpoint Middlewares    Not Found / Method Not Allowed Handler
        |                       |
        |                       |
     Endpoint                Renderer
        |
        |
     Renderer

Endpoint

Create

e := river.NewEndpoint()

Handle Requests

e.Get("/", handler).Post(...).Put(...) // method chaining
e.Handle(method, ...) // for custom request methods

River supports dependency injection. With that, any function can be an endpoint handler.

func () {...} // valid
func (c *river.Context) {...} // valid
func (c *river.Context, m MyStruct) {...} // valid
func (w http.ResponseWriter, r *http.Request) {...} // valid
func (w http.ResponseWriter, r *http.Request, m MyStruct) {...} // valid

JSON helper

func (c *river.Context){
    var users []User
    c.DecodeJSONBody(&users)
    ... // process users
}

Middleware

Any function that takes in the context can be used as a middleware.

type Middleware func(c *river.Context)

River comes with river.Recovery() for panic recovery.

rv.Use(Middleware) // global
e.Use(Middleware)  // endpoint

Middleware can choose to terminate request flow by not calling c.Next(). e.g. Authentication middleware.

func (c *river.Context){
    ... // do something before
    c.Next()
    ... // do something after
}

Any http.Handler can also be used as a middleware.

rv.UseHandler(handler)

Service Injection

Registering

var m MyStruct
...
rv.Register(m) // global
e.Register(m)  // endpoint

This will be passed as parameter to any endpoint handler that has MyStruct as a function parameter.

func handle(c *river.Context, m MyStruct) { ... }

Middlewares can also register request scoped service.

func AuthMiddleware(c *river.Context) {
    var session *Session
    ... // retrieve session
    c.Register(session)
}

Renderer

Renderer takes in data from endpoints and renders the data as response.

context.Render(...) renders using the configured Renderer. JSONRenderer is one of the available renderers.

Example Renderer, transform response to JSend format before sending as JSON.

func MyRenderer (c *river.Context, data interface{}) error {
    resp := river.M{"status" : "success", "data" : data}
    if _, ok := data.(error); ok {
        resp["status"] = "error"
        resp["message"] = data
        delete(resp, "data")
    }
    return JSONRenderer(c, resp)
}

Setting a Renderer. When an endpoint Renderer is not set, global Renderer is used.

rv.Renderer(MyRenderer) // global
e.Renderer(MyRenderer)  // endpoint

Custom server

River is an http.Handler. You can do without Run().

http.ListenAndServe(":8080", rv)

Router

River uses httprouter underneath.

Contributing

  • Create an issue to discuss.
  • Send in a PR.

Why the name "River", a "REST" server ? Can you REST on a River ?

Well, yes. You only need to know how to swim or wear a life jacket.

License

Apache 2

Popular Rest Projects
Popular Renderer Projects
Popular Application Programming Interfaces Categories

Get A Weekly Email With Trending Projects For These Categories
No Spam. Unsubscribe easily at any time.
Golang
Rest
Flow
Renderer