minato

package module
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 18, 2026 License: MIT Imports: 16 Imported by: 0

README

Minato

Minato is an opinionated, fast, and feature-rich HTTP server framework for Go, designed for building production-ready microservices with minimal boilerplate.

Features

  • Graceful Shutdown: Built-in signal handling and dependency teardown.
  • Observability: Structured logging (log/slog), Request ID generation, and automatic Prometheus metrics.
  • Resilience: Panic recovery middleware to keep your server alive.
  • Health Checks: Automatic /healthz (liveness) and /readyz (readiness) endpoints with concurrent dependency checking.
  • Security: Highly configurable CORS middleware.
  • Routing: Clean, chi-backed routing with sub-router groups.
  • gRPC Mode (Optional): Run gRPC (:9090) and HTTP/JSON gateway (:8080) in one process via grpc-gateway.
  • Cross-Transport Middleware Plugins: Apply the same concern to HTTP middleware and gRPC interceptors with UsePlugin(...).

Installation

go get github.com/dwikynator/minato

Quick Start

Here is a minimal example of a Minato server with all the bells and whistles:

package main

import (
	"context"
	"encoding/json"
	"fmt"
	"net/http"
	"time"

	"github.com/dwikynator/minato"
	"github.com/dwikynator/minato/middleware"
)

func main() {
	// 1. Configure the server
	server := minato.New(
		minato.WithAddr(":8080"),
		minato.WithHealthCheck(),
		minato.WithMetrics(),
		minato.WithReadinessCheck("database", checkDatabase),
		minato.WithCloser("database", func() error {
			fmt.Println("Closing database connection...")
			return nil
		}),
	)

	// 2. Register Global Middleware
	server.Use(middleware.RequestID())
	server.Use(middleware.Recovery())
	server.Use(middleware.Logger(
		middleware.WithBodyLogging(true),
	))
	server.Use(middleware.CORS(
		middleware.WithAllowedOrigins("*"),
	))

	// 3. Register Routes
	server.Router().Get("/ping", func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "application/json")
		w.WriteHeader(http.StatusOK)
		json.NewEncoder(w).Encode(map[string]string{"status": "ok"})
	})

	// 4. Start the server (blocks until SIGINT/SIGTERM)
	if err := server.Run(); err != nil {
		panic(err)
	}
}

func checkDatabase(ctx context.Context) error {
	// Check connection here
	return nil
}

gRPC + HTTP Gateway Mode

Enable gRPC mode with WithGRPCAddr(...), register your gRPC services, and register generated gateway handlers.

package main

import (
	"log"

	"github.com/dwikynator/minato"
	greeterpb "github.com/dwikynator/minato/_example/grpc/grpc/greeter/v1"
	"github.com/dwikynator/minato/_example/grpc/handler"
	"github.com/dwikynator/minato/middleware"
	"google.golang.org/grpc"
)

func main() {
	server := minato.New(
		minato.WithAddr(":8080"),     // HTTP gateway
		minato.WithGRPCAddr(":9090"), // gRPC server
		minato.WithGRPCReflection(),  // optional; useful for grpcurl/dev tooling
	)

	server.UsePlugin(
		middleware.RequestIDPlugin(),
		middleware.LoggerPlugin(),
		middleware.RecoveryPlugin(),
	)
	server.Use(middleware.CORS()) // HTTP-only middleware

	server.RegisterGRPC(func(s grpc.ServiceRegistrar) {
		greeterpb.RegisterGreeterServiceServer(s, handler.NewGreeterHandler())
	})
	server.RegisterGateway(greeterpb.RegisterGreeterServiceHandlerFromEndpoint)

	if err := server.Run(); err != nil {
		log.Fatal(err)
	}
}
Registering Multiple Services

Call RegisterGRPC and RegisterGateway once per service:

server.RegisterGRPC(func(s grpc.ServiceRegistrar) {
	userpb.RegisterUserServiceServer(s, userHandler)
})
server.RegisterGateway(userpb.RegisterUserServiceHandlerFromEndpoint)

