chimera

package module
v0.1.1 Latest Latest
Warning

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

Go to latest
Published: Mar 10, 2024 License: MIT Imports: 15 Imported by: 0

README

chimera

Chi-based Module for Easy REST APIs

Overview

chimera is designed for fast/easy API development based on OpenAPI with the following core features:

  • Automatic OpenAPI (3.1) docs from structs (no comments or files needed)
  • Automatic parsing of JSON/text/binary/form requests
  • Automatic serialization of JSON/text/binary responses
  • Automatic handling of request/response parameters (cookies/query/headers/path)
  • Middleware (with easy error handling)
  • Route groups (with isolated middleware)
  • Error handling as responses
  • Static file serving from directories

An example of how some of this might look in practice is:

package main

import "github.com/matt1484/chimera"

type TestBody struct {
    Property string `json:"prop"`
}

type TestParams struct {
    Path string   `param:"path,in=path"`
    Header string `param:"header,in=header"`
}

func main() {
    api := chimera.NewAPI()
    api.Use(func(req *http.Request, ctx chimera.RouteContext, next chimera.NextFunc) (chimera.ResponseWriter, error) {
        resp, err := next(req)
        return resp, err
    })
    chimera.Get(api, "/test/{path}", func(req *chimera.JSON[TestBody, TestParams]) (*chimera.JSON[TestBody, chimera.Nil], error) {
        return &chimera.JSON[TestBody, TestParams]{
            Body: req.Body,
        }, nil
    })
    api.Start(":8000")
}

By using struct tags, generics, reflection, and carefully designed interfaces chimera can infer and automate a lot of the typical tasks that go developers often manually do.

This library relies heavily on chi to support the routing/grouping/middleware internally. While chi is all about being inline with the standard library, this library is more opinionated and instead goes for a more standard layout of development interfaces as seen in other languages/frameworks to support quicker development. A lof of its design was actually heavily inspired by fastapi and you can even see the parallels in this example here:

from typing import Annotated
from fastapi import FastAPI, Header
from pydantic import BaseModel

class TestBody(BaseModel):
    prop: str

api = fastapi.FastAPI()

@api.middleware("http")
def add_process_time_header(request: Request, next):
    response = next(request)
    return response

@api.get("/test/{path}")
def test(path: str, header: Annotated[str, Header()] = None, body: TestBody) -> TestBody
    return body

Additional docs can be found in the docs folder

TODO

  • Proper XML support
  • Multipart form support

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func MarshalParams

func MarshalParams(obj any) (http.Header, error)

MarshalParams turns an object into headers this technically supports cookies and headers but the result is all headers

func UnmarshalParams

func UnmarshalParams(request *http.Request, obj any) error

UnmarshalParams gets all the parameters out of a request object (headers, cookies, query, path)

Types

type API

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

API is a collection of routes and middleware with an associated OpenAPI spec

func NewAPI

func NewAPI() *API

NewAPI returns an initialized API object

func (*API) Group

func (a *API) Group(basePath string) *API

Group creates a sub-API with seperate middleware and routes using a base path. The middleware of the parent API is always evaluated first and any route collisions are handled by chi directly

func (*API) Mount added in v0.0.5

func (a *API) Mount(basePath string, subAPI *API)

Mount adds an API as a child based on route. It is like a reverse Group()

func (*API) OpenAPISpec

func (a *API) OpenAPISpec() *OpenAPI

OpenAPISpec returns the underlying OpenAPI structure for this API

func (*API) ServeHTTP

func (a *API) ServeHTTP(w http.ResponseWriter, req *http.Request)

ServeHTTP serves to implement support for the standard library

func (*API) Start

func (a *API) Start(addr string) error

Start uses http.ListenAndServe to start serving requests from addr

func (*API) Static

func (a *API) Static(apiPath, filesPath string)

Static adds support for serving static content from a directory, this route is hidden from the OpenAPI spec

func (*API) Use

func (a *API) Use(middleware ...MiddlewareFunc)

Use adds middleware to the API

type APIError

type APIError struct {
	StatusCode int
	Body       []byte
	Header     http.Header
}

APIError is an error that can be converted to a response

func NewInvalidParamError

func NewInvalidParamError(in, paramName, value string) APIError

NewInvalidParamError returns an APIError to denote a parameter was improperly formatted

func NewRequiredParamError

func NewRequiredParamError(in, name string) APIError

NewRequiredParamError returns an APIError to denote that a parameter was missing

func (APIError) Error

func (a APIError) Error() string

Error returns the string representation of the error

type Binary

type Binary[Params any] struct {
	Body   []byte
	Params Params
	// contains filtered or unexported fields
}

Binary[Params] is a helper type that effectively works as both a BinaryRequest[Params] and BinaryResponse[Params] This is mostly here for convenience

func (*Binary[Params]) Context

func (r *Binary[Params]) Context() context.Context

Context returns the context that was part of the original http.Request if this was used in a non-request context it will return nil

func (*Binary[Params]) OpenAPIRequestSpec

func (r *Binary[Params]) OpenAPIRequestSpec() RequestSpec

OpenAPIRequestSpec returns the Request definition of a BinaryRequest

func (*Binary[Params]) OpenAPIResponsesSpec

func (r *Binary[Params]) OpenAPIResponsesSpec() Responses

