go-json-spec-handler: github.com/derekdowling/go-json-spec-handler/jsh-api Index | Files | Directories

package jshapi

import "github.com/derekdowling/go-json-spec-handler/jsh-api"

Package jshapi is a http.Handler compatible wrapper that makes building JSON API resource handlers easy.


Package Files

api.go jshapi.go mock_storage.go relationship.go resource.go sender.go utility.go


var SendHandler = DefaultSender(log.New(os.Stderr, "jshapi: ", log.LstdFlags))

SendHandler allows the customization of how API responses are sent and logged. This is used by all jshapi.Resource objects.

type API Uses

type API struct {

    Resources map[string]*Resource
    Debug     bool
    // contains filtered or unexported fields

API is used to direct HTTP requests to resources

func Default Uses

func Default(prefix string, debug bool, logger std.Logger) *API

Default builds a new top-level API with a few out of the box additions to get people started without needing to add a lot of extra functionality.

The most basic implementation is:

// create a logger, the std log package works, as do most other loggers
// std.Logger interface defined here:
// https://github.com/derekdowling/go-stdlogger/blob/master/logger.go
logger := log.New(os.Stderr, "jshapi: ", log.LstdFlags)

// create the API. Specify a http://yourapi/<prefix>/ if required
api := jshapi.Default("<prefix>", false, logger)

func New Uses

func New(prefix string) *API

New initializes a new top level API Resource without doing any additional setup.

func (*API) Add Uses

func (a *API) Add(resource *Resource)

Add implements mux support for a given resource which is effectively handled as: pat.New("/(prefix/)resource.Plu*)

func (*API) RouteTree Uses

func (a *API) RouteTree() string

RouteTree prints out all accepted routes for the API that use jshapi implemented ways of adding routes through resources: NewCRUDResource(), .Get(), .Post, .Delete(), .Patch(), .List(), and .NewAction()

type MockStorage Uses

type MockStorage struct {
    // ResourceType is the name of the resource you are mocking i.e. "user", "comment"
    ResourceType string
    // ResourceAttributes a sample set of attributes a resource object should have
    // used by GET /resources and GET /resources/:id
    ResourceAttributes interface{}
    // ListCount is the number of sample objects to return in a GET /resources request
    ListCount int

MockStorage allows you to mock out APIs really easily, and is also used internally for testing the API layer.

func (*MockStorage) Delete Uses

func (m *MockStorage) Delete(ctx context.Context, id string) jsh.ErrorType

Delete does nothing

func (*MockStorage) Get Uses

func (m *MockStorage) Get(ctx context.Context, id string) (*jsh.Object, jsh.ErrorType)

Get returns a resource with ID as specified by the request

func (*MockStorage) List Uses

func (m *MockStorage) List(ctx context.Context) (jsh.List, jsh.ErrorType)

List returns a sample list

func (*MockStorage) SampleList Uses

func (m *MockStorage) SampleList(length int) jsh.List

SampleList generates a sample list of resources that can be used for/against the mock API

func (*MockStorage) SampleObject Uses

func (m *MockStorage) SampleObject(id string) *jsh.Object

SampleObject builds an object based on provided resource specifications

func (*MockStorage) Save Uses

func (m *MockStorage) Save(ctx context.Context, object *jsh.Object) (*jsh.Object, jsh.ErrorType)

Save assigns a URL of 1 to the object

func (*MockStorage) Update Uses

func (m *MockStorage) Update(ctx context.Context, object *jsh.Object) (*jsh.Object, jsh.ErrorType)

Update does nothing

type Relationship Uses

type Relationship string

Relationship helps define the relationship between two resources

const (
    // ToOne signifies a one to one relationship
    ToOne Relationship = "One-To-One"
    // ToMany signifies a one to many relationship
    ToMany Relationship = "One-To-Many"

type Resource Uses

type Resource struct {
    // The singular name of the resource type("user", "post", etc)
    Type string
    // Routes is a list of routes registered to the resource
    Routes []string
    // Map of relationships
    Relationships map[string]Relationship

Resource holds the necessary state for creating a REST API endpoint for a given resource type. Will be accessible via `/<type>`.

Using NewCRUDResource you can generate a generic CRUD handler for a JSON Specification Resource end point. If you wish to only implement a subset of these endpoints that is also available through NewResource() and manually registering storage handlers via .Post(), .Get(), .List(), .Patch(), and .Delete():

Besides the built in registration helpers, it isn't recommended, but you can add your own routes using the goji.Mux API:

func searchHandler(w http.ResponseWriter, r *http.Request) {
	name := pat.Param("name")
	fmt.Fprintf(w, "Hello, %s!", name)

resource := jshapi.NewCRUDResource("users", userStorage)
// creates /users/search/:name
resource.HandleC(pat.New("search/:name"), searchHandler)

func NewCRUDResource Uses

func NewCRUDResource(resourceType string, storage store.CRUD) *Resource

NewCRUDResource generates a resource

func NewMockResource Uses

func NewMockResource(resourceType string, listCount int, sampleObject interface{}) *Resource

NewMockResource builds a mock API endpoint that can perform basic CRUD actions:

GET    /types
POST   /types
GET    /types/:id
DELETE /types/:id
PATCH  /types/:id

Will return objects and lists based upon the sampleObject that is specified here in the constructor.

func NewResource Uses

func NewResource(resourceType string) *Resource

NewResource is a resource constructor that makes no assumptions about routes that you'd like to implement, but still provides some basic utilities for managing routes and handling API calls.

The prefix parameter causes all routes created within the resource to be prefixed.

func (*Resource) Action Uses

func (res *Resource) Action(actionName string, storage store.Get)

Action allows you to add custom actions to your resource types, it uses the GET /(prefix/)resourceTypes/:id/<actionName> path format

func (*Resource) CRUD Uses

func (res *Resource) CRUD(storage store.CRUD)

CRUD is syntactic sugar and a shortcut for registering all JSON API CRUD routes for a compatible storage implementation:

Registers handlers for:

GET    /resource
POST   /resource
GET    /resource/:id
DELETE /resource/:id
PATCH  /resource/:id

func (*Resource) Delete Uses

func (res *Resource) Delete(storage store.Delete)

Delete registers a `DELETE /resource/:id` handler for the resource

func (*Resource) Get Uses

func (res *Resource) Get(storage store.Get)

Get registers a `GET /resource/:id` handler for the resource

func (*Resource) List Uses

func (res *Resource) List(storage store.List)

List registers a `GET /resource` handler for the resource

func (*Resource) Patch Uses

func (res *Resource) Patch(storage store.Update)

Patch registers a `PATCH /resource/:id` handler for the resource

func (*Resource) Post Uses

func (res *Resource) Post(storage store.Save)

Post registers a `POST /resource` handler with the resource

func (*Resource) RouteTree Uses

func (res *Resource) RouteTree() string

RouteTree prints a recursive route tree based on what the resource, and all subresources have registered

func (*Resource) ToMany Uses

func (res *Resource) ToMany(
    resourceType string,
    storage store.ToMany,

ToMany registers a `GET /resource/:id/(relationships/)<resourceType>s` route which returns a list of "resourceType"s in a One-To-Many relationship with the parent resource. The "/relationships/" uri component is optional.

CRUD actions on a specific relationship "resourceType" object should be performed via it's own top level /<resourceType> jsh-api handler as per JSONAPI specification.

func (*Resource) ToOne Uses

func (res *Resource) ToOne(
    resourceType string,
    storage store.Get,

ToOne registers a `GET /resource/:id/(relationships/)<resourceType>` route which returns a "resourceType" in a One-To-One relationship between the parent resource type and "resourceType" as specified here. The "/relationships/" uri component is optional.

CRUD actions on a specific relationship "resourceType" object should be performed via it's own top level /<resourceType> jsh-api handler as per JSONAPI specification.

type Sender Uses

type Sender func(http.ResponseWriter, *http.Request, jsh.Sendable)

Sender is a function type definition that allows consumers to customize how they send and log API responses.

func DefaultSender Uses

func DefaultSender(logger std.Logger) Sender

DefaultSender is the default sender that will log 5XX errors that it encounters in the process of sending a response.


storePackage store is a collection of composable interfaces that are can be implemented in order to build a storage driver

Package jshapi imports 15 packages (graph). Updated 2017-07-12. Refresh now. Tools for package owners. This is an inactive package (no imports and no commits in at least two years).