server.RegisterGRPC(func(s grpc.ServiceRegistrar) {
	orderpb.RegisterOrderServiceServer(s, orderHandler)
})
server.RegisterGateway(orderpb.RegisterOrderServiceHandlerFromEndpoint)
Quick Verification
# REST via gateway
curl -s -X POST http://localhost:8080/v1/greet \
  -H "Content-Type: application/json" \
  -d '{"name":"Minato"}'

# Direct gRPC via reflection (when WithGRPCReflection is enabled)
grpcurl -plaintext \
  -d '{"name":"Minato"}' \
  localhost:9090 greeter.v1.GreeterService/SayHello

If reflection is disabled, grpcurl still works by providing proto descriptors:

grpcurl -plaintext \
  -import-path _example/grpc/proto \
  -import-path _example/grpc/proto/third_party/googleapis \
  -proto greeter.proto \
  -d '{"name":"Minato"}' \
  localhost:9090 greeter.v1.GreeterService/SayHello

License

MIT License

Documentation

Overview

Package minato provides an opinionated, fast, and feature-rich HTTP server framework built on top of standard library net/http and chi.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type GRPCServiceFunc added in v0.2.0

type GRPCServiceFunc func(s grpc.ServiceRegistrar)

GRPCServiceFunc is a callback that registers a gRPC service implementation against the server's grpc.ServiceRegistrar.

type GatewayRegisterFunc added in v0.2.0

type GatewayRegisterFunc func(
	ctx context.Context,
	mux *runtime.ServeMux,
	endpoint string,
	opts []grpc.DialOption,
) error

GatewayRegisterFunc is a callback that registers a gRPC gateway handler produced by protoc-gen-grpc-gateway.

type Logger added in v0.1.1

type Logger interface {
	Info(msg string, args ...any)
	Error(msg string, args ...any)
}

Logger interface defines the methods required for custom loggin within Minato framework.

type Option

type Option func(*config)

Option defines a functional configuration option for the Minato Server.

func WithAddr

func WithAddr(addr string) Option

WithAddr sets the TCP address for the server to listen on. Defaults to ":8080"

func WithCloser

func WithCloser(name string, fn func() error) Option

WithCloser registers a teardown function that will be called during graceful shutdown.

func WithGRPCAddr added in v0.2.0

func WithGRPCAddr(addr string) Option

WithGRPCAddr sets the TCP address for the gRPC server and enables gRPC mode.

func WithGRPCReflection added in v0.2.0

func WithGRPCReflection() Option

WithGRPCReflection enables gRPC server reflection. Keep disabled by default and enable only when needed.

func WithGRPCStreamInterceptor added in v0.2.0

func WithGRPCStreamInterceptor(interceptors ...grpc.StreamServerInterceptor) Option

WithGRPCStreamInterceptor appends one or more stream interceptors to the gRPC server.

func WithGRPCUnaryInterceptor added in v0.2.0

func WithGRPCUnaryInterceptor(interceptors ...grpc.UnaryServerInterceptor) Option

WithGRPCUnaryInterceptor appends one or more unary interceptors to the gRPC server.

func WithGatewayMuxOptions added in v0.2.0

func WithGatewayMuxOptions(opts ...runtime.ServeMuxOption) Option

WithGatewayMuxOptions forwards options directly to runtime.NewServeMux.

func WithHealthCheck

func WithHealthCheck() Option

WithHealthCheck enables automatic registration of /healthz and /readyz endpoints.

func WithIdleTimeout

func WithIdleTimeout(d time.Duration) Option

WithIdleTimeout sets the maximum amount of time to wait for the next request when keep-alives are enabled. Defaults to 60 seconds.

func WithLogger added in v0.1.1

func WithLogger(l Logger) Option

WithLogger allows injecting a custom Logger implementation for the server. If not provided, it defaults to standard log/slog.

func WithMetrics

func WithMetrics() Option

WithMetrics enables automatic registration of the Prometheus /metrics endpoint.

func WithReadHeaderTimeout

func WithReadHeaderTimeout(d time.Duration) Option