OpenAPIResponsesSpec returns the Responses definition of a BinaryResponse

func (*Binary[Params]) ReadRequest

func (r *Binary[Params]) ReadRequest(req *http.Request) error

ReadRequest reads the body of an http request and assigns it to the Body field using io.ReadAll. This function also reads the parameters using UnmarshalParams and assigns it to the Params field. NOTE: the body of the request is closed after this function is run.

func (*Binary[Params]) WriteBody added in v0.0.5

func (r *Binary[Params]) WriteBody(write BodyWriteFunc) error

WriteBody writes the response body

func (*Binary[Params]) WriteHead added in v0.0.5

func (r *Binary[Params]) WriteHead(head *ResponseHead) error

WriteHead writes the header for this response object

type BinaryRequest

type BinaryRequest[Params any] struct {
	Body   []byte
	Params Params
	// contains filtered or unexported fields
}

BinaryRequest[Params any] is a request type that uses a []byte as the Body and Params as an user-provided struct

func (*BinaryRequest[Params]) Context

func (r *BinaryRequest[Params]) Context() context.Context

Context returns the context that was part of the original http.Request

func (*BinaryRequest[Params]) OpenAPIRequestSpec

func (r *BinaryRequest[Params]) OpenAPIRequestSpec() RequestSpec

OpenAPIRequestSpec returns the Request definition of a BinaryRequest

func (*BinaryRequest[Params]) ReadRequest

func (r *BinaryRequest[Params]) ReadRequest(req *http.Request) error

ReadRequest reads the body of an http request and assigns it to the Body field using io.ReadAll. This function also reads the parameters using UnmarshalParams and assigns it to the Params field. NOTE: the body of the request is closed after this function is run.

type BinaryResponse

type BinaryResponse[Params any] struct {
	Body   []byte
	Params Params
}

BinaryResponse[Params any] is a response type that uses a []byte as the Body and Params as an user-provided struct

func NewBinaryResponse

func NewBinaryResponse[Params any](body []byte, params Params) *BinaryResponse[Params]

NewBinaryResponse creates a BinaryResponse from body and params

func (*BinaryResponse[Params]) OpenAPIResponsesSpec

func (r *BinaryResponse[Params]) OpenAPIResponsesSpec() Responses

OpenAPIResponsesSpec returns the Responses definition of a BinaryResponse

func (*BinaryResponse[Params]) WriteBody added in v0.0.5

func (r *BinaryResponse[Params]) WriteBody(write BodyWriteFunc) error

WriteBody writes the response body

func (*BinaryResponse[Params]) WriteHead added in v0.0.5

func (r *BinaryResponse[Params]) WriteHead(head *ResponseHead) error

WriteHead writes adds the header for this response object

type BodyWriteFunc added in v0.0.5

type BodyWriteFunc func(body []byte) (int, error)

type Components

type Components struct {
	Schemas         map[string]jsonschema.Schema    `json:"schemas,omitempty"`
	Responses       Responses                       `json:"responses,omitempty"`
	Parameters      map[string]Parameter            `json:"parameters,omitempty"`
	Examples        map[string]Example              `json:"examples,omitempty"`
	RequestBodies   map[string]RequestBody          `json:"requestBodies,omitempty"`
	Headers         map[string]map[string]Parameter `json:"headers,omitempty"`
	SecuritySchemes map[string]map[string][]string  `json:"securitySchemes,omitempty"`
	Links           map[string]Link                 `json:"links,omitempty"`
	Callbacks       map[string]map[string]Path      `json:"callbacks,omitempty"`
	PathItems       map[string]Path                 `json:"pathItems,omitempty"`
}

Components describes all openapi components

type Contact

type Contact struct {
	Name  string `json:"name,omitempty"`
	URL   string `json:"url,omitempty"`
	Email string `json:"email,omitempty"`
}

Contact stores basic contanct info

type CookieParamMarshaler

type CookieParamMarshaler interface {
	MarshalCookieParam(ParamStructTag) (http.Cookie, error)
}

CookieParamMarshaler is an interface that supports converting a user-defined type to an http.Cookie

type CookieParamUnmarshaler

type CookieParamUnmarshaler interface {
	UnmarshalCookieParam(http.Cookie, ParamStructTag) error
}

CookieParamUnmarshaler is an interface that supports converting an http.Cookie to a user-defined type

type EmptyRequest

type EmptyRequest struct{}

EmptyRequest is an empty request, effectively a no-op (mostly used for GET requests)

func (*EmptyRequest) OpenAPIRequestSpec

func (*EmptyRequest) OpenAPIRequestSpec() RequestSpec

OpenAPIRequestSpec returns an empty RequestSpec

func (*EmptyRequest) ReadRequest

func (*EmptyRequest) ReadRequest(*http.Request) error

ReadRequest does nothing

type EmptyResponse

type EmptyResponse struct{}

EmptyResponse is an empty response, effectively a no-op (mostly used for DELETE requests)

func (*EmptyResponse) OpenAPIResponsesSpec

func (*EmptyResponse) OpenAPIResponsesSpec() Responses

OpenAPIResponsesSpec returns an empty Responses definition

func (*EmptyResponse) WriteBody added in v0.0.5

func (*EmptyResponse) WriteBody(BodyWriteFunc) error

