jsonapi

package module
v0.21.0 Latest Latest
Warning

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

Go to latest
Published: Oct 8, 2022 License: GPL-3.0 Imports: 11 Imported by: 4

README

jsonapi

jsonapi offers a set of tools to build JSON:API compliant services.

The official JSON:API specification can be found at jsonapi.org/format.

Features

jsonapi offers the following features:

  • Marshaling and unmarshaling of JSON:API URLs and documents
  • Structs for handling URLs, documents, resources, collections...
  • Schema management
    • It can ensure relationships between types make sense.
    • Very useful for validation when marshaling and unmarshaling.
  • Utilities for pagination, sorting, and filtering
    • jsonapi is opiniated when it comes to those features. If you prefer you own strategy fo pagination, sorting, and filtering, it will have to be done manually.
  • In-memory data store (SoftCollection)
    • It can store resources (anything that implements Resource).
    • It can sort, filter, retrieve pages, etc.
    • Enough to build a demo API or use in test suites.
    • Not made for production use.
  • Other useful helpers

State

The library is in beta and its API is subject to change until v1 is released.

In terms of features, jsonapi is complete. The work left is polishing and testing the design of current API.

Roadmap to v1

While anything can happen before a v1 release, the API is stable and no big changes are expected at this moment.

A few tasks are required before committing to the current API:

  • Rethink how errors are handled
    • Use the new tools introduced in Go 1.13.
  • Simplify the API
    • Remove anything that is redundant or not useful.
  • Gather feedback from users
    • The library should be used more on real projects to see of the API is convenient.

Requirements

The supported versions of Go are the latest patch releases of every minor release starting with Go 1.13.

Examples

The best way to learn and appreciate this package is to look at the simple examples provided in the examples/ directory.

Quick start

The simplest way to start using jsonapi is to use the MarshalDocument and UnmarshalDocument functions.

func MarshalDocument(doc *Document, url *URL) ([]byte, error)
func UnmarshalDocument(payload []byte, schema *Schema) (*Document, error)

A struct has to follow certain rules in order to be understood by the library, but interfaces are also provided which let the library avoid the reflect package and be more efficient.

See the following section for more information about how to define structs for this library.

Concepts

Here are some of the main concepts covered by the library.

Request

A Request represents an HTTP request structured in a format easily readable from a JSON:API point of view.

If you are familiar with the specification, reading the Request struct and its fields (URL, Document, etc) should be straightforward.

Schema

A Schema contains all the schema information for an API, like types, fields, relationships between types, and so on. See schema.go and type.go for more details.

This is really useful for many uses cases:

  • Making sure the schema is coherent
  • Validating resources
  • Parsing documents and URLs
  • And probably many more...

For example, when a request comes in, a Document and a URL can be created by parsing the request. By providing a schema, the parsing can fail if it finds some errors like a type that does not exist, a field of the wrong kind, etc. After that step, valid data can be assumed.

Type

A JSON:API type is generally defined with a struct.

There needs to be an ID field of type string. The api tag represents the name of the type.

type User struct {
  ID string `json:"id" api:"users"` // ID is mandatory and the api tag sets the type

  // Attributes
  Name string `json:"name" api:"attr"` // attr means it is an attribute
  BornAt time.Time `json:"born-at" api:"attr"`

  // Relationships
  Articles []string `json:"articles" api:"rel,articles"`
}

Other fields with the api tag (attr or rel) can be added as attributes or relationships.

Attribute

Attributes can be of the following types:

string
int, int8, int16, int32, int64
uint, uint8, uint16, uint32, uint64
bool
time.Time
[]byte
*string
*int, *int8, *int16, *int32, *int64
*uint, *uint8, *uint16, *uint32, *uint64
*bool
*time.Time
*[]byte

Using a pointer allows the field to be nil.

Relationship

Relationships can be a bit tricky. To-one relationships are defined with a string and to-many relationships are defined with a slice of strings. They contain the IDs of the related resources. The api tag has to take the form of "rel,xxx[,yyy]" where yyy is optional. xxx is the type of the relationship and yyy is the name of the inverse relationship when dealing with a two-way relationship. In the following example, our Article struct defines a relationship named author of type users:

Author string `json:"author" api:"rel,users,articles"`
Wrapper

A struct can be wrapped using the Wrap function which returns a pointer to a Wrapper. A Wrapper implements the Resource interface and can be used with this library. Modifying a Wrapper will modify the underlying struct. The resource's type is defined from reflecting on the struct.

user := User{}
wrap := Wrap(&user)
wrap.Set("name", "Mike")
fmt.Printf(wrap.Get("name")) // Output: Mike
fmt.Printf(user.Name) // Output: Mike
SoftResource

A SoftResource is a struct whose type (name, attributes, and relationships) can be modified indefinitely just like its values. When an attribute or a relationship is added, the new value is the zero value of the field type. For example, if you add an attribute named my-attribute of type string, then softresource.Get("my-attribute") will return an empty string.

