gohateoas

package module
v1.1.0 Latest Latest
Warning

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

Go to latest
Published: May 7, 2024 License: MIT Imports: 8 Imported by: 0

README

🦁 Golang Hateoas

Go package GitHub GitHub go.mod Go version

Hateoas isn't always necessary for a REST API to function, but it's definitely a nice-to-have. This library provides a simple way to add hateoas links to your API responses, regardless of the wrapper object you use.

⬇️ Installation

go get github.com/ing-bank/gohateoas

📋 Usage

package main

import (
	"fmt"
	"github.com/ing-bank/gohateoas"
	"encoding/json"
)

// APIResponse is a simple struct that will be used as a wrapper for our response.
type APIResponse struct {
	Data any `json:"data"`
}

// MarshalJSON overrides the usual json.Marshal behaviour to allow us to add links to the response
func (a APIResponse) MarshalJSON() ([]byte, error) {
	return json.Marshal(struct {
		Data json.RawMessage `json:"data"`
	}{
		Data: gohateoas.InjectLinks(gohateoas.DefaultLinkRegistry, a.Data),
	})
}

type Cupcake struct{}

func main() {
	gohateoas.Register(Cupcake{}, gohateoas.Self("/api/v1/cupcakes/{id}", "Get this cupcake"),
		gohateoas.Post("/api/v1/cupcakes", "Create a cupcake"),
		gohateoas.Patch("/api/v1/cupcakes/{id}", "Partially update a cupcake"),
		gohateoas.Delete("/api/v1/cupcakes?id={id}", "Delete this cupcake"))

	response := APIResponse{Data: Cupcake{}}

	jsonBytes, _ := json.Marshal(response)

	fmt.Println(string(jsonBytes))
}

🚀 Development

  1. Clone the repository
  2. Run make t to run unit tests
  3. Run make fmt to format code

You can run make to see a list of useful commands.

🔭 Future Plans

  • Add support for custom link-property name

Documentation

Index

Examples

Constants

This section is empty.

Variables

View Source
var DefaultLinkRegistry = NewLinkRegistry()

DefaultLinkRegistry is the global registry for hateoas links

Functions

func InjectLinks(registry LinkRegistry, object any) []byte

InjectLinks is similar to json.Marshal, but it will inject links into the response if the registry has any links for the given type. It does this recursively.

func Register

func Register(object any, options ...LinkOption)

Register registers links to an object using the DefaultLinkRegistry.

Example
type Cupcake struct{}

Register(Cupcake{}, Self("/api/v1/cupcakes/{id}", "get a cupcake"),
	Post("/api/v1/cupcakes", "create a cupcake"),
	Put("/api/v1/cupcakes/{id}", "fully update a cupcake"),
	Patch("/api/v1/cupcakes/{id}", "partially update a cupcake"),
	Delete("/api/v1/cupcakes?id={id}", "delete this cupcake"))
Output:

func RegisterOn

func RegisterOn(linkRegistry LinkRegistry, object any, options ...LinkOption)

RegisterOn registers links to an object in the given registry.

Types

type LinkInfo

type LinkInfo struct {
	Method  string `json:"method"`
	Href    string `json:"href"`
	Comment string `json:"comment"`
	// Templated marks the link as a template, so the client can identify a link
	// as a template and they don't try to call the endpoint as it is presented.
	//
	// This field is defined in the draft RFC in section 5.2:
	// https://datatracker.ietf.org/doc/html/draft-kelly-json-hal#section-5.2
	Templated bool `json:"templated,omitempty"`
}

LinkInfo represents a link to a resource.

type LinkOption

type LinkOption func(map[string]LinkInfo)

LinkOption is used to register links in a LinkRegistry. Urls may contain replaceable tokens like {id} or {name}. These tokens will be replaced by the values of the corresponding json fields in the struct.

func Custom

func Custom(action string, info LinkInfo) LinkOption

Custom allows you to define a custom action and info. Urls may contain replaceable tokens like {id} or {name}. These tokens will be replaced by the values of the corresponding json fields in the struct.

func Delete

func Delete(url string, comment string) LinkOption

Delete Adds a general Delete route to the LinkRegistry. Urls may contain replaceable tokens like {id} or {name}. These tokens will be replaced by the values of the corresponding json fields in the struct.

func Index

func Index(href string, comment string) LinkOption

Index Adds a general Index route to the type. Urls may contain replaceable tokens like {id} or {name}. These tokens will be replaced by the values of the corresponding json fields in the struct.

func Patch

func Patch(url string, comment string) LinkOption

Patch Adds a general Patch route to the LinkRegistry. Urls may contain replaceable tokens like {id} or {name}. These tokens will be replaced by the values of the corresponding json fields in the struct.

func Post

func Post(href string, comment string) LinkOption

Post Adds a general POST route to the LinkRegistry. Urls may contain replaceable tokens like {id} or {name}. These tokens will be replaced by the values of the corresponding json fields in the struct.

func Put

func Put(href string, comment string) LinkOption

Put Adds a general Put route to the LinkRegistry. Urls may contain replaceable tokens like {id} or {name}. These tokens will be replaced by the values of the corresponding json fields in the struct.

func Self

func Self(href string, comment string) LinkOption

Self Adds the self url of an object to the type, probably an url with an id. Urls may contain replaceable tokens like {id} or {name}. These tokens will be replaced by the values of the corresponding json fields in the struct.

type LinkRegistry

type LinkRegistry map[string]map[string]LinkInfo

LinkRegistry allows you to register URLs on objects, populating links in responses.

func NewLinkRegistry

func NewLinkRegistry() LinkRegistry

NewLinkRegistry instantiates a new LinkRegistry, only used for testing or when overriding the DefaultLinkRegistry.

Jump to

Keyboard shortcuts

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