WriteBody does nothing

func (*EmptyResponse) WriteHead added in v0.0.5

func (*EmptyResponse) WriteHead(*ResponseHead) error

WriteHead does nothing

type Encoding

type Encoding struct {
	ContentType   string               `json:"contentType,omitempty"`
	Headers       map[string]Parameter `json:"headers,omitempty"`
	Style         string               `json:"style,omitempty"`
	Explode       bool                 `json:"explode,omitempty"`
	AllowReserved bool                 `json:"allowReserved,omitempty"`
}

Encoding is used to describe a content encoding in an API

type Example

type Example struct {
	Summary       string `json:"summary,omitempty"`
	Description   string `json:"description,omitempty"`
	Value         any    `json:"value,omitempty"`
	ExternalValue string `json:"externalValue,omitempty"`
	Example       any    `json:"example,omitempty"`
}

Example is an example of any type

type ExternalDocs

type ExternalDocs struct {
	Description string `json:"description"`
	URL         string `json:"url"`
}

ExternalDocs is a link to external API documentation

type FormRequest

type FormRequest[Body, Params any] struct {
	Body   Body
	Params Params
	// contains filtered or unexported fields
}

FormRequest[Body, Params any] is a request type that decodes request bodies to a user-defined struct for the Body and Params

func (*FormRequest[Body, Params]) Context

func (r *FormRequest[Body, Params]) Context() context.Context

Context returns the context that was part of the original http.Request

func (*FormRequest[Body, Params]) OpenAPIRequestSpec

func (r *FormRequest[Body, Params]) OpenAPIRequestSpec() RequestSpec

OpenAPIRequestSpec returns the Request definition of a FormRequest It attempts to utilize patternProperties to try to define the body schema i.e. objects/arrays use dotted/bracketed paths X.Y.Z[i]

func (*FormRequest[Body, Params]) ReadRequest

func (r *FormRequest[Body, Params]) ReadRequest(req *http.Request) error

ReadRequest reads the body of an http request and assigns it to the Body field using http.Request.ParseForm and the "go-playground/form" package. This function also reads the parameters using UnmarshalParams and assigns it to the Params field. NOTE: the body of the request is closed after this function is run.

type HandlerFunc

type HandlerFunc[ReqPtr RequestReaderPtr[Req], Req any, RespPtr ResponseWriterPtr[Resp], Resp any] func(ReqPtr) (RespPtr, error)

HandlerFunc is a handler function. The generic signature may look odd but its effectively: func(req *RequestReader) (*ResponseWriter, error)

func HTTPHandler

func HTTPHandler(handler http.HandlerFunc) HandlerFunc[*Request, Request, *Response, Response]

HTTPHandler is a function that converts a standard http.HandlerFunc into one that works with chimera

type HeaderParamMarshaler

type HeaderParamMarshaler interface {
	MarshalHeaderParam(ParamStructTag) (http.Header, error)
}

HeaderParamMarshaler is an interface that supports converting a user-defined type to a header value ([]string)

type HeaderParamUnmarshaler

type HeaderParamUnmarshaler interface {
	UnmarshalHeaderParam(value []string, info ParamStructTag) error
}

HeaderParamUnmarshaler is an interface that supports converting a header value ([]string) to a user-defined type

type In

type In int

In denotes where a paramter lives (i.e. path, query, header, cookie)

const (
	NullIn In = iota
	PathIn
	QueryIn
	HeaderIn
	CookieIn
)

func (In) UnmarshalTagOption

func (i In) UnmarshalTagOption(field reflect.StructField, value string) (reflect.Value, error)

UnmarshalTagOption is used to unmarshal a In found in a struct tag

type Info

type Info struct {
	Title          string   `json:"title"`
	Summary        string   `json:"summary,omitempty"`
	Description    string   `json:"description,omitempty"`
	TermsOfService string   `json:"termsOfService,omitempty"`
	Contact        *Contact `json:"contact,omitempty"`
	License        *License `json:"license,omitempty"`
	Version        string   `json:"version"`
}

Info holds info about an API

type JSON

type JSON[Body, Params any] struct {
	Body   Body
	Params Params
	// contains filtered or unexported fields
}

JSON[Body, Params] is a helper type that effectively works as both a JSONRequest[Body, Params] and JSONResponse[Body, Params] This is mostly here for convenience

func (*JSON[Body, Params]) Context

func (r *JSON[Body, Params]) Context() context.Context

Context returns the context for this request NOTE: this type can also be used for responses in which case Context() would be nil

func (*JSON[Body, Params]) OpenAPIRequestSpec

func (r *JSON[Body, Params]) OpenAPIRequestSpec() RequestSpec

OpenAPIRequestSpec returns the Request definition of a JSON request using "invopop/jsonschema"

func (*JSON[Body, Params]) OpenAPIResponsesSpec

func (r *JSON[Body, Params]) OpenAPIResponsesSpec() Responses

OpenAPIResponsesSpec returns the Responses definition of a JSON response using "invopop/jsonschema"

func (*JSON[Body, Params]) ReadRequest

func (r *JSON[Body, Params]) ReadRequest(req *http.Request) error