sr := SoftResource{}
sr.AddAttr(Attr{
  Name:     "attr",
  Type:     AttrTypeInt,
  Nullable: false,
})
fmt.Println(sr.Get("attr")) // Output: 0

Take a look at the SoftCollection struct for a similar concept applied to an entire collection of resources.

URLs

From a raw string that represents a URL, it is possible that create a SimpleURL which contains the information stored in the URL in a structure that is easier to handle.

It is also possible to build a URL from a Schema and a SimpleURL which contains additional information taken from the schema. NewURL returns an error if the URL does not respect the schema.

Documentation

Check out the documentation.

The best way to learn how to use it is to look at documentation, the examples, and the code itself.

Documentation

Overview

Package jsonapi offers a library to marshal and unmarshal JSON:API payloads.

It also offers many utilies for developing a JSON:API backend.

The simplest way to start using jsonapi is to use the Marshal and Unmarshal functions.

func Marshal(doc *Document, url *URL) ([]byte, error)
func Unmarshal(payload []byte, url *URL, schema *Schema) (*Document, error)

A schema is collection of types where relationships can point to each other. A schema can also look at its types and return any errors.

A type is generally defined with a struct.

There needs to be an ID field of type string. The `api` tag represents the name of the type.

type User struct {
	ID string `json:"id" api:"users"` // ID is mandatory and the api tag sets the type

	// Attributes
	Name string `json:"name" api:"attr"` // attr means it is an attribute
	BornAt time.Time `json:"born-at" api:"attr"`

	// Relationships
	Articles []string `json:"articles" api:"rel,articles"`
}

A lot more is offered in this library. The best way to learn how to use it is to look at the source code and its comments.

Index

Constants

View Source
const (
	AttrTypeInvalid = iota
	AttrTypeString
	AttrTypeInt
	AttrTypeInt8
	AttrTypeInt16
	AttrTypeInt32
	AttrTypeInt64
	AttrTypeUint
	AttrTypeUint8
	AttrTypeUint16
	AttrTypeUint32
	AttrTypeUint64
	AttrTypeBool
	AttrTypeTime
	AttrTypeBytes
)

Attribute types are the possible types for attributes.

Those constants are numbers that represent the types. Each type has a string representation which should be used instead of the numbers when storing that information. The numbers can change between any version of this library, even if it potentially can break existing code.

The names are as follow:

  • string
  • int, int8, int16, int32, int64
  • uint, uint8, uint16, uint32, uint64
  • bool
  • time (Go type is time.Time)
  • bytes (Go type is []uint8 or []byte)

An asterisk is present as a prefix when the type is nullable (like *string).

Developers are encouraged to use the constants, the Type struct, and other tools to handle attribute types instead of dealing with strings.

Variables

This section is empty.

Functions

func Check added in v0.13.0

func Check(v interface{}) error

Check checks that the given value can be used with this library and returns the first error it finds.

It makes sure that the struct has an ID field of type string and that the api key of the field tags are properly formatted.

If nil is returned, then the value can be safely used with this library.

func Equal added in v0.7.0

func Equal(r1, r2 Resource) bool

Equal reports whether r1 and r2 are equal.

Two resources are equal if their types are equal, all the attributes are equal (same type and same value), and all the relationstips are equal.

IDs are ignored.

func EqualStrict added in v0.10.0

func EqualStrict(r1, r2 Resource) bool

EqualStrict is like Equal, but it also considers IDs.

func GetAttrType added in v0.7.0

func GetAttrType(t string) (int, bool)

GetAttrType returns the attribute type as an int (see constants) and a boolean that indicates whether the attribute can be null or not.

func GetAttrTypeString added in v0.7.0

func GetAttrTypeString(t int, nullable bool) string

GetAttrTypeString returns the name of the attribute type specified by t (see constants) and nullable.

func GetZeroValue added in v0.7.0

func GetZeroValue(t int, nullable bool) interface{}

GetZeroValue returns the zero value of the attribute type represented by the specified int (see constants).

If nullable is true, the returned value is a nil pointer.

func IDAndType

func IDAndType(v interface{}) (string, string)

IDAndType returns the ID and the type of the resource represented by v.

Two empty strings are returned if v is not recognized as a resource. CheckType can be used to check the validity of a struct.

func MarshalCollection added in v0.16.0

func MarshalCollection(c Collection, prepath string, fields map[string][]string, relData map[string][]string) []byte

MarshalCollection marshals a Collection into a JSON-encoded payload.

func MarshalDocument added in v0.16.0

func MarshalDocument(doc *Document, url *URL) ([]byte, error)

MarshalDocument marshals a document according to the JSON:API speficication.

Both doc and url must not be nil.

func MarshalResource added in v0.16.0

func MarshalResource(r Resource, prepath string, fields []string, relData map[string][]string) []byte

