Documentation
¶
Index ¶
- Constants
- Variables
- func EnableHTMLRender()
- func EndDatedQueryParam(value bool) url.Values
- func GetIDParam(r *http.Request, name string) string
- func GetIDParamFromCtx(ctx context.Context, name string) string
- func GetLoggerFromContext(ctx context.Context) *slog.Logger
- func GetRequestBodyFromContext[T any](ctx context.Context) (T, bool)
- func GetResourceFromContext[T Resource](ctx context.Context, key ContextKey) (T, error)
- func Handler(do func(http.ResponseWriter, *http.Request) render.Renderer) http.HandlerFunc
- func IDParamKey(name string) string
- func MustRenderHTML(tmpl *template.Template, data any) string
- func MustRenderHTMLMap(tmpl *template.Template, tmplMap map[string]string, name string, data any) string
- func NewContextWithLogger(ctx context.Context, logger *slog.Logger) context.Context
- func ReadRequestBodyAndDo[T RendererBinder](do func(http.ResponseWriter, *http.Request, T) (render.Renderer, *ErrResponse), ...) http.HandlerFunc
- type API
- func (a *API[T]) AddCustomIDRoute(method, pattern string, handler http.Handler) *API[T]
- func (a *API[T]) AddCustomRootRoute(method, pattern string, handler http.Handler) *API[T]
- func (a *API[T]) AddCustomRoute(method, pattern string, handler http.Handler) *API[T]
- func (a *API[T]) AddIDMiddleware(m func(http.Handler) http.Handler) *API[T]
- func (a *API[T]) AddMiddleware(m func(http.Handler) http.Handler) *API[T]
- func (a *API[T]) AddNestedAPI(childAPI RelatedAPI) *API[T]
- func (a *API[T]) AddServerSentEventHandler(pattern string) chan *ServerSentEvent
- func (a *API[T]) AnyClient(addr string) *Client[*AnyResource]
- func (a *API[T]) ApplyDefaultMiddleware(r chi.Router)
- func (a *API[T]) ApplyExtension(e Extension[T]) *API[T]
- func (a *API[T]) Base() string
- func (a *API[T]) ChildAPIs() map[string]RelatedAPI
- func (a *API[T]) Client(addr string) *Client[T]
- func (a *API[T]) Command() *cobra.Command
- func (a *API[T]) CreateClientMap(parent *Client[*AnyResource]) map[string]*Client[*AnyResource]
- func (a *API[T]) Done() <-chan struct{}
- func (a *API[T]) GetFromRequest(r *http.Request) (T, *ErrResponse)
- func (a *API[T]) GetIDParam(r *http.Request) string
- func (a *API[T]) GetIDParamFromCtx(ctx context.Context) string
- func (a *API[T]) GetParentIDParam(r *http.Request) string
- func (a *API[T]) GetRequestedResource(r *http.Request) (T, *ErrResponse)
- func (a *API[T]) GetRequestedResourceAndDo(do func(http.ResponseWriter, *http.Request, T) (render.Renderer, *ErrResponse)) http.HandlerFunc
- func (a *API[T]) GetRequestedResourceAndDoMiddleware(do func(http.ResponseWriter, *http.Request, T) (*http.Request, *ErrResponse)) func(next http.Handler) http.Handler
- func (a *API[T]) GetResourceFromContext(ctx context.Context) (T, error)
- func (a *API[T]) HandleServerSentEvents(EventsBroadcastChannel *broadcastChannel[*ServerSentEvent]) http.HandlerFunc
- func (a *API[T]) IDParamKey() string
- func (a *API[T]) Modify(modify func(*API[T])) *API[T]
- func (a *API[T]) Name() string
- func (a *API[T]) NewContextWithRequestBody(ctx context.Context, item T) context.Context
- func (a *API[T]) Parent() RelatedAPI
- func (a *API[T]) ParentContextKey() ContextKey
- func (a *API[T]) ReadRequestBodyAndDo(do func(http.ResponseWriter, *http.Request, T) (T, *ErrResponse)) http.HandlerFunc
- func (a *API[T]) Route(r chi.Router) error
- func (a *API[T]) Router() (chi.Router, error)
- func (a *API[T]) RunCLI()
- func (a *API[T]) Serve(address string) error
- func (a *API[T]) SetAfterCreateOrUpdate(afterCreateOrUpdate func(http.ResponseWriter, *http.Request, T) *ErrResponse) *API[T]
- func (a *API[T]) SetAfterDelete(after func(http.ResponseWriter, *http.Request) *ErrResponse) *API[T]
- func (a *API[T]) SetBeforeDelete(before func(http.ResponseWriter, *http.Request) *ErrResponse) *API[T]
- func (a *API[T]) SetCustomResponseCode(verb string, code int) *API[T]
- func (a *API[T]) SetGetAllFilter(f func(*http.Request) FilterFunc[T]) *API[T]
- func (a *API[T]) SetGetAllResponseWrapper(getAllResponder func([]T) render.Renderer) *API[T]
- func (a *API[T]) SetOnCreateOrUpdate(onCreateOrUpdate func(http.ResponseWriter, *http.Request, T) *ErrResponse) *API[T]
- func (a *API[T]) SetResponseWrapper(responseWrapper func(T) render.Renderer) *API[T]
- func (a *API[T]) SetStorage(s Storage[T]) *API[T]
- func (a *API[T]) Stop()
- func (a *API[T]) WithContext(ctx context.Context) *API[T]
- type AnyResource
- type BuilderError
- type Client
- func (c *Client[T]) Command(name string, input *cliArgs) *cobra.Command
- func (c *Client[T]) Delete(ctx context.Context, id string, parentIDs ...string) (*Response[T], error)
- func (c *Client[T]) DeleteRequest(ctx context.Context, id string, parentIDs ...string) (*http.Request, error)
- func (c *Client[T]) DeleteWithEditor(ctx context.Context, id string, requestEditor RequestEditor, ...) (*Response[T], error)
- func (c *Client[T]) Get(ctx context.Context, id string, parentIDs ...string) (*Response[T], error)
- func (c *Client[T]) GetAll(ctx context.Context, rawQuery string, parentIDs ...string) (*Response[*ResourceList[T]], error)
- func (c *Client[T]) GetAllAny(ctx context.Context, rawQuery string, parentIDs ...string) (*Response[any], error)
- func (c *Client[T]) GetAllAnyWithEditor(ctx context.Context, rawQuery string, requestEditor RequestEditor, ...) (*Response[any], error)
- func (c *Client[T]) GetAllRequest(ctx context.Context, rawQuery string, parentIDs ...string) (*http.Request, error)
- func (c *Client[T]) GetAllWithEditor(ctx context.Context, rawQuery string, requestEditor RequestEditor, ...) (*Response[*ResourceList[T]], error)
- func (c *Client[T]) GetRequest(ctx context.Context, id string, parentIDs ...string) (*http.Request, error)
- func (c *Client[T]) GetWithEditor(ctx context.Context, id string, requestEditor RequestEditor, ...) (*Response[T], error)
- func (c *Client[T]) MakeGenericRequest(req *http.Request, target any) (*Response[any], error)
- func (c *Client[T]) MakeRequest(req *http.Request, expectedStatusCode int) (*Response[T], error)
- func (c *Client[T]) MakeRequestWithEditor(req *http.Request, expectedStatusCode int, requestEditor RequestEditor) (*Response[T], error)
- func (c *Client[T]) NewRequestWithParentIDs(ctx context.Context, method string, body io.Reader, id string, ...) (*http.Request, error)
- func (c *Client[T]) Patch(ctx context.Context, id string, resource T, parentIDs ...string) (*Response[T], error)
- func (c *Client[T]) PatchRaw(ctx context.Context, id, body string, parentIDs ...string) (*Response[T], error)
- func (c *Client[T]) PatchRawWithEditor(ctx context.Context, id, body string, requestEditor RequestEditor, ...) (*Response[T], error)
- func (c *Client[T]) PatchRequest(ctx context.Context, body io.Reader, id string, parentIDs ...string) (*http.Request, error)
- func (c *Client[T]) PatchWithEditor(ctx context.Context, id string, resource T, requestEditor RequestEditor, ...) (*Response[T], error)
- func (c *Client[T]) Post(ctx context.Context, resource T, parentIDs ...string) (*Response[T], error)
- func (c *Client[T]) PostRaw(ctx context.Context, body string, parentIDs ...string) (*Response[T], error)
- func (c *Client[T]) PostRawWithEditor(ctx context.Context, body string, requestEditor RequestEditor, ...) (*Response[T], error)
- func (c *Client[T]) PostRequest(ctx context.Context, body io.Reader, parentIDs ...string) (*http.Request, error)
- func (c *Client[T]) PostWithEditor(ctx context.Context, resource T, requestEditor RequestEditor, ...) (*Response[T], error)
- func (c *Client[T]) Put(ctx context.Context, resource T, parentIDs ...string) (*Response[T], error)
- func (c *Client[T]) PutRaw(ctx context.Context, id, body string, parentIDs ...string) (*Response[T], error)
- func (c *Client[T]) PutRawWithEditor(ctx context.Context, id, body string, requestEditor RequestEditor, ...) (*Response[T], error)
- func (c *Client[T]) PutRequest(ctx context.Context, body io.Reader, id string, parentIDs ...string) (*http.Request, error)
- func (c *Client[T]) PutWithEditor(ctx context.Context, resource T, requestEditor RequestEditor, ...) (*Response[T], error)
- func (c *Client[T]) SetCustomResponseCode(verb string, code int) *Client[T]
- func (c *Client[T]) SetCustomResponseCodeMap(customResponseCodes map[string]int) *Client[T]
- func (c *Client[T]) SetHTTPClient(client *http.Client) *Client[T]
- func (c *Client[T]) SetRequestEditor(requestEditor RequestEditor) *Client[T]
- func (c *Client[T]) URL(id string, parentIDs ...string) (string, error)
- type ContextKey
- type DefaultRenderer
- type DefaultResource
- type EndDateable
- type ErrResponse
- type Extension
- type FilterFunc
- type HTMLer
- type ID
- type KVStorage
- type NilResource
- type Patcher
- type PrintableResponse
- type RelatedAPI
- type RendererBinder
- type RequestEditor
- type Resource
- type ResourceList
- type Response
- type ServerSentEvent
- type Storage
Constants ¶
const MethodGetAll = "GetAll"
MethodGetAll is the same as http.MethodGet, but can be used when setting custom response codes
Variables ¶
var DefaultMiddleware = []func(http.Handler) http.Handler{ middleware.RequestID, middleware.RealIP, middleware.Recoverer, }
var ErrForbidden = &ErrResponse{HTTPStatusCode: http.StatusForbidden, StatusText: "Forbidden"}
var ErrMethodNotAllowedResponse = &ErrResponse{HTTPStatusCode: http.StatusMethodNotAllowed, StatusText: "Method not allowed."}
var ErrNotFound = errors.New("resource not found")
var ErrNotFoundResponse = &ErrResponse{HTTPStatusCode: http.StatusNotFound, StatusText: "Resource not found."}
Functions ¶
func EnableHTMLRender ¶ added in v0.22.0
func EnableHTMLRender()
EnableHTMLRender overrides the default render.Respond function to add support for the babyapi.HTMLer interface that renders HTML responses
func EndDatedQueryParam ¶ added in v0.13.0
func GetIDParam ¶
GetIDParam gets resource ID from the request URL for a resource by name
func GetIDParamFromCtx ¶ added in v0.18.0
GetIDParamFromCtx gets resource ID from the request URL for a resource by name
func GetLoggerFromContext ¶
GetLoggerFromContext returns the structured logger from the context. It expects to use an HTTP request context to get a logger with details from middleware
func GetRequestBodyFromContext ¶ added in v0.15.0
GetRequestBodyFromContext gets an API resource from the request context. It can only be used in URL paths that include the resource ID
func GetResourceFromContext ¶
func GetResourceFromContext[T Resource](ctx context.Context, key ContextKey) (T, error)
GetResourceFromContext gets the API resource from request context
func Handler ¶ added in v0.3.0
func Handler(do func(http.ResponseWriter, *http.Request) render.Renderer) http.HandlerFunc
func IDParamKey ¶
IDParamKey gets the chi URL param key used for the ID of a resource
func MustRenderHTML ¶ added in v0.2.0
MustRenderHTML renders the provided template and data to a string. Panics if there is an error
func MustRenderHTMLMap ¶ added in v0.3.0
func MustRenderHTMLMap(tmpl *template.Template, tmplMap map[string]string, name string, data any) string
MustRenderHTMLMap accepts a map of template name to the template contents. It parses the template strings and executes the template with provided data. Since the template map doesn't preserve order, the name of the base/root template must be provided. A base *template.Template can be passed in to provide custom functions or already-parsed templates. Use nil if nothing is required. Panics if there is an error
func NewContextWithLogger ¶
NewContextWithLogger stores a structured logger in the context
func ReadRequestBodyAndDo ¶ added in v0.15.0
func ReadRequestBodyAndDo[T RendererBinder](do func(http.ResponseWriter, *http.Request, T) (render.Renderer, *ErrResponse), instance func() T) http.HandlerFunc
ReadRequestBodyAndDo is a helper function that can be used without an API to handle a request
Types ¶
type API ¶
type API[T Resource] struct { // Storage is the interface used by the API server to read/write resources Storage[T] // GetAll is the handler for /base and returns an array of resources GetAll http.HandlerFunc // Get is the handler for /base/{ID} and returns a requested resource by ID Get http.HandlerFunc // Post is used to create new resources at /base Post http.HandlerFunc // Put is used to idempotently create or modify resources at /base/{ID} Put http.HandlerFunc // Patch is used to modify resources at /base/{ID} Patch http.HandlerFunc // Delete is used to delete the resource at /base/{ID} Delete http.HandlerFunc // contains filtered or unexported fields }
API encapsulates all handlers and other pieces of code required to run the CRUID API based on the provided Resource type
func NewAPI ¶
NewAPI initializes an API using the provided name, base URL path, and function to create a new instance of the resource with defaults
func NewRootAPI ¶ added in v0.4.0
func NewRootAPI(name, base string) *API[*NilResource]
NewRootAPI initializes an API which can serve as a top-level parent of other APIs, so multiple unrelated resources can exist without any parent/child relationship. This API does not have any default handlers, but custom handlers can still be added. Since there are no IDs in the path, Get and GetAll routes cannot be differentiated so only Get is used
func (*API[T]) AddCustomIDRoute ¶
AddCustomIDRoute appends a custom API route to the base path after the ID URL parameter: /base/{ID}/custom-route. The handler for this route can access the requested resource using GetResourceFromContext
func (*API[T]) AddCustomRootRoute ¶ added in v0.3.0
AddCustomRootRoute appends a custom API route to the absolute root path ("/"). It does not work for APIs with parents because it would conflict with the parent's route. Panics if the API is already a child when this is called
func (*API[T]) AddCustomRoute ¶
AddCustomRoute appends a custom API route to the base path: /base/custom-route
func (*API[T]) AddIDMiddleware ¶ added in v0.3.0
AddIDMiddleware adds a middleware which is active only on the paths including a resource ID
func (*API[T]) AddMiddleware ¶ added in v0.3.0
AddMiddleware adds a middleware which is active only on the paths without resource ID
func (*API[T]) AddNestedAPI ¶
func (a *API[T]) AddNestedAPI(childAPI RelatedAPI) *API[T]
AddNestedAPI adds a child API to this API and initializes the parent relationship on the child's side
func (*API[T]) AddServerSentEventHandler ¶ added in v0.2.0
func (a *API[T]) AddServerSentEventHandler(pattern string) chan *ServerSentEvent
AddServerSentEventHandler is a shortcut for HandleServerSentEvents that automatically creates and returns the events channel and adds a custom handler for GET requests matching the provided pattern
func (*API[T]) AnyClient ¶
func (a *API[T]) AnyClient(addr string) *Client[*AnyResource]
AnyClient returns a new Client based on the API's configuration. It is a shortcut for NewClient
func (*API[T]) ApplyDefaultMiddleware ¶ added in v0.23.0
func (a *API[T]) ApplyDefaultMiddleware(r chi.Router)
func (*API[T]) ApplyExtension ¶ added in v0.6.0
ApplyExtension adds an Extension to the API and applies it
func (*API[T]) ChildAPIs ¶ added in v0.6.0
func (a *API[T]) ChildAPIs() map[string]RelatedAPI
ChildAPIs returns the nested children APIs
func (*API[T]) Client ¶
Client returns a new Client based on the API's configuration. It is a shortcut for NewClient
func (*API[T]) CreateClientMap ¶ added in v0.4.0
func (a *API[T]) CreateClientMap(parent *Client[*AnyResource]) map[string]*Client[*AnyResource]
CreateClientMap returns a map of API names to the corresponding Client for that child API. This makes it easy to use child APIs dynamically. The initial parent/base client must be provided so child APIs can use NewSubClient
func (*API[T]) Done ¶ added in v0.2.0
func (a *API[T]) Done() <-chan struct{}
Done returns a channel that's closed when the API stops, similar to context.Done()
func (*API[T]) GetFromRequest ¶
func (a *API[T]) GetFromRequest(r *http.Request) (T, *ErrResponse)
GetFromRequest will read the API's resource type from the request body or request context
func (*API[T]) GetIDParam ¶
GetIDParam gets resource ID from the request URL for this API's resource
func (*API[T]) GetIDParamFromCtx ¶ added in v0.18.0
GetIDParamFromCtx gets resource ID from the request URL for this API's resource
func (*API[T]) GetParentIDParam ¶
GetParentIDParam reads the URL param from the request to get the ID of the parent resource
func (*API[T]) GetRequestedResource ¶
func (a *API[T]) GetRequestedResource(r *http.Request) (T, *ErrResponse)
GetRequestedResource reads the API's resource from storage based on the ID in the request URL
func (*API[T]) GetRequestedResourceAndDo ¶
func (a *API[T]) GetRequestedResourceAndDo(do func(http.ResponseWriter, *http.Request, T) (render.Renderer, *ErrResponse)) http.HandlerFunc
GetRequestedResourceAndDo is a wrapper that handles getting a resource from storage based on the ID in the request URL and rendering the response. This is useful for imlementing a CustomIDRoute
func (*API[T]) GetRequestedResourceAndDoMiddleware ¶ added in v0.3.0
func (a *API[T]) GetRequestedResourceAndDoMiddleware(do func(http.ResponseWriter, *http.Request, T) (*http.Request, *ErrResponse)) func(next http.Handler) http.Handler
GetRequestedResourceAndDoMiddleware is a shortcut for creating an ID-scoped middleware that gets the requested resource from storage, calls the provided 'do' function, and calls next.ServeHTTP. If the resource is not found for a PUT request, the error is ignored The 'do' function returns *http.Request so the request context can be modified by middleware
func (*API[T]) GetResourceFromContext ¶
GetResourceFromContext gets the API resource from request context
func (*API[T]) HandleServerSentEvents ¶ added in v0.2.0
func (a *API[T]) HandleServerSentEvents(EventsBroadcastChannel *broadcastChannel[*ServerSentEvent]) http.HandlerFunc
HandleServerSentEvents is a handler function that will listen on the provided channel and write events to the HTTP response
func (*API[T]) IDParamKey ¶
IDParamKey gets the chi URL param key used for this API
func (*API[T]) Modify ¶ added in v0.19.0
Modify allows inline, fluent-style modification of the API, so custom modifications can be made in the same fluent style as the built-in methods
func (*API[T]) NewContextWithRequestBody ¶
NewContextWithRequestBody stores the API resource in the context
func (*API[T]) ParentContextKey ¶
func (a *API[T]) ParentContextKey() ContextKey
ParentContextKey returns the context key for the direct parent's resource
func (*API[T]) ReadRequestBodyAndDo ¶
func (a *API[T]) ReadRequestBodyAndDo(do func(http.ResponseWriter, *http.Request, T) (T, *ErrResponse)) http.HandlerFunc
ReadRequestBodyAndDo is a wrapper that handles decoding the request body into the resource type and rendering a response
func (*API[T]) RunCLI ¶
func (a *API[T]) RunCLI()
RunCLI is an alternative entrypoint to running the API beyond just Serve. It allows running a server or client based on the provided CLI arguments. Use this in your main() function
func (*API[T]) SetAfterCreateOrUpdate ¶ added in v0.6.0
func (a *API[T]) SetAfterCreateOrUpdate(afterCreateOrUpdate func(http.ResponseWriter, *http.Request, T) *ErrResponse) *API[T]
func (*API[T]) SetAfterDelete ¶
func (a *API[T]) SetAfterDelete(after func(http.ResponseWriter, *http.Request) *ErrResponse) *API[T]
SetAfterDelete sets a function that is executed after deleting a resource. It is useful for additional cleanup or other actions that should be done after deleting
func (*API[T]) SetBeforeDelete ¶
func (a *API[T]) SetBeforeDelete(before func(http.ResponseWriter, *http.Request) *ErrResponse) *API[T]
SetBeforeDelete sets a function that is executing before deleting a resource. It is useful for additional validation before completing the delete
func (*API[T]) SetCustomResponseCode ¶ added in v0.2.0
SetCustomResponseCode will override the default response codes for the specified HTTP verb. Use MethodGetAll to set the response code for listing all resources
func (*API[T]) SetGetAllFilter ¶
func (a *API[T]) SetGetAllFilter(f func(*http.Request) FilterFunc[T]) *API[T]
SetGetAllFilter sets a function that can use the request context to create a filter for GetAll. Use this to introduce custom filtering after reading from storage. This should mostly be used with the default storage client options. If you are using a custom SQL or other query-based implementation, it is better to use the url.Values to create custom filtering
func (*API[T]) SetGetAllResponseWrapper ¶ added in v0.2.0
SetGetAllResponseWrapper sets a function that can create a custom response for GetAll. This function will receive a slice of Resources from storage and must return a render.Renderer
func (*API[T]) SetOnCreateOrUpdate ¶
func (a *API[T]) SetOnCreateOrUpdate(onCreateOrUpdate func(http.ResponseWriter, *http.Request, T) *ErrResponse) *API[T]
SetOnCreateOrUpdate runs on POST, PATCH, and PUT requests before saving the created/updated resource. This is useful for adding more validations or performing tasks related to resources such as initializing schedules or sending events
func (*API[T]) SetResponseWrapper ¶ added in v0.2.0
SetResponseWrapper sets a function that returns a new Renderer before responding with T. This is used to add more data to responses that isn't directly from storage
func (*API[T]) SetStorage ¶
type AnyResource ¶
AnyResource is intended to create a "generic" Client
func (AnyResource) GetID ¶
func (ar AnyResource) GetID() string
func (*AnyResource) Render ¶
func (*AnyResource) Render(w http.ResponseWriter, r *http.Request) error
type BuilderError ¶ added in v0.6.0
type BuilderError struct {
// contains filtered or unexported fields
}
BuilderError is used for combining errors that may occur when constructing a new API
func (BuilderError) Error ¶ added in v0.6.0
func (e BuilderError) Error() string
type Client ¶
Client is used to interact with the provided Resource's API
func NewSubClient ¶
NewSubClient creates a Client as a child of an existing Client. This is useful for accessing nested API resources
func (*Client[T]) Delete ¶
func (c *Client[T]) Delete(ctx context.Context, id string, parentIDs ...string) (*Response[T], error)
Delete makes a DELETE request to delete a resource by ID
func (*Client[T]) DeleteRequest ¶ added in v0.11.0
func (c *Client[T]) DeleteRequest(ctx context.Context, id string, parentIDs ...string) (*http.Request, error)
DeleteRequest creates a request that can be used to delete a resource
func (*Client[T]) DeleteWithEditor ¶ added in v0.17.0
func (c *Client[T]) DeleteWithEditor(ctx context.Context, id string, requestEditor RequestEditor, parentIDs ...string) (*Response[T], error)
DeleteWithEditor makes a DELETE request to delete a resource by ID after modifying the request with requestEditor
func (*Client[T]) GetAll ¶
func (c *Client[T]) GetAll(ctx context.Context, rawQuery string, parentIDs ...string) (*Response[*ResourceList[T]], error)
GetAll gets all resources from the API
func (*Client[T]) GetAllAny ¶ added in v0.12.0
func (c *Client[T]) GetAllAny(ctx context.Context, rawQuery string, parentIDs ...string) (*Response[any], error)
GetAllAny allows using GetAll when using a custom response wrapper
func (*Client[T]) GetAllAnyWithEditor ¶ added in v0.17.0
func (c *Client[T]) GetAllAnyWithEditor(ctx context.Context, rawQuery string, requestEditor RequestEditor, parentIDs ...string) (*Response[any], error)
GetAllAnyWithEditor allows using GetAll when using a custom response wrapper after modifying the request with requestEditor
func (*Client[T]) GetAllRequest ¶ added in v0.11.0
func (c *Client[T]) GetAllRequest(ctx context.Context, rawQuery string, parentIDs ...string) (*http.Request, error)
GetAllRequest creates a request that can be used to get all resources
func (*Client[T]) GetAllWithEditor ¶ added in v0.17.0
func (c *Client[T]) GetAllWithEditor(ctx context.Context, rawQuery string, requestEditor RequestEditor, parentIDs ...string) (*Response[*ResourceList[T]], error)
GetAllWithEditor gets all resources from the API after modifying the request with requestEditor
func (*Client[T]) GetRequest ¶ added in v0.11.0
func (c *Client[T]) GetRequest(ctx context.Context, id string, parentIDs ...string) (*http.Request, error)
GetRequest creates a request that can be used to get a resource
func (*Client[T]) GetWithEditor ¶ added in v0.17.0
func (c *Client[T]) GetWithEditor(ctx context.Context, id string, requestEditor RequestEditor, parentIDs ...string) (*Response[T], error)
GetWithEditor will get a resource by ID after modifying the request with requestEditor
func (*Client[T]) MakeGenericRequest ¶ added in v0.11.0
MakeGenericRequest allows making a request without specifying the return type. It accepts a pointer receiver to pass to json.Unmarshal. This allows returning any type using the Client.
func (*Client[T]) MakeRequest ¶
MakeRequest generically sends an HTTP request after calling the request editor and checks the response code It returns a babyapi.Response which contains the http.Response after extracting the body to Body string and JSON decoding the resource type into Data if the response is JSON
func (*Client[T]) MakeRequestWithEditor ¶ added in v0.17.0
func (c *Client[T]) MakeRequestWithEditor(req *http.Request, expectedStatusCode int, requestEditor RequestEditor) (*Response[T], error)
MakeRequestWithEditor is like MakeRequest, but allows setting a RequestEditor instead of using the Client's configured editor
func (*Client[T]) NewRequestWithParentIDs ¶
func (c *Client[T]) NewRequestWithParentIDs(ctx context.Context, method string, body io.Reader, id string, parentIDs ...string) (*http.Request, error)
NewRequestWithParentIDs uses http.NewRequestWithContext to create a new request using the URL created from the provided ID and parent IDs
func (*Client[T]) Patch ¶
func (c *Client[T]) Patch(ctx context.Context, id string, resource T, parentIDs ...string) (*Response[T], error)
Patch makes a PATCH request to modify a resource by ID
func (*Client[T]) PatchRaw ¶
func (c *Client[T]) PatchRaw(ctx context.Context, id, body string, parentIDs ...string) (*Response[T], error)
PatchRaw makes a PATCH request to modify a resource by ID. It uses the provided string as the request body
func (*Client[T]) PatchRawWithEditor ¶ added in v0.17.0
func (c *Client[T]) PatchRawWithEditor(ctx context.Context, id, body string, requestEditor RequestEditor, parentIDs ...string) (*Response[T], error)
PatchRawWithEditor makes a PATCH request to modify a resource by ID after modifying the request with requestEditor. It uses the provided string as the request body
func (*Client[T]) PatchRequest ¶ added in v0.11.0
func (c *Client[T]) PatchRequest(ctx context.Context, body io.Reader, id string, parentIDs ...string) (*http.Request, error)
PatchRequest creates a request that can be used to PATCH a resource
func (*Client[T]) PatchWithEditor ¶ added in v0.17.0
func (c *Client[T]) PatchWithEditor(ctx context.Context, id string, resource T, requestEditor RequestEditor, parentIDs ...string) (*Response[T], error)
PatchWithEditor makes a PATCH request to modify a resource by ID after modifying the request with requestEditor
func (*Client[T]) Post ¶
func (c *Client[T]) Post(ctx context.Context, resource T, parentIDs ...string) (*Response[T], error)
Post makes a POST request to create a new resource
func (*Client[T]) PostRaw ¶
func (c *Client[T]) PostRaw(ctx context.Context, body string, parentIDs ...string) (*Response[T], error)
PostRaw makes a POST request using the provided string as the body
func (*Client[T]) PostRawWithEditor ¶ added in v0.17.0
func (c *Client[T]) PostRawWithEditor(ctx context.Context, body string, requestEditor RequestEditor, parentIDs ...string) (*Response[T], error)
PostRawWithEditor makes a POST request using the provided string as the body after modifying the request with requestEditor
func (*Client[T]) PostRequest ¶ added in v0.11.0
func (c *Client[T]) PostRequest(ctx context.Context, body io.Reader, parentIDs ...string) (*http.Request, error)
PostRequest creates a request that can be used to POST a resource
func (*Client[T]) PostWithEditor ¶ added in v0.17.0
func (c *Client[T]) PostWithEditor(ctx context.Context, resource T, requestEditor RequestEditor, parentIDs ...string) (*Response[T], error)
PostWithEditor makes a POST request to create a new resource after modifying the request with requestEditor
func (*Client[T]) PutRaw ¶
func (c *Client[T]) PutRaw(ctx context.Context, id, body string, parentIDs ...string) (*Response[T], error)
PutRaw makes a PUT request to create/modify a resource by ID. It uses the provided string as the request body
func (*Client[T]) PutRawWithEditor ¶ added in v0.17.0
func (c *Client[T]) PutRawWithEditor(ctx context.Context, id, body string, requestEditor RequestEditor, parentIDs ...string) (*Response[T], error)
PutRaw makes a PUT request to create/modify a resource by ID. It uses the provided string as the request body
func (*Client[T]) PutRequest ¶ added in v0.11.0
func (c *Client[T]) PutRequest(ctx context.Context, body io.Reader, id string, parentIDs ...string) (*http.Request, error)
PutRequest creates a request that can be used to PUT a resource
func (*Client[T]) PutWithEditor ¶ added in v0.17.0
func (c *Client[T]) PutWithEditor(ctx context.Context, resource T, requestEditor RequestEditor, parentIDs ...string) (*Response[T], error)
PutWithEditor makes a PUT request to create/modify a resource by ID after modifying the request with requestEditor
func (*Client[T]) SetCustomResponseCode ¶ added in v0.4.0
SetCustomResponseCode will override the default expected response codes for the specified HTTP verb
func (*Client[T]) SetCustomResponseCodeMap ¶ added in v0.4.0
SetCustomResponseCodeMap sets the whole map for custom expected response codes
func (*Client[T]) SetHTTPClient ¶
SetHTTPClient allows overriding the Clients HTTP client with a custom one
func (*Client[T]) SetRequestEditor ¶
func (c *Client[T]) SetRequestEditor(requestEditor RequestEditor) *Client[T]
SetRequestEditor sets a request editor function that is used to modify all requests before sending. This is useful for adding custom request headers or authorization
type ContextKey ¶
type ContextKey string
ContextKey is used to store API resources in the request context
type DefaultRenderer ¶ added in v0.3.0
type DefaultRenderer struct{}
DefaultRenderer implements an empty Render method and can be used to easily create render.Renderer implementations without having to add the method
func (*DefaultRenderer) Render ¶ added in v0.3.0
func (*DefaultRenderer) Render(w http.ResponseWriter, r *http.Request) error
type DefaultResource ¶
type DefaultResource struct { *DefaultRenderer ID ID `json:"id"` }
DefaultResource implements Resource and uses the provided ID type. Extending this type is the easiest way to implement a Resource based around the provided ID type
func NewDefaultResource ¶
func NewDefaultResource() DefaultResource
NewDefaultResource creates a DefaultResource with a new random ID
func (*DefaultResource) GetID ¶
func (dr *DefaultResource) GetID() string
type EndDateable ¶ added in v0.13.0
EndDateable allows soft-delete by setting an end-date on resources instead of deleting them
type ErrResponse ¶
type ErrResponse struct { Err error `json:"-"` HTTPStatusCode int `json:"-"` StatusText string `json:"status"` // user-level status message AppCode int64 `json:"code,omitempty"` // application-specific error code ErrorText string `json:"error,omitempty"` // application-level error message, for debugging }
ErrResponse is an error that implements Renderer to be used in HTTP response
func ErrInvalidRequest ¶
func ErrInvalidRequest(err error) *ErrResponse
func ErrRender ¶
func ErrRender(err error) *ErrResponse
func GetFromRequest ¶ added in v0.15.0
func GetFromRequest[T RendererBinder](r *http.Request, instance func() T) (T, *ErrResponse)
GetFromRequest will read a resource type from the request body or request context
func InternalServerError ¶
func InternalServerError(err error) *ErrResponse
func (*ErrResponse) Error ¶
func (e *ErrResponse) Error() string
func (*ErrResponse) Render ¶
func (e *ErrResponse) Render(_ http.ResponseWriter, r *http.Request) error
type Extension ¶ added in v0.6.0
Extension is a way that a collection of modifiers, or other code, can be applied to an API all at once. This makes code more reusable and allows external libraries to provide modifiers
type FilterFunc ¶
FilterFunc is used for GetAll to filter resources that are read from storage
func (FilterFunc[T]) Filter ¶ added in v0.12.0
func (f FilterFunc[T]) Filter(in []T) []T
type HTMLer ¶ added in v0.2.0
type HTMLer interface {
HTML(http.ResponseWriter, *http.Request) string
}
HTMLer allows for easily represending reponses as HTML strings when accepted content type is text/html
type ID ¶
ID is a type that can be optionally used to improve Resources and their APIs. It uses xid to create unique identifiers and implements a custom Bind method to:
- Disallow POST requests with IDs
- Automatically set new ID on POSTed resources
- Enforce that ID is set
- Do not allow changing ID with PATCH
type KVStorage ¶ added in v0.13.0
type KVStorage[T Resource] struct { // contains filtered or unexported fields }
KVStorage implements the Storage interface for the provided type using hord.Database for the storage backend
It allows soft-deleting if your type implements the kv.EndDateable interface. This means Delete will set the end-date to now and update in storage instead of deleting. If something is already end-dated, then it is hard-deleted. Also, the GetAll method will automatically read the 'end_dated' query param to determine if end-dated resources should be filtered out
func (*KVStorage[T]) Delete ¶ added in v0.13.0
Delete will delete a resource by the key. If the resource implements EndDateable, it will first soft-delete by setting the EndDate to time.Now()
func (*KVStorage[T]) Get ¶ added in v0.13.0
Get will use the provided key to read data from the data source. Then, it will Unmarshal into the generic type
type NilResource ¶ added in v0.4.0
type NilResource struct{ *DefaultRenderer }
NilResource is an empty resource type which should be used when creating APIs without any real resource
func (*NilResource) GetID ¶ added in v0.4.0
func (*NilResource) GetID() string
type Patcher ¶
type Patcher[T Resource] interface { Patch(T) *ErrResponse }
Patcher is used to optionally-enable PATCH endpoint. Since the library cannot generically modify resources without using reflection, implement Patch function to use the input to modify the receiver
type PrintableResponse ¶ added in v0.5.0
PrintableResponse allows CLI method to generically return a type that can be written to out
type RelatedAPI ¶ added in v0.2.0
type RelatedAPI interface { Router() (chi.Router, error) Route(chi.Router) error Base() string Name() string GetIDParam(*http.Request) string Parent() RelatedAPI CreateClientMap(*Client[*AnyResource]) map[string]*Client[*AnyResource] }
RelatedAPI declares a subset of methods from the API struct that are required to enable nested/parent-child API relationships
type RendererBinder ¶ added in v0.15.0
type RendererBinder interface { // Renderer is used to control the output behavior when creating a response. // Use this for any after-request logic or response modifications render.Renderer // Binder is used to control the input behavior, after decoding the request. // Use it for input validation or additional modification of the resource using request headers or other params render.Binder }
RendererBinder just combines render.Renderer and render.Binder
type RequestEditor ¶
RequestEditor is a function that can modify the HTTP request before sending
var DefaultRequestEditor RequestEditor = func(r *http.Request) error { return nil }
type Resource ¶
type Resource interface { comparable RendererBinder GetID() string }
Resource is an interface/constraint used for API resources. In order to use API, you must have types that implement this. It enables HTTP request/response handling and getting resources by ID
type ResourceList ¶
ResourceList is used to automatically enable the GetAll endpoint that returns an array of Resources
func (*ResourceList[T]) Render ¶
func (rl *ResourceList[T]) Render(w http.ResponseWriter, r *http.Request) error
type Response ¶ added in v0.2.0
Response wraps an HTTP response from the API and allows easy access to the decoded response type (if JSON), the ContentType, string Body, and the original response
func MakeRequest ¶ added in v0.2.0
func MakeRequest[T any](req *http.Request, client *http.Client, expectedStatusCode int, requestEditor RequestEditor) (*Response[T], error)
MakeRequest generically sends an HTTP request after calling the request editor and checks the response code It returns a babyapi.Response which contains the http.Response after extracting the body to Body string and JSON decoding the resource type into Data if the response is JSON
type ServerSentEvent ¶ added in v0.2.0
ServerSentEvent is a simple struct that represents an event used in HTTP event stream
func (*ServerSentEvent) Write ¶ added in v0.2.0
func (sse *ServerSentEvent) Write(w http.ResponseWriter)
Write will write the ServerSentEvent to the HTTP response stream and flush. It removes all newlines in the event data
type Storage ¶
type Storage[T Resource] interface { // Get a single resource by ID Get(context.Context, string) (T, error) // GetAll will return all resources that match the provided query filters GetAll(context.Context, url.Values) ([]T, error) // Set will save the provided resource Set(context.Context, T) error // Delete will delete a resource by ID Delete(context.Context, string) error }
Storage defines how the API will interact with a storage backend