ReadRequest reads the body of an http request and assigns it to the Body field using json.Unmarshal This function also reads the parameters using UnmarshalParams and assigns it to the Params field. NOTE: the body of the request is closed after this function is run.

func (*JSON[Body, Params]) WriteBody added in v0.0.5

func (r *JSON[Body, Params]) WriteBody(write BodyWriteFunc) error

WriteBody writes the response body

func (*JSON[Body, Params]) WriteHead added in v0.0.5

func (r *JSON[Body, Params]) WriteHead(head *ResponseHead) error

WriteHead writes header for this response object

type JSONRequest

type JSONRequest[Body, Params any] struct {
	Body   Body
	Params Params
	// contains filtered or unexported fields
}

JSONRequest[Body, Params any] is a request type that decodes json request bodies to a user-defined struct for the Body and Params

func (*JSONRequest[Body, Params]) Context

func (r *JSONRequest[Body, Params]) Context() context.Context

Context returns the context that was part of the original http.Request

func (*JSONRequest[Body, Params]) OpenAPIRequestSpec

func (r *JSONRequest[Body, Params]) OpenAPIRequestSpec() RequestSpec

OpenAPIRequestSpec returns the Request definition of a JSONRequest using "invopop/jsonschema"

func (*JSONRequest[Body, Params]) ReadRequest

func (r *JSONRequest[Body, Params]) ReadRequest(req *http.Request) error

ReadRequest reads the body of an http request and assigns it to the Body field using json.Unmarshal This function also reads the parameters using UnmarshalParams and assigns it to the Params field. NOTE: the body of the request is closed after this function is run.

type JSONResponse

type JSONResponse[Body, Params any] struct {
	Body   Body
	Params Params
}

JSONResponse[Body, Params any] is a response type that converts user-provided types to json and marshals params to headers

func NewJSONResponse

func NewJSONResponse[Body, Params any](body Body, params Params) *JSONResponse[Body, Params]

NewJSONResponse creates a JSONResponse from body and params

func (*JSONResponse[Body, Params]) OpenAPIResponsesSpec

func (r *JSONResponse[Body, Params]) OpenAPIResponsesSpec() Responses

OpenAPIResponsesSpec returns the Responses definition of a JSONResponse using "invopop/jsonschema"

func (*JSONResponse[Body, Params]) WriteBody added in v0.0.5

func (r *JSONResponse[Body, Params]) WriteBody(write BodyWriteFunc) error

WriteBody writes the response body using json.Marshal

func (*JSONResponse[Body, Params]) WriteHead added in v0.0.5

func (r *JSONResponse[Body, Params]) WriteHead(head *ResponseHead) error

WriteHead writes header for this response object

type LazyBodyResponse added in v0.0.5

type LazyBodyResponse struct {
	StatusCode int
	Body       ResponseBodyWriter
	Headers    http.Header
}

LazyBodyResponse is a response that effectively wraps another ReponseWriter with predefined header/status code

func NewLazyBodyResponse added in v0.0.5

func NewLazyBodyResponse(head ResponseHead, resp ResponseBodyWriter) *LazyBodyResponse

NewLazyBodyResponse creates a response with predefined headers and a lazy body

func (*LazyBodyResponse) OpenAPIResponsesSpec added in v0.0.5

func (r *LazyBodyResponse) OpenAPIResponsesSpec() Responses

OpenAPIResponsesSpec returns an empty Responses object

func (*LazyBodyResponse) WriteBody added in v0.0.5

func (r *LazyBodyResponse) WriteBody(write BodyWriteFunc) error

WriteBody writes the exact body from the struct

func (*LazyBodyResponse) WriteHead added in v0.0.5

func (r *LazyBodyResponse) WriteHead(head *ResponseHead) error

WriteHead returns the status code and header for this response object

type License

type License struct {
	Name       string `json:"name,omitempty"`
	URL        string `json:"url,omitempty"`
	Identifier string `json:"identifier,omitempty"`
}

License describes the license of an API

type Link struct {
	OperationRef string         `json:"operationRef,omitempty"`
	OperationId  string         `json:"operationId,omitempty"`
	Parameters   map[string]any `json:"parameters,omitempty"`
	RequestBody  any            `json:"requestBody,omitempty"`
	Description  string         `json:"description,omitempty"`
	Server       *Server        `json:"server,omitempty"`
}

Link descript a link to parts of a spec

type MediaType

type MediaType struct {
	Schema   *jsonschema.Schema  `json:"schema,omitempty"`
	Encoding map[string]Encoding `json:"encoding,omitempty"`
	Example  any                 `json:"example,omitempty"`
	Examples *map[string]Example `json:"examples,omitempty"`
}

MediaType describes a media type in openapi

type MiddlewareFunc

type MiddlewareFunc func(req *http.Request, ctx RouteContext, next NextFunc) (ResponseWriter, error)

MiddlewareFunc is a function that can be used as middleware

func HTTPMiddleware added in v0.1.1

func HTTPMiddleware(middleware func(http.Handler) http.Handler) MiddlewareFunc

type NextFunc

type NextFunc func(req *http.Request) (ResponseWriter, error)

NextFunc is the format for allowing middleware to continue to child middleware

type Nil

type Nil struct{}

Nil is an empty struct that is designed to represent "nil" and is typically used to denote that a request/response has no body or parameters depending on context

type NoBodyRequest