MarshalResource marshals a Resource into a JSON-encoded payload.

Types

type Attr

type Attr struct {
	Name     string
	Type     int
	Nullable bool
}

Attr represents a resource attribute.

func (Attr) UnmarshalToType added in v0.14.0

func (a Attr) UnmarshalToType(data []byte) (interface{}, error)

UnmarshalToType unmarshals the data into a value of the type represented by the attribute and returns it.

type BelongsToFilter

type BelongsToFilter struct {
	Type   string
	ID     string
	Name   string
	ToName string
}

A BelongsToFilter represents a parent resource, used to filter out resources that are not children of the parent.

For example, in /articles/abc123/comments, the parent is the article with the ID abc123.

type Collection

type Collection interface {
	// GetType returns the type of the resources.
	GetType() Type

	// Len returns the number of resources in the collection.
	Len() int

	// At returns the resource at index i.
	At(int) Resource

	// Add adds a resource in the collection.
	Add(Resource)
}

A Collection defines the interface of a structure that can manage a set of ordered resources of the same type.

func Range added in v0.14.0

func Range(c Collection, ids []string, filter *Filter, sort []string, size uint, num uint) Collection

Range returns a subset of the collection arranged according to the given parameters.

From collection c, only IDs from ids are considered. filter is applied if not nil. The resources are sorted in the order defined by sort, which may contain the names of some or all of the attributes. The result is split in pages of a certain size (defined by size). The page at index num is returned.

A non-nil Collection is always returned, but it can be empty.

func UnmarshalCollection added in v0.16.0

func UnmarshalCollection(data []byte, schema *Schema) (Collection, error)

UnmarshalCollection unmarshals a JSON-encoded payload into a Collection.

type Copier added in v0.20.0

type Copier interface {
	New() Resource
	Copy() Resource
}

Copier is a interface for objects that can return a new and empty instance or a deep copy of themselves.

type Document

type Document struct {
	// Data
	Data interface{}

	// Included
	Included []Resource

	// References
	Resources map[string]map[string]struct{}
	Links     map[string]Link

	// Relationships where data has to be included in payload
	RelData map[string][]string

	// Top-level members
	Meta Meta

	// Errors
	Errors []Error

	// Internal
	PrePath string
}

A Document represents a JSON:API document.

func UnmarshalDocument added in v0.16.0

func UnmarshalDocument(payload []byte, schema *Schema) (*Document, error)

UnmarshalDocument reads a payload to build and return a Document object.

schema must not be nil.

func (*Document) Include

func (d *Document) Include(res Resource)

Include adds res to the set of resources to be included under the included top-level field.

It also makes sure that resources are not added twice.

type Error

type Error struct {
	ID     string                 `json:"id"`
	Code   string                 `json:"code"`
	Status string                 `json:"status"`
	Title  string                 `json:"title"`
	Detail string                 `json:"detail"`
	Links  map[string]string      `json:"links"`
	Source map[string]interface{} `json:"source"`
	Meta   Meta                   `json:"meta"`
}

An Error represents an error object from the JSON:API specification.

func NewErrBadRequest

func NewErrBadRequest(title, detail string) Error

NewErrBadRequest (400) returns the corresponding error.

func NewErrDuplicateFieldInFieldsParameter added in v0.13.0

func NewErrDuplicateFieldInFieldsParameter(typ string, field string) Error

NewErrDuplicateFieldInFieldsParameter (400) returns the corresponding error.

func NewErrForbidden

func NewErrForbidden() Error

NewErrForbidden (403) returns the corresponding error.

func NewErrInternalServerError

func NewErrInternalServerError() Error

NewErrInternalServerError (500) returns the corresponding error.

func NewErrInvalidFieldValueInBody added in v0.14.0

func NewErrInvalidFieldValueInBody(field string, badValue string, typ string) Error

NewErrInvalidFieldValueInBody (400) returns the corresponding error.

func NewErrInvalidPageNumberParameter

func NewErrInvalidPageNumberParameter(badPageNumber string) Error

NewErrInvalidPageNumberParameter (400) returns the corresponding error.

func NewErrInvalidPageSizeParameter

func NewErrInvalidPageSizeParameter(badPageSize string) Error

NewErrInvalidPageSizeParameter (400) returns the corresponding error.

func NewErrInvalidValueInFilterParameter

func NewErrInvalidValueInFilterParameter(val, kind string) Error

NewErrInvalidValueInFilterParameter (400) returns the corresponding error.

func NewErrMalformedFilterParameter

func NewErrMalformedFilterParameter(badFitler string) Error

NewErrMalformedFilterParameter (400) returns the corresponding error.

func NewErrMissingDataMember added in v0.14.0

func NewErrMissingDataMember() Error

NewErrMissingDataMember (400) returns the corresponding error.

func NewErrNotFound

func NewErrNotFound() Error

