vel

package module
v0.3.1 Latest Latest
Warning

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

Go to latest
Published: Aug 3, 2025 License: MIT Imports: 8 Imported by: 0

README

vel

A type-safe Go HTTP framework with automatic OpenAPI generation and client code generation.

Features

  • Type-safe handlers using Go generics for compile-time safety
  • Automatic OpenAPI 3.0 generation from your handler implementations
  • Client code generation for Go and TypeScript
  • Full net/http compatibility - no custom abstractions
  • Code-first approach - API specs generated from implementation, not documentation
  • Minimal dependencies - built on Go standard library

Quick Start

package main

import (
	"context"
	"net/http"

	"github.com/dennypenta/vel"
)

type HelloRequest struct {
	Name string `json:"name"`
}

type HelloResponse struct {
	Message string `json:"message"`
}

func HelloHandler(ctx context.Context, req HelloRequest) (HelloResponse, *vel.Error) {
	return HelloResponse{
		Message: "Hello, " + req.Name,
	}, nil
}

func main() {
	router := vel.NewRouter()
	vel.RegisterPost(router, "hello", HelloHandler)

	http.ListenAndServe(":8080", router.Mux())
}

Installation

go get github.com/dennypenta/vel

Documentation

https://vel-8u3w.onrender.com

Development

  • Test: go test -v ./...
  • Format: goimports -w .

Design Philosophy

  • Opinionated: No path parameters, explicit types required
  • Simple: Leverages Go's type system for safety
  • Compatible: Full net/http compatibility maintained
  • Generated: OpenAPI specs and clients generated from code

Backlog

  • SSE code gen for clients and OpenAPI
  • Error codes code gen, from yaml generate the server constants and its mapping to http status, from the same file OpenAPI can be enriched to include the error codes
  • Extend possible Error types, to support not only the build-in one, but others
  • Custom clients templates to generate clients as you wish

Documentation

Index

Constants

This section is empty.

Variables

View Source
var GlobalOpts = Opts{
	ProcessErr: nil,
	MapCodeToStatus: func(code string) int {
		if code == "" {
			return http.StatusInternalServerError
		}
		return http.StatusBadRequest
	},
}

Functions

func NewHandler

func NewHandler[I, O any](call Handler[I, O]) http.HandlerFunc

func NoopMiddleware

func NoopMiddleware(h http.Handler) http.Handler

func RequestFromContext

func RequestFromContext(ctx context.Context) *http.Request

func RequestWithContext

func RequestWithContext(ctx context.Context, r *http.Request) context.Context

func WriterFromContext

func WriterFromContext(ctx context.Context) http.ResponseWriter

func WriterWithContext

func WriterWithContext(ctx context.Context, w http.ResponseWriter) context.Context

Types

type Error

type Error struct {
	Code    string            `json:"code"`
	Message string            `json:"message,omitempty"`
	Meta    map[string]string `json:"meta,omitempty,omitzero"`
	Err     error             `json:"-"`
}

func (*Error) Error

func (e *Error) Error() string

func (*Error) JsonString

func (e *Error) JsonString() string

type ErrorSpec

type ErrorSpec struct {
	Code        string
	Description string
	Meta        []KeyValueSpec
}

type Handler

type Handler[I, O any] func(ctx context.Context, i I) (O, *Error)

type HandlerMeta

type HandlerMeta struct {
	Input       any
	Output      any
	OperationID string
	Method      string
	Spec        Spec
}

func RegisterGet

func RegisterGet[I, O any](r *Router, operationID string, handler Handler[I, O], middlewares ...Middleware) *HandlerMeta

func RegisterHandler

func RegisterHandler(r *Router, handler http.Handler, meta HandlerMeta, middlewares ...Middleware) *HandlerMeta

func RegisterHandlerFunc

func RegisterHandlerFunc(r *Router, meta HandlerMeta, h http.HandlerFunc, middlewares ...Middleware) *HandlerMeta

func RegisterPost

func RegisterPost[I, O any](r *Router, operationID string, handler Handler[I, O], middlewares ...Middleware) *HandlerMeta

func (*HandlerMeta) SetSpec

func (m *HandlerMeta) SetSpec(spec Spec)

type KeyValueSpec

type KeyValueSpec struct {
	Key          string
	ValueType    PrimitiveType
	ValueExample string
	Description  string
	Validation   Validation
}

type Middleware

type Middleware func(http.Handler) http.Handler

type Opts

type Opts struct {
	ProcessErr       func(r *http.Request, e *Error)
	MapCodeToStatus  func(code string) int
	SkipOptionMethod bool
}

type PrimitiveType

type PrimitiveType string
const (
	Bool    PrimitiveType = "bool"
	Int     PrimitiveType = "int"
	Uint    PrimitiveType = "uint"
	Float64 PrimitiveType = "float64"
	// Array   Type = "array"
	// Map     Type = "map"
	String PrimitiveType = "string"
)

type Router

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

func NewRouter

func NewRouter() *Router

func (*Router) Meta

func (r *Router) Meta() []HandlerMeta

func (*Router) Mux

func (r *Router) Mux() *http.ServeMux

func (*Router) Subrouter added in v0.3.0

func (r *Router) Subrouter(prefix string) *Router

func (*Router) Use

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

type Spec

type Spec struct {
	Description     string
	RequestHeaders  KeyValueSpec
	ResponseHeaders KeyValueSpec
	Errors          map[int][]ErrorSpec
}

type Validation

type Validation struct {
	Required bool
	MinLen   int
	MaxLen   int
	MinValue int
	MaxValue uint
	Enum     []string
}

Directories

Path Synopsis
cmd
gen command
examples

Jump to

Keyboard shortcuts

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