type NoBodyRequest[Params any] struct {
	Params Params
}

NoBodyRequest is a request with only parameters and an empty body (mostly used for GET requests)

func (*NoBodyRequest[Params]) OpenAPIRequestSpec

func (r *NoBodyRequest[Params]) OpenAPIRequestSpec() RequestSpec

OpenAPIRequestSpec returns the parameter definitions of this object

func (*NoBodyRequest[Params]) ReadRequest

func (r *NoBodyRequest[Params]) ReadRequest(req *http.Request) error

ReadRequest parses the params of the request

type NoBodyResponse

type NoBodyResponse[Params any] struct {
	Params Params
}

NoBodyResponse is a response with no body, but has parameters (mostly used for DELETE requests)

func NewNoBodyResponse

func NewNoBodyResponse[Params any](params Params) *NoBodyResponse[Params]

NewBinaryResponse creates a NoBodyResponse from params

func (*NoBodyResponse[Params]) OpenAPIResponsesSpec

func (r *NoBodyResponse[Params]) OpenAPIResponsesSpec() Responses

OpenAPIResponsesSpec returns the parameter definitions of this object

func (*NoBodyResponse[Params]) WriteBody added in v0.0.5

func (r *NoBodyResponse[Params]) WriteBody(BodyWriteFunc) error

WriteBody does nothing

func (*NoBodyResponse[Params]) WriteHead added in v0.0.5

func (r *NoBodyResponse[Params]) WriteHead(head *ResponseHead) error

WriteHead writes the headers for this response

type OneOfResponse

type OneOfResponse[ResponseType any] struct {
	Response ResponseType
}

OneOfResponse[ResponseType any] is a response that uses the fields of ResponseType to determine which response to use as well as ResponseStructTag to control the status code, description of the different responses All fields must implement ResponseWriter to allow this to work properly

func NewOneOfResponse

func NewOneOfResponse[ResponseType any](response ResponseType) *OneOfResponse[ResponseType]

NewOneOfResponse creates a OneOfResponse from a response

func (*OneOfResponse[ResponseType]) OpenAPIResponsesSpec

func (r *OneOfResponse[ResponseType]) OpenAPIResponsesSpec() Responses

OpenAPIResponsesSpec returns the Responses definition of a OneOfResponse using all the OpenAPIResponsesSpec() functions of the fields in ResponseType

func (*OneOfResponse[ResponseType]) WriteBody added in v0.0.5

func (r *OneOfResponse[ResponseType]) WriteBody(write BodyWriteFunc) error

WriteBody writes the response body using the first non-nil field

func (*OneOfResponse[ResponseType]) WriteHead added in v0.0.5

func (r *OneOfResponse[ResponseType]) WriteHead(head *ResponseHead) error

WriteHead writes the status code and header using the first non-nil field

type OpenAPI

type OpenAPI struct {
	OpenAPI           string                `json:"openapi,omitempty"`
	Info              Info                  `json:"info,omitempty"`
	JSONSchemaDialect string                `json:"jsonSchemaDialect,omitempty"`
	Servers           []Server              `json:"servers,omitempty"`
	Paths             map[string]Path       `json:"paths,omitempty"`
	Webhooks          map[string]Path       `json:"webhooks,omitempty"`
	Components        *Components           `json:"components,omitempty"`
	Security          []map[string][]string `json:"security,omitempty"`
	Tags              []Tag                 `json:"tags,omitempty"`
	ExternalDocs      *ExternalDocs         `json:"externalDocs,omitempty"`
}

OpenAPI is used to store an entire openapi spec

func (*OpenAPI) Merge

func (o *OpenAPI) Merge(spec OpenAPI)

Merge attempts to fold a spec into the current spec In general, the provided spec takes precedence over the current one

type Operation

type Operation struct {
	*RequestSpec
	Tags         []string                   `json:"tags,omitempty"`
	Summary      string                     `json:"summary,omitempty"`
	Description  string                     `json:"description,omitempty"`
	ExternalDocs *ExternalDocs              `json:"externalDocs,omitempty"`
	OperationID  string                     `json:"operationId,omitempty"`
	Callbacks    map[string]map[string]Path `json:"callbacks,omitempty"`
	Deprecated   bool                       `json:"deprecated,omitempty"`
	Security     []map[string][]string      `json:"security,omitempty"`
	Servers      []Server                   `json:"servers,omitempty"`
	Responses    Responses                  `json:"responses,omitempty"`
}

Operation describes an openapi Operation

func (*Operation) Merge

func (o *Operation) Merge(other Operation)

Merge folds an Operation object into the current Operation object In general, the provided operation takes precedence over the current one

type ParamStructTag

type ParamStructTag struct {
	Name            string `structtag:"$name"`
	In              In     `structtag:"in,required"`
	Explode         bool   `structtag:"explode"`
	Style           Style  `structtag:"style"`
	Required        bool   `structtag:"required"`
	Description     string `structtag:"description"`
	Deprecated      bool   `structtag:"deprecated"`
	AllowEmptyValue bool   `structtag:"allowEmptyValue"`
	AllowReserved   bool   `structtag:"allowReserved"`
	// contains filtered or unexported fields
}

ParamStructTag describes the various parts of the "param" struct tag

func (*ParamStructTag) OpenAPIParameterSpec