NewErrNotFound (404) returns the corresponding error.

func NewErrNotImplemented

func NewErrNotImplemented() Error

NewErrNotImplemented (503) returns the corresponding error.

func NewErrPayloadTooLarge

func NewErrPayloadTooLarge() Error

NewErrPayloadTooLarge (413) returns the corresponding error.

func NewErrRequestHeaderFieldsTooLarge

func NewErrRequestHeaderFieldsTooLarge() Error

NewErrRequestHeaderFieldsTooLarge (431) returns the corresponding error.

func NewErrRequestURITooLong

func NewErrRequestURITooLong() Error

NewErrRequestURITooLong (414) returns the corresponding error.

func NewErrServiceUnavailable

func NewErrServiceUnavailable() Error

NewErrServiceUnavailable (503) returns the corresponding error.

func NewErrTooManyRequests

func NewErrTooManyRequests() Error

NewErrTooManyRequests (429) returns the corresponding error.

func NewErrUnauthorized

func NewErrUnauthorized() Error

NewErrUnauthorized (401) returns the corresponding error.

func NewErrUnknownCollationInFilterParameter

func NewErrUnknownCollationInFilterParameter(col string) Error

NewErrUnknownCollationInFilterParameter (400) returns the corresponding error.

func NewErrUnknownFieldInBody

func NewErrUnknownFieldInBody(typ, field string) Error

NewErrUnknownFieldInBody (400) returns the corresponding error.

func NewErrUnknownFieldInFilterParameter

func NewErrUnknownFieldInFilterParameter(field string) Error

NewErrUnknownFieldInFilterParameter (400) returns the corresponding error.

func NewErrUnknownFieldInURL

func NewErrUnknownFieldInURL(field string) Error

NewErrUnknownFieldInURL (400) returns the corresponding error.

func NewErrUnknownFilterParameterLabel

func NewErrUnknownFilterParameterLabel(label string) Error

NewErrUnknownFilterParameterLabel (400) returns the corresponding error.

func NewErrUnknownOperatorInFilterParameter

func NewErrUnknownOperatorInFilterParameter(op string) Error

NewErrUnknownOperatorInFilterParameter (400) returns the corresponding error.

func NewErrUnknownParameter

func NewErrUnknownParameter(param string) Error

NewErrUnknownParameter (400) returns the corresponding error.

func NewErrUnknownRelationshipInPath

func NewErrUnknownRelationshipInPath(typ, rel, path string) Error

NewErrUnknownRelationshipInPath (400) returns the corresponding error.

func NewErrUnknownTypeInURL

func NewErrUnknownTypeInURL(typ string) Error

NewErrUnknownTypeInURL (400) returns the corresponding error.

func NewErrUnsupportedMediaType

func NewErrUnsupportedMediaType() Error

NewErrUnsupportedMediaType (415) returns the corresponding error.

func NewError

func NewError() Error

NewError returns an empty Error object.

func (Error) Error

func (e Error) Error() string

Error returns the string representation of the error.

If the error does note contain a valid error status code, it returns an empty string.

func (Error) MarshalJSON

func (e Error) MarshalJSON() ([]byte, error)

MarshalJSON returns a JSON representation of the error according to the JSON:API specification.

type Filter added in v0.11.0

type Filter struct {
	Field string      `json:"f"`
	Op    string      `json:"o"`
	Val   interface{} `json:"v"`
	Col   string      `json:"c"`
}

A Filter is used to define filters when querying collections.

func (*Filter) IsAllowed added in v0.11.0

func (f *Filter) IsAllowed(res Resource) bool

IsAllowed reports whether res is valid under the rules defined in the filter.

func (*Filter) UnmarshalJSON added in v0.11.0

func (f *Filter) UnmarshalJSON(data []byte) error

UnmarshalJSON parses the provided data and populates a Filter.

type Identifier

type Identifier struct {
	ID   string `json:"id"`
	Type string `json:"type"`
}

Identifier represents a resource's type and ID.

func UnmarshalIdentifier added in v0.16.0

func UnmarshalIdentifier(payload []byte, schema *Schema) (Identifier, error)

UnmarshalIdentifier reads a payload where the main data is one identifier to build and return an Identifier object.

schema must not be nil.

type Identifiers

type Identifiers []Identifier

Identifiers represents a slice of Identifier.

func NewIdentifiers

func NewIdentifiers(t string, ids []string) Identifiers

NewIdentifiers returns an Identifiers object.

t is the type of the identifiers. ids is the set of IDs.

func UnmarshalIdentifiers added in v0.14.0

func UnmarshalIdentifiers(payload []byte, schema *Schema) (Identifiers, error)

UnmarshalIdentifiers reads a payload where the main data is a collection of identifiers to build and return an Idenfitiers slice.

schema must not be nil.

func (Identifiers) IDs

func (i Identifiers) IDs() []string

IDs returns the IDs part of the Identifiers.

