Skip to content

Adapters

MeGaNeKo edited this page Mar 20, 2026 · 1 revision

Adapters

Supported Adapters

Adapter Import Path Router
neomachi adapters/neomachi/v5 chi/v5
neomaecho adapters/neomaecho/v4 echo/v4
neomaecho adapters/neomaecho/v5 echo/v5
neomagin adapters/neomagin/v1 gin
neomafiber adapters/neomafiber/v2 fiber/v2
neomafiber adapters/neomafiber/v3 fiber/v3
neomastdlib adapters/neomastdlib net/http ServeMux (Go 1.22+)

Using an Adapter

Every adapter follows the same two-step pattern: create an adapter from a router, then pass it to neoma.NewAPI.

Each adapter package exports:

  • NewAdapter(router) core.Adapter creates an adapter from a router instance.
  • New(router, core.Config) core.API is a convenience that combines NewAdapter and neoma.NewAPI.
  • Unwrap(core.Context) extracts the underlying router-specific request/response types.
  • MultipartMaxMemory int64 controls the multipart form memory limit.

Chi Example

import (
    "github.com/MeGaNeKoS/neoma/adapters/neomachi/v5"
    "github.com/MeGaNeKoS/neoma/core"
    "github.com/MeGaNeKoS/neoma/neoma"
    "github.com/go-chi/chi/v5"
)

router := chi.NewMux()
adapter := neomachi.NewAdapter(router)
api := neoma.NewAPI(neoma.DefaultConfig("My API", "1.0.0"), adapter)

// Register routes using neoma and core packages
neoma.Get(api, "/items", handler)

Stdlib Example

import (
    "net/http"
    "github.com/MeGaNeKoS/neoma/adapters/neomastdlib"
    "github.com/MeGaNeKoS/neoma/neoma"
)

mux := http.NewServeMux()
adapter := neomastdlib.NewAdapter(mux)
api := neoma.NewAPI(neoma.DefaultConfig("My API", "1.0.0"), adapter)

http.ListenAndServe(":8080", mux)

Unwrap

Use Unwrap to access the underlying HTTP primitives from within middleware or handlers:

r, w := neomachi.Unwrap(ctx) // *http.Request, http.ResponseWriter

Writing a Custom Adapter

Implement two interfaces from the core package.

core.Context

Represents the current request/response pair:

type Context interface {
    Operation() *Operation
    Context() context.Context
    TLS() *tls.ConnectionState
    Version() ProtoVersion
    Method() string
    Host() string
    RemoteAddr() string
    URL() url.URL
    Param(name string) string
    Query(name string) string
    Header(name string) string
    EachHeader(cb func(name, value string))
    BodyReader() io.Reader
    GetMultipartForm() (*multipart.Form, error)
    SetReadDeadline(time.Time) error
    SetStatus(code int)
    Status() int
    SetHeader(name, value string)
    AppendHeader(name, value string)
    GetResponseHeader(name string) string
    DeleteResponseHeader(name string)
    BodyWriter() io.Writer
    MatchedPattern() string
}

core.Adapter

Registers routes and serves HTTP:

type Adapter interface {
    Handle(op *Operation, handler func(ctx Context))
    ServeHTTP(http.ResponseWriter, *http.Request)
}

Skeleton

package myadapter

import (
    "net/http"
    "github.com/MeGaNeKoS/neoma/core"
)

type myContext struct {
    op  *core.Operation
    r   *http.Request
    w   http.ResponseWriter
}

func (c *myContext) Operation() *core.Operation { return c.op }
func (c *myContext) Method() string             { return c.r.Method }
// ... implement remaining core.Context methods

type myAdapter struct {
    router *MyRouter
}

func (a *myAdapter) Handle(op *core.Operation, handler func(core.Context)) {
    a.router.Add(op.Method, op.Path, func(w http.ResponseWriter, r *http.Request) {
        handler(&myContext{op: op, r: r, w: w})
    })
}

func (a *myAdapter) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    a.router.ServeHTTP(w, r)
}

func NewAdapter(router *MyRouter) core.Adapter {
    return &myAdapter{router: router}
}

Clone this wiki locally