func (p *ParamStructTag) OpenAPIParameterSpec() Parameter

OpenAPIParameterSpec returns the Parameter definition of a struct tag

type Parameter

type Parameter struct {
	Name            string              `json:"name,omitempty"`
	In              string              `json:"in,omitempty"`
	Description     string              `json:"description,omitempty"`
	Required        bool                `json:"required,omitempty"`
	Deprecated      bool                `json:"deprecated,omitempty"`
	AllowEmptyValue bool                `json:"allowEmptyValue,omitempty"`
	Style           string              `json:"style,omitempty"`
	Explode         bool                `json:"explode,omitempty"`
	AllowReserved   bool                `json:"allowReserved,omitempty"`
	Schema          *jsonschema.Schema  `json:"schema,omitempty"`
	Example         any                 `json:"example,omitempty"`
	Examples        *map[string]Example `json:"examples,omitempty"`
}

Parameter describes a paramater used in requests/responses

func CacheRequestParamsType

func CacheRequestParamsType(t reflect.Type) []Parameter

CacheRequestParamsType adds a type to the internal tag cache and returns the resulting Paramter objects

func CacheResponseParamsType

func CacheResponseParamsType(t reflect.Type) []Parameter

CacheResponseParamsType adds a type to the internal tag cache and returns the resulting Paramter objects

type Path

type Path struct {
	// Ref         string      `json:"$ref,omitempty"`
	Summary     string      `json:"summary,omitempty"`
	Description string      `json:"description,omitempty"`
	Get         *Operation  `json:"get,omitempty"`
	Put         *Operation  `json:"put,omitempty"`
	Post        *Operation  `json:"post,omitempty"`
	Delete      *Operation  `json:"delete,omitempty"`
	Options     *Operation  `json:"options,omitempty"`
	Head        *Operation  `json:"head,omitempty"`
	Patch       *Operation  `json:"patch,omitempty"`
	Trace       *Operation  `json:"trace,omitempty"`
	Servers     []Server    `json:"servers,omitempty"`
	Parameters  []Parameter `json:"parameters,omitempty"`
}

Path stores all operations allowed on a particular path

type PathParamUnmarshaler

type PathParamUnmarshaler interface {
	UnmarshalPathParam(param string, info ParamStructTag) error
}

PathParamUnmarshaler is used to allow types to implement their own logic for parsing path parameters

type PlainText

type PlainText[Params any] struct {
	Body   string
	Params Params
	// contains filtered or unexported fields
}

PlainText[Params] is a helper type that effectively works as both a PlainTextRequest[Params] and PlainTextResponse[Params] This is mostly here for convenience

func (*PlainText[Params]) Context

func (r *PlainText[Params]) Context() context.Context

Context returns the context that was part of the original http.Request

func (*PlainText[Params]) OpenAPIRequestSpec

func (r *PlainText[Params]) OpenAPIRequestSpec() RequestSpec

OpenAPIRequestSpec describes the RequestSpec for text/plain requests

func (*PlainText[Params]) OpenAPIResponsesSpec

func (r *PlainText[Params]) OpenAPIResponsesSpec() Responses

OpenAPIResponsesSpec describes the Responses for text/plain requests

func (*PlainText[Params]) ReadRequest

func (r *PlainText[Params]) ReadRequest(req *http.Request) error

ReadRequest reads the body of an http request and assigns it to the Body field using io.ReadAll. This function also reads the parameters using UnmarshalParams and assigns it to the Params field. NOTE: the body of the request is closed after this function is run.

func (*PlainText[Params]) WriteBody added in v0.0.5

func (r *PlainText[Params]) WriteBody(write BodyWriteFunc) error

WriteBody writes the response body

func (*PlainText[Params]) WriteHead added in v0.0.5

func (r *PlainText[Params]) WriteHead(head *ResponseHead) error

WriteHead writes the header for this response object

type PlainTextRequest

type PlainTextRequest[Params any] struct {
	Body   string
	Params Params
	// contains filtered or unexported fields
}

PlainTextRequest is any text/plain request that results in a string body

func (*PlainTextRequest[Params]) Context

func (r *PlainTextRequest[Params]) Context() context.Context

Context returns the context that was part of the original http.Request

func (*PlainTextRequest[Params]) OpenAPIRequestSpec

func (r *PlainTextRequest[Params]) OpenAPIRequestSpec() RequestSpec

OpenAPIRequestSpec describes the RequestSpec for text/plain requests

func (*PlainTextRequest[Params]) ReadRequest

func (r *PlainTextRequest[Params]) ReadRequest(req *http.Request) error

ReadRequest reads the body of an http request and assigns it to the Body field using io.ReadAll. This function also reads the parameters using UnmarshalParams and assigns it to the Params field. NOTE: the body of the request is closed after this function is run.

type PlainTextResponse

type PlainTextResponse[Params any] struct {
	Body   string
	Params Params
}

PlainTextRequest[Params] is any text/plain response that uses a string body

func NewPlainTextResponse

func NewPlainTextResponse[Params any](body string, params Params) *PlainTextResponse[Params]

NewPlainTextResponse creates a PlainTextResponse from a string and params

func (*PlainTextResponse[Params]) OpenAPIResponsesSpec

