jape

package module
v0.12.1 Latest Latest
Warning

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

Go to latest
Published: Sep 1, 2024 License: MIT Imports: 21 Imported by: 28

README

jape

GoDoc

jape is a "micro-framework" for building JSON-based HTTP APIs. It includes:

  • A generic client type that speaks JSON
  • A Context type for handlers, with convenient methods for JSON and error handling
  • A static analyzer that ensures parity between client and server definitions

Usage

import (
    "net/http"
    "go.sia.tech/jape"
)

func helloHandler(jc jape.Context) {
    var greeting string
    if jc.Decode(&greeting) == nil {
        jc.Encode(greeting + ", " + jc.PathParam("name"))
    }
}

func NewServer() http.Handler {
    return jape.Mux(map[string]jape.Handler{
        "POST /hello/:name": helloHandler,
    })
}

type Client struct {
    c jape.Client
}

func (c Client) Hello(name, greeting string) (resp int, err error) {
    err = c.c.POST("/hello/"+name, greeting, &resp)
    return
}

Did you notice the error in the example code? If we run japecheck, it reports:

example.go:24:43 Client has wrong response type for POST /hello/:name (got int, should be string)

To install japecheck, run go install go.sia.tech/jape/japecheck. You can then run it as a pre-commit hook like so:

echo -e "#!/usr/bin/env bash\njapecheck ./api" > .git/hooks/pre-commit
chmod +x .git/hooks/pre-commit

Use with Github Actions

To use with action-golang-analysis, create .github/workflows/analyzer.yml in your repository with the following contents:

name: Analyzer
on:
  pull_request:
    branches: [ master ]
  push:
    branches: [ master ]

jobs:
  analyzer:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-go@v3
      - uses: SiaFoundation/action-golang-analysis@HEAD
        with:
          analyzers: |
            go.sia.tech/jape.Analyzer

It can also be added as a job within your existing workflow, like in renterd.

Documentation

Index

Constants

View Source
const Doc = `` /* 160-byte string literal not displayed */

Variables

View Source
var Analyzer = &analysis.Analyzer{
	Name:             "japecheck",
	Doc:              Doc,
	Run:              run,
	RunDespiteErrors: true,
	Requires: []*analysis.Analyzer{
		inspect.Analyzer,
		ctrlflow.Analyzer,
	},
}

Functions

func Adapt added in v0.5.0

func Adapt(mid func(http.Handler) http.Handler) func(Handler) Handler

Adapt turns a http.Handler transformer into a Handler transformer, allowing standard middleware to be applied to individual jape endpoints.

func BasicAuth added in v0.5.0

func BasicAuth(password string) func(http.Handler) http.Handler

BasicAuth returns a http.Handler transformer that enforces HTTP Basic Authentication.

func Mux

func Mux(routes map[string]Handler) *httprouter.Router

Mux returns an http.Handler for the provided set of routes. The map keys must contain both the method and path of the route, separated by whitespace, e.g. "GET /foo/:bar".

Types

type Client

type Client struct {
	BaseURL  string
	Password string
	// contains filtered or unexported fields
}

A Client provides methods for interacting with an API server.

func (*Client) Custom added in v0.4.0

func (c *Client) Custom(method, route string, d, r interface{})

Custom is a no-op that simply declares the request and response types used by a client method. This allows japecheck to be used on endpoints that do not speak JSON.

func (*Client) DELETE

func (c *Client) DELETE(route string) error

DELETE performs a DELETE request.

func (*Client) GET

func (c *Client) GET(route string, r interface{}) error

GET performs a GET request, decoding the response into r.

func (*Client) PATCH added in v0.10.0

func (c *Client) PATCH(route string, d, r interface{}) error

PATCH performs a PATCH request. If d is non-nil, it is encoded as the request body. If r is non-nil, the response is decoded into it.

func (*Client) POST

func (c *Client) POST(route string, d, r interface{}) error

POST performs a POST request. If d is non-nil, it is encoded as the request body. If r is non-nil, the response is decoded into it.

func (*Client) PUT

func (c *Client) PUT(route string, d interface{}) error

PUT performs a PUT request, encoding d as the request body.

func (*Client) WithContext added in v0.6.0

func (c *Client) WithContext(ctx context.Context) *Client

WithContext returns a copy of the client that uses the provided context for all requests.

type Context

type Context struct {
	ResponseWriter http.ResponseWriter
	Request        *http.Request
	PathParams     httprouter.Params
}

A Context contains the values relevant to an HTTP handler.

func (Context) Check

func (c Context) Check(msg string, err error) error

Check conditionally writes an error. If err is non-nil, Check prefixes it with msg, writes it to the response body (with status code 500), and returns it. Otherwise it returns nil.

func (Context) Custom added in v0.4.0

func (c Context) Custom(req, resp interface{})

Custom is a no-op that simply declares the request and response types used by a handler. This allows japecheck to be used on endpoints that do not speak JSON.

func (Context) Decode

func (c Context) Decode(v interface{}) error

Decode decodes the JSON of the request body into v. If decoding fails, Decode writes an error to the response body and returns it.

func (Context) DecodeForm added in v0.3.0

func (c Context) DecodeForm(key string, v interface{}) error

DecodeForm decodes the form value with the specified key into v, which must implement one of the following methods:

UnmarshalText([]byte) error
LoadString(string) error

The following basic types are also supported:

*int
*bool
*string

If decoding fails, DecodeForm writes an error to the response body and returns it. If the form value is empty, no error is returned and v is unchanged.

func (Context) DecodeParam

func (c Context) DecodeParam(param string, v interface{}) error

DecodeParam decodes the specified path parameter into v, which must implement one of the following methods:

UnmarshalText([]byte) error
LoadString(string) error

The following basic types are also supported:

*int
*bool
*string

If decoding fails, DecodeParam writes an error to the response body and returns it.

func (Context) EmptyResonse added in v0.12.1

func (c Context) EmptyResonse()

EmptyResonse writes a 204 No Content response. This should be used when the client should not expect a response body.

func (Context) Encode

func (c Context) Encode(v interface{})

Encode writes the JSON encoding of v to the response body.

func (Context) Error added in v0.3.0

func (c Context) Error(err error, status int) error

Error writes err to the response body and returns it.

func (Context) PathParam

func (c Context) PathParam(param string) string

PathParam returns the value of a path parameter. If the parameter is undefined, it returns the empty string.

type Handler

type Handler func(Context)

A Handler handles HTTP requests.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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