type Link struct {
	HRef string                 `json:"href"`
	Meta map[string]interface{} `json:"meta"`
}

Link represents a JSON:API links object.

func (Link) MarshalJSON

func (l Link) MarshalJSON() ([]byte, error)

MarshalJSON builds the JSON representation of a Link object.

type Meta added in v0.19.0

type Meta map[string]interface{}

Meta holds meta information.

func (Meta) GetBool added in v0.19.0

func (m Meta) GetBool(key string) bool

GetBool returns the bool associated with the given key.

False is returned if the key could not be found or the type is not compatible. The "true" JSON keyword is the only value that will make this method return true.

func (Meta) GetInt added in v0.19.0

func (m Meta) GetInt(key string) int

GetInt returns the int associated with the given key.

0 is returned if the key could not be found or the type is not compatible.

func (Meta) GetString added in v0.19.0

func (m Meta) GetString(key string) string

GetString returns the string associated with the given key.

An empty string is returned if the key could not be found or the type is not compatible.

func (Meta) GetTime added in v0.19.0

func (m Meta) GetTime(key string) time.Time

GetTime returns the time.Time associated with the given key.

time.Time{} is returned is the value associated with the key could not be found or could not be parsed with time.RFC3339Nano.

func (Meta) Has added in v0.19.0

func (m Meta) Has(key string) bool

Has reports whether the Meta map contains or not the given key.

type MetaHolder added in v0.19.0

type MetaHolder interface {
	Meta() Meta
	SetMeta(Meta)
}

A MetaHolder can hold and return meta values.

It is useful for a struct that represents a resource type to implement this interface to have a meta property as part of its JSON output.

Implementations don't have to deeply copy the maps.

type Params

type Params struct {
	// Fields
	Fields  map[string][]string
	Attrs   map[string][]Attr
	Rels    map[string][]Rel
	RelData map[string][]string

	// Filter
	FilterLabel string
	Filter      *Filter

	// Sorting
	SortingRules []string

	// Pagination
	Page map[string]interface{}

	// Include
	Include [][]Rel
}

A Params object represents all the query parameters from the URL.

func NewParams

func NewParams(schema *Schema, su SimpleURL, resType string) (*Params, error)

NewParams creates and returns a Params object built from a SimpleURL and a given resource type. A schema is used for validation.

If validation is not expected, it is recommended to simply build a SimpleURL object with NewSimpleURL.

type Rel

type Rel struct {
	FromType string
	FromName string
	ToOne    bool
	ToType   string
	ToName   string
	FromOne  bool
}

Rel represents a resource relationship.

func (*Rel) Invert added in v0.16.0

func (r *Rel) Invert() Rel

Invert returns the inverse relationship of r.

func (*Rel) Normalize added in v0.14.0

func (r *Rel) Normalize() Rel

Normalize inverts the relationship if necessary in order to have it in the right direction and returns the result.

This is the form stored in Schema.Rels.

func (Rel) String added in v0.16.0

func (r Rel) String() string

String builds and returns the name of the receiving Rel.

r.Normalize is always called.

type Request added in v0.8.0

type Request struct {
	Method string
	URL    *URL
	Doc    *Document
}

A Request represents a JSON:API request.

func NewRequest added in v0.8.0

func NewRequest(r *http.Request, schema *Schema) (*Request, error)

NewRequest builds and returns a *Request based on r and schema.

schema can be nil, in which case no checks will be done to insure that the request respects a specific schema.

type Resource

type Resource interface {
	// Structure
	Attrs() map[string]Attr
	Rels() map[string]Rel

	// Read
	GetType() Type
	Get(key string) interface{}

	// Update
	Set(key string, val interface{})
}

A Resource is an element of a collection.

func UnmarshalResource added in v0.16.0

func UnmarshalResource(data []byte, schema *Schema) (Resource, error)

UnmarshalResource unmarshals a JSON-encoded payload into a Resource.

type Resources added in v0.14.0

type Resources []Resource

Resources is a slice of objects that implement the Resource interface. They do not necessarily have the same type.

func (*Resources) Add added in v0.14.0

func (r *Resources) Add(res Resource)

Add adds a Resource object to r.

func (*Resources) At added in v0.14.0

func (r *Resources) At(i int) Resource

At returns the number of elements in r.

func (*Resources) GetType added in v0.14.0

func (r *Resources) GetType() Type

GetType returns a zero Type object because the collection does not represent a particular type.

func (*Resources) Len added in v0.14.0

func (r *Resources) Len() int

Len returns the number of elements in r.

type Schema added in v0.7.0

type Schema struct {
	Types []Type
	// contains filtered or unexported fields
}

A Schema contains a list of types. It makes sure that all types are valid and their relationships are consistent.

Check can be used to validate the relationships between the types.

func (*Schema) AddAttr added in v0.7.0

func (s *Schema) AddAttr(typ string, attr Attr) error