func (r *PlainTextResponse[Params]) OpenAPIResponsesSpec() Responses

OpenAPIResponsesSpec describes the Responses for text/plain requests

func (*PlainTextResponse[Params]) WriteBody added in v0.0.5

func (r *PlainTextResponse[Params]) WriteBody(write BodyWriteFunc) error

WriteBody writes the response

func (*PlainTextResponse[Params]) WriteHead added in v0.0.5

func (r *PlainTextResponse[Params]) WriteHead(head *ResponseHead) error

WriteHead write the header for this response object

type QueryParamUnmarshaler

type QueryParamUnmarshaler interface {
	UnmarshalQueryParam(value url.Values, info ParamStructTag) error
}

QueryParamUnmarshaler allows a type to add custom validation or parsing logic based on query parameters

type Request

type Request http.Request

Request is just an http.Request that matches the expected interfaces

func (*Request) OpenAPIRequestSpec

func (r *Request) OpenAPIRequestSpec() RequestSpec

OpenAPIRequestSpec returns an empty RequestSpec

func (*Request) ReadRequest

func (r *Request) ReadRequest(req *http.Request) error

ReadRequest assigns the request to the Request struct

type RequestBody

type RequestBody struct {
	Description string               `json:"description"`
	Required    bool                 `json:"required,omitempty"`
	Content     map[string]MediaType `json:"content,omitempty"`
}

RequestBody is the spec of a request body

type RequestReader

type RequestReader interface {
	ReadRequest(*http.Request) error
	OpenAPIRequestSpec() RequestSpec
}

RequestReader is used to allow chimera to automatically read/parse requests as well as describe the parts of a request via openapi

type RequestReaderPtr

type RequestReaderPtr[T any] interface {
	RequestReader
	*T
}

RequestReaderPtr is just a workaround to allow chimera to accept a pointer to a RequestReader and convert to the underlying type

type RequestSpec

type RequestSpec struct {
	Parameters  []Parameter  `json:"parameters,omitempty"`
	RequestBody *RequestBody `json:"requestBody,omitempty"`
}

RequestSpec is the description of an openapi request used in an Operation

func (*RequestSpec) Merge

func (r *RequestSpec) Merge(other RequestSpec)

Merge folds a Request object into the current Request object In general, the provided request takes precedence over the current one

type Response

type Response struct {
	StatusCode int
	Headers    http.Header
	Body       []byte
}

Response is a simple response type to support creating responses on the fly it is mostly useful for middleware where execution needs to halt and an undefined response needs to be returned

func NewResponse

func NewResponse(body []byte, statusCode int, header http.Header) *Response

NewResponse creates a response with the body, status, and header

func (*Response) Header

func (r *Response) Header() http.Header

Header returns the current header for http.ResponseWriter compatibility

func (*Response) OpenAPIResponsesSpec

func (r *Response) OpenAPIResponsesSpec() Responses

OpenAPIResponsesSpec returns an empty Responses object

func (*Response) Write

func (r *Response) Write(body []byte) (int, error)

Write stores the body in the Reponse object for use later

func (*Response) WriteBody added in v0.0.5

func (r *Response) WriteBody(write BodyWriteFunc) error

WriteBody writes the exact body from the struct

func (*Response) WriteHead added in v0.0.5

func (r *Response) WriteHead(head *ResponseHead) error

WriteHead returns the status code and header for this response object

func (*Response) WriteHeader

func (r *Response) WriteHeader(status int)

WriteHeader stores the status code in the Reponse object for use later

type ResponseBodyWriter added in v0.0.5

type ResponseBodyWriter interface {
	WriteBody(write BodyWriteFunc) error
}

type ResponseHead added in v0.0.4

type ResponseHead struct {
	StatusCode int
	Headers    http.Header
}

ResponseHead contains the head of an HTTP Response

type ResponseHeadWriter added in v0.0.5

type ResponseHeadWriter interface {
	WriteHead(*ResponseHead) error
}

type ResponseSpec

type ResponseSpec struct {
	Description string               `json:"description"`
	Headers     map[string]Parameter `json:"headers,omitempty"`
	Content     map[string]MediaType `json:"content,omitempty"`
	Links       map[string]Link      `json:"links,omitempty"`
}

ResponseSpec is an openapi Response description

type ResponseStructTag

type ResponseStructTag struct {
	StatusCode  int    `structtag:"statusCode"`
	Description string `structtag:"description"`
}

ResponseStructTag represents the "response" struct tag used by OneOfResponse it has a statusCode and a description

type ResponseWriter

type ResponseWriter interface {
	ResponseBodyWriter
	ResponseHeadWriter
	OpenAPIResponsesSpec() Responses
}

ResponseWriter allows chimera to automatically write responses

type ResponseWriterPtr

type ResponseWriterPtr[T any] interface {
	ResponseWriter
	*T
}

ResponseWriterPtr is just a workaround to allow chimera to accept a pointer to a ResponseWriter and convert to the underlying type

type Responses

type Responses map[string]ResponseSpec

Responses is a map of status code string to ResponseSpec

func (*Responses) Merge

func (r *Responses) Merge(other Responses)

Merge combines 2 responses objects into a single map

type Route

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

Route contains basic info about an API route and allows for inline editing of itself

func Delete

