• Stars
    star
    13
  • Rank 1,512,524 (Top 30 %)
  • Language
    Go
  • License
    Other
  • Created over 2 years ago
  • Updated 3 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

golang http router with elegance, speed, and flexibility

nchi - http router with speed, flexbility, and elegance

GoDoc unit tests report card codecov

nchi is a lightweight, elegant, and fast router for building Go HTTP services. It's especially good at helping you write large REST API services that are kept maintainable as your project grows and changes. nchi is built on top of the nject dependency injection framework and the fastest Go http router, httprouter. nchi is a straight-up rip-off of chi substituting nject for context and in the process making it easier to write middleware and and endpoints.

nchi can use standard middleware and it can use dependency-injection middleware. See:

  • nvelope for nject-based middleware
  • chi for chi's middleware collection

Note: if you're using nvelope.DeferredWriter, avoid other middleware that replaces the http.ResponseWriter.

"Standard" middlewhare has one of the following shapes:

  • func(http.HandlerFunc) http.HandlerFunc
  • func(http.Handler) http.Handler

nchi automatically detects standard middleware and translates it for use in an nject-based framework.

Install

go get github.com/muir/nchi

Examples

As easy as:

package main

import (
	"net/http"

	"github.com/muir/nchi"
	"github.com/go-chi/chi/v5/middleware"
)

func main() {
	r := nchi.NewRouter()
	r.Use(middleware.Logger)
	r.Get("/", func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("welcome"))
	})
	http.ListenAndServe(":3000", r)
}

REST Preview:

Here is a little preview of how routing looks like with nchi.

import (
  //...
  "github.com/muir/nchi"
  "github.com/muir/nvelope"
  "github.com/muir/nject"
  "github.com/go-chi/chi/v5/middleware"
)

func main() {
  r := nchi.NewRouter()

  // A good base middleware stack
  r.Use(
     middleware.RequestID, 
     middleware.RealIP, 
     middleware.Logger,
     nchi.DecodeJSON,
  )

  r.Use(func(inner func() error, w http.ResponseWriter) {
     err := inner()
     if err == nil { 
       return
     }
     code := nvelope.GetReturnCode(err)
     w.WriteHeader(code)
     w.Write([]byte(err.Error()))
  })

  // Set a timeout value on the request context (ctx), that will signal
  // through ctx.Done() that the request has timed out and further
  // processing should be stopped.
  r.Use(middleware.Timeout(60 * time.Second))

  r.Get("/", func(w http.ResponseWriter) {
    w.Write([]byte("hi"))
  })

  // RESTy routes for "articles" resource
  r.Route("/articles", func(r nchi.Router) {
    r.With(paginate).Get("/", listArticles)                           // GET /articles
    r.With(paginate).Get("/:month/:day/:year", listArticlesByDate)    // GET /articles/01-16-2017

    r.Post("/", createArticle)                                        // POST /articles
    r.Get("/search", searchArticles)                                  // GET /articles/search

    r.Get("/:articleSlug", getArticleBySlug)                          // GET /articles/home-is-toronto

    // Subrouters:
    r.Route("/:articleID", func(r nchi.Router) {
      r.Use(LoadArticle)
      r.Get("/", getArticle)                                          // GET /articles/123
      r.Put("/", updateArticle)                                       // PUT /articles/123
      r.Delete("/", deleteArticle)                                    // DELETE /articles/123
    })
  })

  // Mount the admin sub-router
  r.Mount("/admin", adminRouter())

  http.ListenAndServe(":3333", r)
}

func LoadArticle(params nchi.Params) (*Article, nject.TerminalError) {
  articleID := params.ByName("articleID")
  article, err := dbGetArticle(articleID)
  if errors.Is(err, sql.NotFound) {
    return nil, nvelope.NotFound(err)
  }
  return article, err
}

func getArticle(article *Article, w http.ResponseWriter) {
  w.Write([]byte(fmt.Sprintf("title:%s", article.Title)))
}

Developement status

nchi seems to be working fine for the time being so not much is changing. Please file an issue if there is something you would like changed.

More Repositories

1

nject

Golang type-safe dependency injection
Go
28
star
2

libschema

database schema migrations on a per-library basis [Go]
Go
15
star
3

Net-Netmask

Net::Netmask perl module
Perl
6
star
4

reflectutils

Golang utility functions for working with reflection
Go
6
star
5

nfigure

Golang struct-tag based configfile and flag parsing
Go
6
star
6

Time-modules

CPAN modules: TIme::ParseDate, Time::CTime, Time::JulianDay etc
Perl
5
star
7

sqltoken

High performance SQL tokenizer - Golang
Go
4
star
8

Cisco-Reconfig

The Cisco::Reconfig perl module
Perl
4
star
9

drbd-lxd

Instructions/tools for shared nothing DRBD LXC HA setup
Shell
4
star
10

nvelope

injection chains for building endpoints (golang)
Go
3
star
11

xop-go

Golang structured logging/tracing framework
Go
3
star
12

nserve

injection chains for for starting and stopping servers
Go
3
star
13

Daemon-Generic

The Daemon::Generic CPAN perl module
Perl
3
star
14

IO-Event

the CPAN IO::Event module
Perl
2
star
15

Stream-Aggregate

The Stream::Aggregate perl module
Perl
2
star
16

npoint

dependency injection wrappers for binding http endpoint handlers
Go
2
star
17

OOPS

OOPS cpan module --- object persistant store
Perl
2
star
18

nape

dependency injection of endpoint handlers using gorilla/mux
Go
2
star
19

Eval-LineNumbers

Eval::LineNumbers perl module on CPAN
Perl
1
star
20

Mail-SendVarious

Mail::SendVarious perl module
Perl
1
star
21

Proc-JobQueue

Proc::JobQueue perl modules
Perl
1
star
22

HTML-Transmorgify

HTML::Transmorgify perl module
Perl
1
star
23

Net-SMTP-Receive

Net::SMTP::Receive perl module
Perl
1
star
24

Text-Tabs-Wrap

The Text::Tabs & Text::Wrap CPAN Modules
1
star
25

rinetd.pl

rinetd.pl - tcp redirection server
Perl
1
star
26

genpxelinux.pl

genpxelinux.pl command
Perl
1
star
27

Proc-Parallel

The Proc::Parallel and RCP::ToWorker CPAN modules
Perl
1
star
28

Config-Checker

Config::Checker perl module
Perl
1
star
29

Object-Dependency

Object::Dependency perl module
Perl
1
star
30

File-Slurp-Remote

The File::Slurp::Remote cpan module
Perl
1
star
31

gwrap

Golang generic wrappers for core library functions
Go
1
star