AddAttr adds an attribute to the specified type.

func (*Schema) AddRel added in v0.7.0

func (s *Schema) AddRel(typ string, rel Rel) error

AddRel adds a relationship to the specified type.

func (*Schema) AddTwoWayRel added in v0.19.0

func (s *Schema) AddTwoWayRel(rel Rel) error

AddTwoWayRel adds a two-way relationship to both types involved.

The types must already exist in the schema.

func (*Schema) AddType added in v0.7.0

func (s *Schema) AddType(typ Type) error

AddType adds a type to the schema.

func (*Schema) Check added in v0.7.0

func (s *Schema) Check() []error

Check checks the integrity of all the relationships between the types and returns all the errors that were found.

func (*Schema) GetType added in v0.7.0

func (s *Schema) GetType(name string) Type

GetType returns the type associated with the speficied name.

If no type with the given name is found, an zero instance of Type is returned. Therefore, checking whether the Name field is empty or not is a good way to dertermine whether the type was found or not.

func (*Schema) HasType added in v0.7.0

func (s *Schema) HasType(name string) bool

HasType returns a boolean indicating whether a type has the specified name or not.

func (*Schema) Rels added in v0.14.0

func (s *Schema) Rels() []Rel

Rels returns all the relationships from the schema's types. For two-way relationships (two types where each has a relationship pointing to the other type), only one of the two relationships will appear in the list.

func (*Schema) RemoveAttr added in v0.7.0

func (s *Schema) RemoveAttr(typ string, attr string)

RemoveAttr removes an attribute from the specified type.

func (*Schema) RemoveRel added in v0.7.0

func (s *Schema) RemoveRel(typ string, rel string)

RemoveRel removes a relationship from the specified type.

func (*Schema) RemoveType added in v0.7.0

func (s *Schema) RemoveType(typ string)

RemoveType removes a type from the schema.

type SimpleURL

type SimpleURL struct {

	// URL
	Fragments []string // [users, abc123, articles]
	Route     string   // /users/:id/articles

	// Params
	Fields       map[string][]string
	FilterLabel  string
	Filter       *Filter
	SortingRules []string
	Page         map[string]interface{}
	Include      []string
}

A SimpleURL represents a URL not validated nor supplemented from a schema.

It parses a URL in text format and stores the values as is.

func NewSimpleURL

func NewSimpleURL(u *url.URL) (SimpleURL, error)

NewSimpleURL takes and parses a *url.URL and returns a SimpleURL.

func (*SimpleURL) Path

func (s *SimpleURL) Path() string

Path returns the path only of the SimpleURL. It does not include any query parameters.

type SoftCollection added in v0.10.0

type SoftCollection struct {
	Type *Type
	// contains filtered or unexported fields
}

SoftCollection is a collection of SoftResources where the type can be changed for all elements at once by modifying the Type field.

func (*SoftCollection) Add added in v0.10.0

func (s *SoftCollection) Add(r Resource)

Add creates a SoftResource and adds it to the collection.

func (*SoftCollection) AddAttr added in v0.10.0

func (s *SoftCollection) AddAttr(attr Attr) error

AddAttr adds an attribute to all of the resources in the collection.

func (*SoftCollection) AddRel added in v0.10.0

func (s *SoftCollection) AddRel(rel Rel) error

AddRel adds a relationship to all of the resources in the collection.

func (*SoftCollection) At added in v0.12.0

func (s *SoftCollection) At(i int) Resource

At returns the element at index i.

func (*SoftCollection) GetType added in v0.11.0

func (s *SoftCollection) GetType() Type

GetType returns the collection's type.

func (*SoftCollection) Len added in v0.10.0

func (s *SoftCollection) Len() int

Len returns the length of the collection.

func (*SoftCollection) Remove added in v0.10.0

func (s *SoftCollection) Remove(id string)

Remove removes the resource with an ID equal to id.

Nothing happens if no resource has such an ID.

func (*SoftCollection) Resource added in v0.10.0

func (s *SoftCollection) Resource(id string, fields []string) Resource

Resource returns the element with an ID equal to id.

It builds and returns a SoftResource with only the specified fields.

func (*SoftCollection) SetType added in v0.11.0

func (s *SoftCollection) SetType(typ *Type)

SetType sets the collection's type.

type SoftResource added in v0.7.0

type SoftResource struct {
	Type *Type
	// contains filtered or unexported fields
}

SoftResource represents a resource whose type is defined by an internal field of type *Type.

Changing the type automatically changes the resource's attributes and relationships. When a field is added, its value is the zero value of the field's type.

func UnmarshalPartialResource added in v0.16.0

func UnmarshalPartialResource(data []byte, schema *Schema) (*SoftResource, error)

UnmarshalPartialResource unmarshals the given payload into a *SoftResource.

