hal

package module
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: Jun 21, 2018 License: MIT Imports: 3 Imported by: 19

README

Hal

Build Status Coverage Status GoDoc

Go implementation of the HAL standard.

This is a work in progress... Everything might/will change.

Usage

The library gives a way of mapping Go Structs into HAL Resources by implementing the hal.Mapper interface. You only need to define which fields you want and how you want them translated.

type Mapper interface {
	GetMap() Entry
}

For a given Product struct, this would be the hal.Mapper implementation:

type Product struct {
	Code int
	Name string
	Price int
}

func (p Product) GetMap() hal.Entry {
	return hal.Entry{
		"name":  p.Name,
		"price": p.Price,
	}
}

Then you can just create a HAL Resource for a Product by:

p := Product{
	Code: 1,
	Name: "Some Product",
	Price: 10
}

pr := hal.NewResource(p, "http://rest.api/products/1")

And pass it through json.Marsal when needed getting this result:

{
	"_links": {
		"self": {"href": "http://rest.api/products/1"}
	},
	"name": "Some product",
	"price": 10
}

Embedded Resources

Let's say your API has to serve a list of Task structs.

Since for HAL standard everything is a resource, even the entire API response could be seen as a resource containing other embedded resources. Check this out:

type (
	Response struct {
		Count int
		Total int
	}

	Task struct {
		Id   int
		Name string
	}
)

func (p Response) GetMap() hal.Entry {
	return hal.Entry{
		"count": p.Count,
		"total": p.Total,
	}
}

func (c Task) GetMap() hal.Entry {
	return hal.Entry{
		"id":   c.Id,
		"name": c.Name,
	}
}

Then you could create the Resources by doing something like this:

// Creating Response resource
r := hal.NewResource(Response{Count: 10, Total: 20}, "/tasks")
r.AddNewLink("next", "/tasks=page=2")

// Creating Task resources
t1 := hal.NewResource(Task{Id: 1, Name: "Some Task"}, "/tasks/1")
t2 := hal.NewResource(Task{Id: 2, Name: "Some Task"}, "/tasks/2")

// Embedding
r.Embed("tasks", t1)
r.Embed("tasks", t2)

Output:

{
  "_embedded": {
    "tasks": [
      {
        "_links": {
          "self": {
            "href": "/tasks/1"
          }
        },
        "id": 1,
        "name": "Some Task"
      },
      {
        "_links": {
          "self": {
            "href": "/tasks/2"
          }
        },
        "id": 2,
        "name": "Some Task"
      }
    ]
  },
  "_links": {
    "next": {
      "href": "/tasks=page=2"
    },
    "self": {
      "href": "/tasks"
    }
  },
  "count": 10,
  "total": 20
}

CURIES

To include CURIE relations in your output you can 'register' the curie name and fluently add a link relation as follows:

p := Product{
	Code: 1,
	Name: "Some Product",
	Price: 10
}

// Creating Product resource
pr := hal.NewResource(p, "http://rest.api/products/1")
pr.RegisterCurie("acme", "http://acme.com/docs/{rel}", true).AddNewLink("widgets", "http://rest.api/products/1/widgets")

Output

{
	"_links": {
		"self": {"href": "http://rest.api/products/1"},
		"curies": [{ 
		        "name":"acme",
		        "href":"http://acme.com/docs/{rel}",
		        "templated":true
		    }],
		"acme:widgets": { "href": "http://rest.api/products/1/widgets" }
	},
	"name": "Some product",
	"price": 10
}

Registered curies can also be retreived by name from the resources' Curies map:

pr := hal.NewResource(p, "http://rest.api/products/1")
pr.RegisterCurie("acme", "http://acme.com/docs/{rel}", true)
...

curie := pr.Curies["acme"]
curie.AddNewLink("widgets", "http://rest.api/products/1/widgets")

Todo

  • XML Marshaler.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type CurieHandle added in v0.3.0

type CurieHandle struct {
	Name string
	*Resource
}
func (c CurieHandle) AddNewLink(rel Relation, href string)

AddNewLink adds a link to the resources_link collection prepended with the curie Name

type Embedded

type Embedded map[Relation]interface{}

func (Embedded) Add

func (e Embedded) Add(rel Relation, r *Resource)

Add appends the resource into the list of embedded resources with the specified relation. r should be a Resource

func (Embedded) AddCollection

func (e Embedded) AddCollection(rel Relation, r ResourceCollection)

AddCollection appends the resource into the list of embedded resources with the specified relation. r should be a ResourceCollection

func (Embedded) Del

func (e Embedded) Del(rel Relation)

Del deletes the resources associated with the given relation.

func (Embedded) Set

func (e Embedded) Set(rel Relation, r *Resource)

Set sets the resource into the list of embedded resources with the specified relation. It replaces any existing resources associated with the relation. r should be a pointer to a Resource

func (Embedded) SetCollection

func (e Embedded) SetCollection(rel Relation, r ResourceCollection)

Set sets the resource into the list of embedded resources with the specified relation. It replaces any existing resources associated with the relation. r should be a ResourceCollection

type Entry

type Entry map[string]interface{}
type Link LinkAttr
func NewLink(href string, attrs ...LinkAttr) Link

NewLink returns a new Link object.

type LinkAttr

type LinkAttr map[string]interface{}

Link types that store hyperlinks and its attributes.

type LinkCollection

type LinkCollection []Link

type LinkRelations

type LinkRelations map[Relation]interface{}

type Mapper

type Mapper interface {
	GetMap() Entry
}

Mapper is the interface implemented by the objects that can be converted into HAL format.

type Relation

type Relation string

type Resource

type Resource struct {
	Payload  interface{}
	Links    LinkRelations
	Embedded Embedded
	Curies   map[string]*CurieHandle
}

Resource is a struct that stores a resource data. It represents a converted object in the HAL spec by containing all its fields and also a set of related links and a sub-set of recursively related resources.

func NewResource

func NewResource(p interface{}, selfUri string) *Resource

NewResource creates a Resource object for a given struct and its link.

func (r *Resource) AddLink(rel Relation, l Link)

AddLink appends a Link to the resource. l should be a Link

func (*Resource) AddLinkCollection

func (r *Resource) AddLinkCollection(rel Relation, l LinkCollection)

AddLinkCollection appends a LinkCollection to the resource. l should be a LinkCollection

func (r *Resource) AddNewLink(rel Relation, href string)

AddNewLink appends a new Link object based on the rel and href params.

func (*Resource) Embed

func (r *Resource) Embed(rel Relation, re *Resource)

Embed appends a Resource to the array of embedded resources. re should be a pointer to a Resource

func (*Resource) EmbedCollection

func (r *Resource) EmbedCollection(rel Relation, re ResourceCollection)

EmbedCollection appends a ResourceCollection to the array of embedded resources. re should be a ResourceCollection

func (Resource) GetMap

func (r Resource) GetMap() Entry

Map implements the interface Mapper.

func (Resource) MarshalJSON

func (r Resource) MarshalJSON() ([]byte, error)

MarshalJSON is a Marshaler interface implementation for Resource struct

func (*Resource) RegisterCurie added in v0.3.0

func (r *Resource) RegisterCurie(name, href string, templated bool) *CurieHandle

RegisterCurie adds a Link relation of type 'curies' and returns a CurieHandle to allow users to fluently add new links that have this curie relation definition

type ResourceCollection

type ResourceCollection []*Resource

Directories

Path Synopsis
examples

Jump to

Keyboard shortcuts

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