func Delete[ReqPtr RequestReaderPtr[Req], Req any, RespPtr ResponseWriterPtr[Resp], Resp any](api *API, path string, handler HandlerFunc[ReqPtr, Req, RespPtr, Resp]) Route

Delete adds a "DELETE" route to the API object which will invode the handler function on route match it also returns the Route object to allow easy updates of the Operation spec

func Get

func Get[ReqPtr RequestReaderPtr[Req], Req any, RespPtr ResponseWriterPtr[Resp], Resp any](api *API, path string, handler HandlerFunc[ReqPtr, Req, RespPtr, Resp]) Route

Get adds a "GET" route to the API object which will invode the handler function on route match it also returns the Route object to allow easy updates of the Operation spec

func Options

func Options[ReqPtr RequestReaderPtr[Req], Req any, RespPtr ResponseWriterPtr[Resp], Resp any](api *API, path string, handler HandlerFunc[ReqPtr, Req, RespPtr, Resp]) Route

Options adds a "OPTIONS" route to the API object which will invode the handler function on route match it also returns the Route object to allow easy updates of the Operation spec

func Patch

func Patch[ReqPtr RequestReaderPtr[Req], Req any, RespPtr ResponseWriterPtr[Resp], Resp any](api *API, path string, handler HandlerFunc[ReqPtr, Req, RespPtr, Resp]) Route

Patch adds a "PATCH" route to the API object which will invode the handler function on route match it also returns the Route object to allow easy updates of the Operation spec

func Post

func Post[ReqPtr RequestReaderPtr[Req], Req any, RespPtr ResponseWriterPtr[Resp], Resp any](api *API, path string, handler HandlerFunc[ReqPtr, Req, RespPtr, Resp]) Route

Post adds a "POST" route to the API object which will invode the handler function on route match it also returns the Route object to allow easy updates of the Operation spec

func Put

func Put[ReqPtr RequestReaderPtr[Req], Req any, RespPtr ResponseWriterPtr[Resp], Resp any](api *API, path string, handler HandlerFunc[ReqPtr, Req, RespPtr, Resp]) Route

Put adds a "PUT" route to the API object which will invode the handler function on route match it also returns the Route object to allow easy updates of the Operation spec

func (Route) Internalize

func (r Route) Internalize() Route

Internalize hides the route from the api spec

func (Route) OpenAPIOperationSpec

func (r Route) OpenAPIOperationSpec() *Operation

OpenAPIOperationSpec returns the Operation spec for this route

func (Route) UsingOperation

func (r Route) UsingOperation(op Operation) Route

UsingOperation replaces the operation's spec for this route

func (Route) UsingRequest

func (r Route) UsingRequest(req RequestSpec) Route

UsingRequest replaces the operation's request spec for this route

func (Route) UsingResponses

func (r Route) UsingResponses(resp Responses) Route

UsingResponses replaces the operation's responses for this route

func (Route) WithOperation

func (r Route) WithOperation(op Operation) Route

WithOperation performs a merge on the operation's spec for this route

func (Route) WithRequest

func (r Route) WithRequest(req RequestSpec) Route

WithRequest performs a merge on the operation's request spec for this route

func (Route) WithResponseCode

func (r Route) WithResponseCode(code int) Route

WithResponseCode sets the default response code for this route NOTE: the first time this is called, the presumption is that default code has been set based on http method

func (Route) WithResponses

func (r Route) WithResponses(resp Responses) Route

WithResponses performs a merge on the operation's responses for this route

type RouteContext

type RouteContext interface {
	// Path returns the path that the route was setup with (i.e. /route/{var})
	Path() string
	// Method returns the method intended to be used by the route
	Method() string
	// DefaultResponseCode returns the default response code for this route
	DefaultResponseCode() int
	// GetResponseHead gets the ResponseHead based on the default status code and a ResponseWriter
	GetResponseHead(ResponseWriter) (*ResponseHead, error)
	// GetResponse turns a ResponseWriter into *Response based on the default status code
	GetResponse(ResponseWriter) (*Response, error)
}

RouteContext contains basic info about a matched Route

type SchemaType

type SchemaType int

SchemaType describes the type of a schema

type Server

type Server struct {
	URL         string                    `json:"url,omitempty"`
	Description string                    `json:"description,omitempty"`
	Variables   map[string]ServerVariable `json:"variables,omitempty"`
}

Server describes a server

type ServerVariable

type ServerVariable struct {
	Enum        []string `json:"enum,omitempty"`
	Default     string   `json:"default,omitempty"`
	Description string   `json:"description,omitempty"`
}

ServerVariable is a variable used in servers

type Style

type Style int

Style denotes the openapi "style" of a parameter

const (
	DefaultStyle Style = iota
	SimpleStyle
	LabelStyle
	MatrixStyle
	SpaceDelimitedStyle
	PipeDelimitedStyle
	DeepObjectStyle
	FormStyle
)

func (Style) UnmarshalTagOption

func (p Style) UnmarshalTagOption(field reflect.StructField, value string) (reflect.Value, error)

UnmarshalTagOption is used to unmarshal a Style found in a struct tag

type Tag

type Tag struct {
	Name        string `json:"name"`
	Description string `json:"description"`
}

Tag is used to tag parts of an API

Jump to

Keyboard shortcuts

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