The returned *SoftResource will only contain the information found in the payload. That means that fields not in the payload won't be part of the *SoftResource. Its type will be a new type whose fields will be a subset of the fields of the corresponding type from the schema.

This is useful when handling a PATCH request where only some fields might be set to a value. UnmarshalResource returns a Resource where the missing fields are added and set to their zero value, but UnmarshalPartialResource does not do that. Therefore, the user is able to tell which fields have been set.

func (*SoftResource) AddAttr added in v0.7.0

func (sr *SoftResource) AddAttr(attr Attr)

AddAttr adds an attribute.

func (*SoftResource) AddRel added in v0.7.0

func (sr *SoftResource) AddRel(rel Rel)

AddRel adds a relationship.

func (*SoftResource) Attr added in v0.7.0

func (sr *SoftResource) Attr(key string) Attr

Attr returns the attribute named after key.

func (*SoftResource) Attrs added in v0.7.0

func (sr *SoftResource) Attrs() map[string]Attr

Attrs returns the resource's attributes.

func (*SoftResource) Copy added in v0.7.0

func (sr *SoftResource) Copy() Resource

Copy returns a new SoftResource object with the same type and values.

func (*SoftResource) Get added in v0.7.0

func (sr *SoftResource) Get(key string) interface{}

Get returns the value associated to the field named after key.

func (*SoftResource) GetID added in v0.7.0

func (sr *SoftResource) GetID() string

GetID returns the resource's ID.

func (*SoftResource) GetType added in v0.7.0

func (sr *SoftResource) GetType() Type

GetType returns the resource's type.

func (*SoftResource) Meta added in v0.19.0

func (sr *SoftResource) Meta() Meta

Meta returns the meta values of the resource.

func (*SoftResource) New added in v0.7.0

func (sr *SoftResource) New() Resource

New returns a new resource (of type SoftResource) with the same type but without the values.

func (*SoftResource) Rel added in v0.7.0

func (sr *SoftResource) Rel(key string) Rel

Rel returns the relationship named after key.

func (*SoftResource) Rels added in v0.7.0

func (sr *SoftResource) Rels() map[string]Rel

Rels returns the resource's relationships.

func (*SoftResource) RemoveField added in v0.7.0

func (sr *SoftResource) RemoveField(field string)

RemoveField removes a field.

func (*SoftResource) Set added in v0.7.0

func (sr *SoftResource) Set(key string, v interface{})

Set sets the value associated to the field named key to v.

func (*SoftResource) SetID added in v0.7.0

func (sr *SoftResource) SetID(id string)

SetID sets the resource's ID.

func (*SoftResource) SetMeta added in v0.19.0

func (sr *SoftResource) SetMeta(m Meta)

SetMeta sets the meta values of the resource.

func (*SoftResource) SetType added in v0.7.0

func (sr *SoftResource) SetType(typ *Type)

SetType sets the resource's type.

type Type

type Type struct {
	Name    string
	Attrs   map[string]Attr
	Rels    map[string]Rel
	NewFunc func() Resource
}

A Type stores all the necessary information about a type as represented in the JSON:API specification.

NewFunc stores a function that returns a new Resource of the type defined by the object with all the fields and the ID set to their zero values. Users may call the New method which returns the result of NewFunc if it is non-nil, otherwise it returns a SoftResource based on the type.

New makes sure NewFunc is not nil and then calls it, but does not use any kind of locking in the process. Therefore, it is unsafe to set NewFunc and call New concurrently.

func BuildType added in v0.14.0

func BuildType(v interface{}) (Type, error)

BuildType takes a struct or a pointer to a struct to analyse and builds a Type object that is returned.

If an error is returned, the Type object will be empty.

func MustBuildType added in v0.14.0

func MustBuildType(v interface{}) Type

MustBuildType calls BuildType and returns the result.

It panics if the error returned by BuildType is not nil.

func (*Type) AddAttr added in v0.7.0

func (t *Type) AddAttr(attr Attr) error

AddAttr adds an attributes to the type.

func (*Type) AddRel added in v0.7.0

func (t *Type) AddRel(rel Rel) error

AddRel adds a relationship to the type.

func (Type) Copy added in v0.16.0

func (t Type) Copy() Type

Copy deeply copies the receiver and returns the result.

func (Type) Equal added in v0.14.0

func (t Type) Equal(typ Type) bool

Equal returns true if both types have the same name, attributes, relationships. NewFunc is ignored.

func (*Type) Fields

func (t *Type) Fields() []string

Fields returns a list of the names of all the fields (attributes and relationships) in the type.

func (*Type) New added in v0.14.0

func (t *Type) New() Resource

New calls the NewFunc field and returns the result Resource object.

If NewFunc is nil, it returns a *SoftResource with its Type field set to the value of the receiver.

func (*Type) RemoveAttr added in v0.7.0

func (t *Type) RemoveAttr(attr string)

RemoveAttr removes an attribute from the type if it exists.

func (*Type) RemoveRel added in v0.7.0

func (t *Type) RemoveRel(rel string)

RemoveRel removes a relationship from the type if it exists.

type URL

type URL struct {
	// URL
	Fragments []string // [users, u1, articles]
	Route     string   // /users/:id/articles

	// Data
	IsCol           bool
	ResType         string
	ResID           string
	RelKind         string
	Rel             Rel
	BelongsToFilter BelongsToFilter

	// Params
	Params *Params
}

A URL stores all the information from a URL formatted for a JSON:API request.

The data structure allows to have more information than what the URL itself stores.

func NewURL

func NewURL(schema *Schema, su SimpleURL) (*URL, error)

NewURL builds a URL from a SimpleURL and a schema for validating and supplementing the object with extra information.

func NewURLFromRaw added in v0.12.0

func NewURLFromRaw(schema *Schema, rawurl string) (*URL, error)

NewURLFromRaw parses rawurl to make a *url.URL before making and returning a *URL.

func (*URL) String added in v0.12.0

func (u *URL) String() string

String returns a string representation of the URL where special characters are escaped.

The URL is normalized, so it always returns exactly the same string given the same URL.

func (*URL) UnescapedString added in v0.12.0

func (u *URL) UnescapedString() string

UnescapedString returns the same thing as String, but special characters are not escaped.

type Wrapper

type Wrapper struct {
	// contains filtered or unexported fields
}

Wrapper wraps a reflect.Value that represents a struct.

The Wrap function can be used to wrap a struct and make a Wrapper object.

It implements the Resource interface, so the value can be handled as if it were a Resource.

func Wrap

func Wrap(v interface{}) *Wrapper

Wrap wraps v (a struct or a pointer to a struct) and returns a Wrapper that can be used as a Resource to handle the given value.

Changes made to the Wrapper object (through Set for example) will be applied to v.

If v is not a pointer, a copy is made and v won't be modified by the wrapper.

func (*Wrapper) Attr

func (w *Wrapper) Attr(key string) Attr

Attr returns the attribute that corresponds to the given key.

func (*Wrapper) Attrs

func (w *Wrapper) Attrs() map[string]Attr

Attrs returns the attributes of the Wrapper.

func (*Wrapper) Copy

func (w *Wrapper) Copy() Resource

Copy makes a copy of the wrapped resource and returns it.

The returned value's concrete type is also a Wrapper.

func (*Wrapper) Get

func (w *Wrapper) Get(key string) interface{}

Get returns the value associated to the attribute named after key.

func (*Wrapper) GetID

func (w *Wrapper) GetID() string

GetID returns the wrapped resource's ID.

func (*Wrapper) GetType

func (w *Wrapper) GetType() Type

GetType returns the wrapped resource's type.

func (*Wrapper) IDAndType

func (w *Wrapper) IDAndType() (string, string)

IDAndType returns the ID and the type of the Wrapper.

func (*Wrapper) Meta added in v0.19.0

func (w *Wrapper) Meta() Meta

Meta returns the meta values of the resource.

func (*Wrapper) New

func (w *Wrapper) New() Resource

New returns a copy of the resource under the wrapper.

func (*Wrapper) Rel

func (w *Wrapper) Rel(key string) Rel

Rel returns the relationship that corresponds to the given key.

func (*Wrapper) Rels

func (w *Wrapper) Rels() map[string]Rel

Rels returns the relationships of the Wrapper.

func (*Wrapper) Set

func (w *Wrapper) Set(key string, val interface{})

Set sets the value associated to the attribute named after key.

func (*Wrapper) SetID

func (w *Wrapper) SetID(id string)

SetID sets the ID of the wrapped resource.

func (*Wrapper) SetMeta added in v0.19.0

func (w *Wrapper) SetMeta(m Meta)

SetMeta sets the meta values of the resource.

type WrapperCollection

type WrapperCollection struct {
	// contains filtered or unexported fields
}

WrapperCollection is a Collection of resources of a certain type defined using the WrapCollection constructor.

Only resources of that type can be added to the collection and the type may not be modified.

func WrapCollection

func WrapCollection(r Resource) *WrapperCollection

WrapCollection returns a *WrapperCollection which implements the Collection interface and holds resources of the type defined in r.

func (*WrapperCollection) Add

func (wc *WrapperCollection) Add(r Resource)

Add appends the given resource at the end of the collection.

func (*WrapperCollection) At added in v0.12.0

func (wc *WrapperCollection) At(i int) Resource

At returns the resource at the given index.

It returns nil if the index is greater than the number of resources in the collection.

func (*WrapperCollection) GetType added in v0.12.0

func (wc *WrapperCollection) GetType() Type

GetType returns the type of the resources in the collection.

func (*WrapperCollection) Len

func (wc *WrapperCollection) Len() int

Len returns the number of elements in the collection.

Jump to

Keyboard shortcuts

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