WithReadHeaderTimeout sets the amount of time allowed to read request headers. Defaults to 5 seconds.

func WithReadinessCheck

func WithReadinessCheck(name string, fn func(ctx context.Context) error) Option

WithReadinessCheck registers a named dependency check for the /readyz endpoint.

func WithShutdownTimeout

func WithShutdownTimeout(d time.Duration) Option

WithShutdownTimeout sets the deadline for graceful shutdown. Defaults to 30 seconds.

type Plugin added in v0.2.0

type Plugin struct {
	HTTP func(http.Handler) http.Handler
	GRPC grpc.UnaryServerInterceptor
}

Plugin bundles the HTTP middleware form and the gRPC unary interceptor form of the same cross-cutting concern into a single registerable unit.

type Router

type Router struct {
	// contains filtered or unexported fields
}

Router is a wrapper around chi.Mux to prevent exposing third-party router dependencies directly to library consumers.

func (*Router) Delete

func (r *Router) Delete(pattern string, h http.HandlerFunc)

Delete adds the route `pattern` that matches a DELETE HTTP method to route handler `h`

func (*Router) Get

func (r *Router) Get(pattern string, h http.HandlerFunc)

Get adds the route `pattern` that matches a GET HTTP method to route handler `h`

func (*Router) Group

func (r *Router) Group(pattern string, fn func(r *Router))

Group creates a new inline-router with a fresh middleware stack.

func (*Router) Mount added in v0.2.0

func (r *Router) Mount(pattern string, h http.Handler)

Mount attaches an http.Handler at the given pattern prefix. Used internally by gRPC mode to mount the grpc-gateway ServeMux

func (*Router) Patch

func (r *Router) Patch(pattern string, h http.HandlerFunc)

Patch adds the route `pattern` that matches a PATCH HTTP method to route handler `h`

func (*Router) Post

func (r *Router) Post(pattern string, h http.HandlerFunc)

Post adds the route `pattern` that matches a POST HTTP method to route handler `h`

func (*Router) Put

func (r *Router) Put(pattern string, h http.HandlerFunc)

Put adds the route `pattern` that matches a PUT HTTP method to route handler `h`

func (*Router) ServeHTTP

func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request)

ServeHTTP implements the standard net/http.Handler interface.

func (*Router) Use

func (r *Router) Use(middlewares ...func(http.Handler) http.Handler)

Use appends one or more middlewares onto the Router stack.

type Server

type Server struct {
	// contains filtered or unexported fields
}

Server represents the Minato HTTP server instance, wrapping an internal http.Server and Router

func New

func New(opts ...Option) *Server

New creates a new Minato Server instance with the provided options.

func (*Server) RegisterGRPC added in v0.2.0

func (s *Server) RegisterGRPC(fn GRPCServiceFunc)

RegisterGRPC registers a gRPC service implementation.

func (*Server) RegisterGateway added in v0.2.0

func (s *Server) RegisterGateway(fn GatewayRegisterFunc)

RegisterGateway registers a generated grpc-gateway handler for HTTP<->gRPC translation.

func (*Server) Router

func (s *Server) Router() *Router

Router returns the underlying Minato Router for registering routes.

func (*Server) Run

func (s *Server) Run() error

Run starts the server. If a gRPC address is configured, it starts in gRPC mode with both gRPC and HTTP/REST endpoints. Otherwise, it starts in standard HTTP mode.

func (*Server) Use

func (s *Server) Use(middlewares ...func(http.Handler) http.Handler)

Use registers global middleware that will be applied to all routes.

func (*Server) UseGRPC added in v0.2.0

func (s *Server) UseGRPC(interceptors ...grpc.UnaryServerInterceptor)

UseGRPC appends gRPC unary interceptors directly (without an HTTP counterpart)

func (*Server) UsePlugin added in v0.2.0

func (s *Server) UsePlugin(plugins ...Plugin)

UsePlugin applies the HTTP form of each plugin to the HTTP middleware chain and the gRPC form to the gRPC interceptor chain.

Directories

Path Synopsis
grpc command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL