jsonapi

package module
v2.1.0 Latest Latest
Warning

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

Go to latest
Published: Aug 26, 2024 License: MIT Imports: 14 Imported by: 0

README

jsonapi

Test GoDoc Release

Yet Another JSON API library for Go.

Package jsonapi provides structures and functions to implement JSON API compatible APIs. The library can be used with any framework and is built on top of the standard Go http library.

Installation

Get the package using the go tool:

$ go get -u github.com/gonobo/jsonapi/v2

Structures

This library uses StructField tags to annotate the structs fields that you already have and use in your app and then reads and writes JSON API output based on the tag content.

type Customer struct {
  ID   string `jsonapi:"primary,customers"`
  Name string `jsonapi:"attr,name"`
}

type Order struct {
  ID       string     `jsonapi:"primary,orders"`
  Customer *Customer  `jsonapi:"relation,customer"`
  Products []*Product `jsonapi:"relation,products,omitempty"`
}

type Product struct {
  ID string   `jsonapi:"primary,products"`
  Name string `jsonapi:"attr,name"`
}

// This object...
order := Order{
  ID:       "1",
  Customer: &Customer{ID: "2", Name: "John"},
  Products: []*Product{
    {ID: "42", Name: "Shoes"},
    {ID: "24", Name: "Socks"},
  }
}

// ...is transformed into this resource when marshaled.
resource := jsonapi.Resource{
  ID:   "1",
  Type: "orders",
  Relationships: jsonapi.Relationships{
    "customer": &jsonapi.Relationship{
      Data: jsonapi.One{
        Value: &jsonapi.Resource{
          ID:         "2",
          Type:       "customers",
          Attributes: map[string]any{"name": "John"},
        }}
    },
    "products": &jsonapi.Relationship{
      Data: jsonapi.Many{
        Values: []*jsonapi.Resource{
          {
            ID:         "42",
            Type:       "products",
            Attributes: map[string]any{"name": "Shoes"}
          },
          {
            ID:         "24",
            Type:       "products",
            Attributes: map[string]any{"name": "Socks"}
          },
        },
      },
    },
  }
}
Permitted Tag Values

Struct tag values are equivalent to those found in the Google JSON API library:

primary
`jsonapi:"primary,<type field output>"`

This indicates this is the primary key field for this struct type. Tag value arguments are comma separated. The first argument must be, primary, and the second must be the name that should appear in the type* field for all data objects that represent this type of model.

* According the JSON API spec, the plural record types are shown in the examples, but not required.

attr
`jsonapi:"attr,<key name in attributes hash>,<optional: omitempty>"`

These fields' values will end up in the attributeshash for a record. The first argument must be, attr, and the second should be the name for the key to display in the attributes hash for that record. The optional third argument is omitempty - if it is present the field will not be present in the "attributes" if the field's value is equivalent to the field types empty value (ie if the count field is of type int, omitempty will omit the field when count has a value of 0). Lastly, the spec indicates that attributes key names should be dasherized for multiple word field names.

relation
`jsonapi:"relation,<key name in relationships hash>,<optional: omitempty>"`

Relations are struct fields that represent a one-to-one or one-to-many relationship with other structs. JSON API will traverse the graph of relationships and marshal or unmarshal records. The first argument must be, relation, and the second should be the name of the relationship, used as the key in the relationships hash for the record. The optional third argument is omitempty - if present will prevent non existent to-one and to-many from being serialized.

Marshaling and Unmarshaling

All Marshal and Unmarshal methods expect pointers to struct instance or slices of the same type. Using values during marshaling and unmarshal is undefined behavior.

import "github.com/gonobo/jsonapi/v2"

func createOrder(w *http.ResponseWriter, r *http.Request) {
  in, err := jsonapi.Decode(r.Body)
  order := Order{}
  err = jsonapi.Unmarshal(in, &order)

  newOrder, err := db.CreateNewOrder(order)
  out, err := jsonapi.Marshal(newOrder)
  w.WriteHeader(http.StatusCreated)
  err = jsonapi.Write(w, out)
}

JSON:API Server

The server package contains structs and methods for handling http requests that conform to the JSON:API specification.

The server.Handler struct wraps a standard http.Handler instance, inferring the JSON:API context from the request:

import (
  "net/http"

  "github.com/gonobo/jsonapi/v2"
  "github.com/gonobo/jsonapi/v2/server"
)

func main() {
  mux := http.NewServeMux()
  mux.Handle(
    "GET /orders/42/relationships/customer",
    http.HandleFunc(getOrderCustomer),
  )

  handler := jsonapi.Handle(mux)
  http.ListenAndServe(":3000", handler)
}

func getOrderCustomer(w http.ResponseWriter, r *http.Request) {
  ctx := jsonapi.Context(r.Context())

  log.Printf("type: %s", ctx.ResourceType)         // "orders"
  log.Printf("id: %s", ctx.ResourceID)             // "42"
  log.Printf("relationship: %s", ctx.Relationship) // "customer"
  
  order, err := db.GetOrder(ctx, ctx.ResourceID)
  if err != nil {
    // return an JSON:API error document with the error message
    // reflected in the details field.
    server.Error(w, err, http.StatusInternalServerError)
    return
  }

  // write the order's customer as a resource reference in the
  // response document.
  server.Write(w, order, http.StatusOk,
    server.WriteRef("customer"),
  )
}

There are additional handlers that can take care of routing requests to their proper handler:

import (
  "net/http"

  "github.com/gonobo/jsonapi/v2"
  "github.com/gonobo/jsonapi/v2/server"
)

func main() {
  mux := http.NewServeMux()
  mux.Handle("/",
    server.ResourceMux{
      "orders": server.Resource{
        Get:             http.HandlerFunc(getOrder),      // GET /orders/42
        Create:          http.HandlerFunc(createOrder),   // POST /orders
        List:            http.HandlerFunc(searchOrders),  // GET /orders
        Relationships:   server.RelationshipMux{
          "customer": server.Relationship{
            Get: http.HandlerFunc(getOrderCustomer),      // GET /orders/42/relationships/customer
          },
        },
      },
    },
  )

  handler := jsonapi.Handle(mux)
  http.ListenAndServe(":3000", handler)
}

The handlers only deal with http.Handler instances so you can control the degree of precision.

Examples

TBD.

License

The MIT License (MIT)

Copyright (c) 2024 Nathan Simpson

Documentation

Index

Constants

View Source
const LatestSupportedVersion = "1.1"
View Source
const (
	MediaType = "application/vnd.api+json"
)

Variables

View Source
var (
	ErrJSONAPI = errors.New("jsonapi error")
)

Functions

func Decode

func Decode(r io.Reader, doc *Document) error

Decode reads the JSON-encoded document from its input and stores it in the input document.

func Do

func Do(c Client, options ...func(*http.Request)) (*http.Response, error)

Do sends a request to the server.

func Encode

func Encode(w io.Writer, doc Document) error

Encode writes the JSON encoding of v to the stream, followed by a newline character.

func MarshalRaw

func MarshalRaw(value any) (*json.RawMessage, error)

MarshalRaw serializes the input value to its JSON equivalent, wrapped in a RawMessage type for ease of use. Typically used for marshaling extensions within a JSON:API document.

func RequestWithContext

func RequestWithContext(r *http.Request, c *RequestContext) *http.Request

RequestWithContext sets the request context on the provided request.

func Unmarshal

func Unmarshal(doc *Document, out any) error

Unmarshal populates the output struct or slice with information stored inside the provided document. Struct fields must either be properly tagged with "jsonapi:" or the struct must implement the UnmarshalResourceJSONAPI() method.

func UnmarshalResource

func UnmarshalResource(node *Resource, out any) error

UnmarshalResource populates the output struct's fields with information stored inside the provided resource node. Fields must either be properly tagged with "jsonapi:" or the struct must implement the UnmarshalJSONAPI() method.

func WithContext

func WithContext(ctx context.Context, value *RequestContext) context.Context

WithContext sets the JSON:API Context in the parent context.

Types

type Client

type Client struct {
	JSONEncoder                // The JSON encoder.
	URLResolver                // The URL resolver.
	Doer                       // The underlying http client.
	BaseURL     string         // The base url of the JSON:API server.
	Context     RequestContext // The JSON:API request context.
	Method      string         // The http method to use.
}

Client is a JSON:API http client. It uses an underlying standard library http client to send requests that adhere to the JSON:API specification.

By default, Client generates the following urls (given a base url):

":base/:type" for search, create
":base/:type/:id" for fetch, update, delete
":base/:type/:id/relationships/:ref" for fetchRef
":base/:type/:id/:ref" for fetchRelated

This behavior can be modified by updating the URLResolver field of a Client instance.

func NewRequest

func NewRequest(baseURL string, options ...func(*Client)) Client

NewRequest creates a new JSON:API request instance.

func (Client) AddRefsToMany

func (c Client) AddRefsToMany(data Resource, ref string, options ...func(*http.Request)) (*http.Response, error)

AddRefsToMany adds a server resource reference to the provided resource's "to-many" relationship.

func (Client) Create

func (c Client) Create(data Resource, options ...func(*http.Request)) (*http.Response, error)

Create creates a new server resource. If the resource has an empty string resource ID, then the server will assign it; otherwise, the id will be submitted in the request payload.

func (Client) Delete

func (c Client) Delete(resourceType, id string, options ...func(*http.Request)) (*http.Response, error)

Delete removes a resource from the server.

func (Client) Get

func (c Client) Get(resourceType, id string, options ...func(*http.Request)) (*http.Response, error)

Get retrieves a single resource from the server.

func (Client) GetRef

func (c Client) GetRef(resourceType, id, ref string, options ...func(*http.Request)) (*http.Response, error)

GetRef retrieves a single resource's relationship from the server.

func (Client) GetRelated

func (c Client) GetRelated(resourceType, id, relation string, options ...func(*http.Request)) (*http.Response, error)

GetRelated retrieves all server resources that are referenced in a resource's relationship.

func (Client) List

func (c Client) List(resourceType string, options ...func(*http.Request)) (*http.Response, error)

List retrieves a collection of server resources associated with the resource type.

func (Client) RemoveRefsFromMany

func (c Client) RemoveRefsFromMany(data Resource, ref string, options ...func(*http.Request)) (*http.Response, error)

RemoveRefsFromMany removes a server resource reference to the provided resource's "to-many" relationship.

func (Client) Update

func (c Client) Update(data Resource, options ...func(*http.Request)) (*http.Response, error)

Update updates a new server resource.

func (Client) UpdateRef

func (c Client) UpdateRef(data Resource, ref string, options ...func(*http.Request)) (*http.Response, error)

UpdateRef replaces a single resource's relationship with the request data.

type Comparator

type Comparator interface {
	// Compare compares the values of the specified attribute for the
	// two resources at the specified indexes. If the two values are
	// equivalent, then Compare() should return 0. If the first value is
	// greater than the second value, then Compare() should return a
	// positive value. If the first value is less than the second value,
	// then Compare() should return a negative value.
	Compare(i, j int, attribute string) int
}

Comparator compares two resources and determines ordinality by comparing the values of a specified attribute.

func ResourceComparator

func ResourceComparator[S ~[]T, T any](arr S, m map[string]Comparer[T]) Comparator

ResourceComparator returns a Comparator that compares two resources a and b based on an attribute specified by the key index of map m.

type ComparatorFunc

type ComparatorFunc func(i, j int, attribute string) int

ComparatorFunc functions implement Comparator.

func (ComparatorFunc) Compare

func (f ComparatorFunc) Compare(i, j int, attribute string) int

Compare compares items indexed at i and j, returning negative if less, positive if greater, or zero if equal.

type Comparer

type Comparer[T any] func(a, b T) int

Comparer determines the order of two items.

type ContextResolver

type ContextResolver interface {
	// ResolveContext resolves the JSON:API context from the provided http request.
	// The context informs downstream dependencies; at minimum, the context should
	// populate the following fields (if applicable):
	//	- ResourceType (the resource type being requested)
	//	- ResourceID (the unique identifier of the resource being requested)
	//	- Relationship (the relationship being requested)
	//	- Related (whether the relationship is a related resource)
	ResolveContext(*http.Request) (*RequestContext, error)
}

ContextResolver resolves JSON:API context information from an incoming http request.

type ContextResolverFunc

type ContextResolverFunc func(*http.Request) (*RequestContext, error)

ContextResolverFunc functions implement ContextResolver.

func DefaultContextResolver

func DefaultContextResolver() ContextResolverFunc

DefaultContextResolver returns a resolver that populates a JSON:API context based on the URL path examples given by the JSON:API specification:

"/:type"                         // ResourceType
"/:type/:id"                     // ResourceType, ResourceID
"/:type/:id/relationships/:ref"  // ResourceType, ResourceID, Relationship
"/:type/:id/:ref"                // ResourceType, ResourceID, Relationship, Related

func (ContextResolverFunc) ResolveContext

func (fn ContextResolverFunc) ResolveContext(r *http.Request) (*RequestContext, error)

ResolveContext resolves the JSON:API context from the provided http request.

type DefaultJSONEncoder

type DefaultJSONEncoder struct{}

DefaultJSONEncoder is a wrapper that implements JSONEncoder by calling:

json.NewEncoder(w).Encode(value).

func (DefaultJSONEncoder) EncodeJSON

func (DefaultJSONEncoder) EncodeJSON(w io.Writer, value any) error

EncodeJSON encodes the provided value to JSON.

type Document

type Document struct {
	Jsonapi    JSONAPI                     // The JSON:API object.
	Data       PrimaryData                 // The primary data.
	Meta       Meta                        // Top-level metadata.
	Links      Links                       // Top-level links.
	Errors     []*Error                    // Server response errors.
	Included   []*Resource                 // Included resources associated with the primary data.
	Extensions map[string]*json.RawMessage // Optional JSON:API extensions.
}

Document is the highest order node, containing either a single resource or collection of resources in response to a client request. Clients also send documents to a server to create or modify existing resources.

func Marshal

func Marshal(in any) (Document, error)

Marshal generates a JSON:API document from the specified value. If the value is a struct, then a single document is returned, using the value as primary data. If the value is a slice or array, then a many document is returned, using the value as primary data.

Marshaling Document structs simply returns a copy of the instance.

func MarshalRef

func MarshalRef(in any, name string) (Document, error)

MarshalRef generates a JSON:API document, using a resource's relationship as primary data. It otherwise functions in the same manner as Marshal().

func NewMultiDocument

func NewMultiDocument(data ...*Resource) *Document

NewMultiDocument creates a new document with the provided resources as primary data.

func NewSingleDocument

func NewSingleDocument(data *Resource) *Document

NewSingleDocument creates a new document with the provided resource as primary data.

func (Document) Error

func (d Document) Error() error

Error calls errors.Join() on all errors within the document. It returns a single error if any errors were present or nil otherwise.

func (Document) MarshalJSON

func (d Document) MarshalJSON() ([]byte, error)

MarshalJSON serializes the document as JSON.

func (*Document) Sort

func (d *Document) Sort(cmp Comparator, criterion []query.Sort)

Sort sorts the document's primary data by comparing the resources against the provided sort criterion.

func (*Document) UnmarshalJSON

func (d *Document) UnmarshalJSON(data []byte) error

UnmarshalJSON deserializes the document from JSON, populating its contents.

func (Document) Validate

func (d Document) Validate(validator DocumentValidator) error

type DocumentValidator

type DocumentValidator interface {
	ValidateDocument(*Document) error
}

type Doer

type Doer interface {
	// Do sends an HTTP request and returns an HTTP response.
	Do(*http.Request) (*http.Response, error)
}

Doer is responsible for sending HTTP requests. The Golang http.Client struct implements this interface.

type Error

type Error struct {
	ID     string       `json:"id,omitempty"`     // A unique identifier for this particular occurrence of the problem.
	Links  Links        `json:"links,omitempty"`  // A links object associated with the error.
	Status string       `json:"status,omitempty"` // The HTTP status code applicable to this problem.
	Code   string       `json:"code,omitempty"`   // An application-specific error code.
	Title  string       `json:"title,omitempty"`  // A short summary of the problem.
	Detail string       `json:"detail,omitempty"` // A specific explanation of the problem.
	Source *ErrorSource `json:"source,omitempty"` // An object containing references to the primary source of the error.
	Meta   Meta         `json:"meta,omitempty"`   // Contains non-standard meta-information about the error.
}

Error provides additional information about problems encountered while performing an operation. Error objects MUST be returned as an array keyed by errors in the top level of a JSON:API document.

func NewError

func NewError(cause error, title string) Error

NewError creates a new ErrorNode with the given status and title.

func (Error) Error

func (e Error) Error() string

Error returns the combined title and detail as a single message.

type ErrorSource

type ErrorSource struct {
	// A JSON Pointer [RFC6901] to the value in the request document
	// that caused the error [e.g. "/data" for a primary data object,
	// or "/data/attributes/title" for a specific attribute].
	Pointer string `json:"pointer,omitempty"`

	Parameter string `json:"parameter,omitempty"` // URI query parameter that caused the error.
	Header    string `json:"header,omitempty"`    // Name of a single request header which caused the error.
}

ErrorSource is an object containing references to the primary source of the error.

type ExtensionsNode

type ExtensionsNode = map[string]*json.RawMessage

ExtensionsNode contains data defined by JSON:API extensions. Since they can be arbitrary, they are stored as raw JSON messages to be serialized by the caller.

type HrefLang

type HrefLang []string

HrefLang is a string or an array of strings indicating the language(s) of the link’s target. An array of strings indicates that the link’s target is available in multiple languages. Each string MUST be a valid language tag [RFC5646].

HrefLang is serialized as a string if there is only one element within the slice, or an array of strings otherwise.

func (HrefLang) MarshalJSON

func (h HrefLang) MarshalJSON() ([]byte, error)

MarshalJSON provides custom JSON deserialization.

func (*HrefLang) UnmarshalJSON

func (h *HrefLang) UnmarshalJSON(data []byte) error

UnmarshalJSON provides custom JSON deserialization.

type JSONAPI

type JSONAPI struct {
	Version Version        `json:"version"`           // The highest specification version supported by the server.
	Ext     []string       `json:"ext,omitempty"`     // An array of URIs for all applied extensions.
	Profile []string       `json:"profile,omitempty"` // An array of URIs for all applied profiles.
	Meta    map[string]any `json:"meta,omitempty"`    // Metadata containing non-standard information.
}

JSONAPI includes information about the server's implementation. See https://jsonapi.org/format/#document-jsonapi-object for details.

type JSONEncoder

type JSONEncoder interface {
	// EncodeJSON encodes the provided value to JSON.
	EncodeJSON(w io.Writer, value any) error
}

JSONEncoder is responsible for encoding JSON data. It is primarily used for dependency injection during unit testing.

type Link struct {
	Href     string   // URI-reference pointing to the link’s target.
	Rel      string   // The link’s relation type.
	Type     string   // The media type of the link’s target.
	Title    string   // Human-readable link destination.
	HrefLang HrefLang // Array of strings indicating the link's target language(s).
	Meta     Meta     // Contains non-standard meta-information about the link.
}

Link represents a single link.

func (Link) MarshalJSON

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

MarshalJSON serializes this link to JSON.

func (*Link) UnmarshalJSON

func (l *Link) UnmarshalJSON(data []byte) error

UnmarshalJSON deserializes this link from JSON.

type Links = map[string]*Link

Links contains the links defined within a resource, document, or error.

type LinksMarshaler

type LinksMarshaler interface {
	// MarshalLinksJSONAPI returns links associated with the instance when marshaled.
	MarshalLinksJSONAPI() Links
}

LinksMarshaler creates links associated with the instance when marshaled.

type LinksUnmarshaler

type LinksUnmarshaler interface {
	// UnmarshalLinksJSONAPI extracts links from a resource node and populates itself.
	UnmarshalLinksJSONAPI(Links)
}

LinksUnmarshaler can extract links from a resource node and populate itself.

type Many

type Many struct {
	Value []*Resource `json:"-"` // Value is the collection of resources.
}

Many is a data node that represents a "to-many" relationship or a document's primary data.

func (Many) First

func (m Many) First() *Resource

First returns the first item in the array of resources.

func (Many) IsMany

func (Many) IsMany() bool

IsMany returns true, as this is a "to-many" relationship.

func (Many) Items

func (m Many) Items() []*Resource

Items returns the underlying value collection.

func (Many) MarshalJSON

func (m Many) MarshalJSON() ([]byte, error)

MarshalJSON serializes the node to JSON.

func (*Many) UnmarshalJSON

func (m *Many) UnmarshalJSON(data []byte) error

UnmarshalJSON deserializes the node from JSON.

type Meta

type Meta = map[string]any

Meta contains non-standard information within a document.

type MetaMarshaler

type MetaMarshaler interface {
	// MarshalMetaJSONAPI returns metadata associated with the instance when marshaled.
	MarshalMetaJSONAPI() Meta
}

MetaMarshaler creates metadata associated with the instance when marshaled.

type MetaUnmarshaler

type MetaUnmarshaler interface {
	// UnmarshalMetaJSONAPI extracts metadata from a resource node and populates itself.
	UnmarshalMetaJSONAPI(Meta)
}

MetaUnmarshaler can extract metadata from a resource node and populate itself.

type One

type One struct {
	Value *Resource `json:"-"` // Value is the single resource.
}

One is a data node that represents either a "to-one" relationship or a document's primary data.

func (One) First

func (o One) First() *Resource

First returns the resource value (if present) or nil.

func (One) IsMany

func (One) IsMany() bool

IsMany returns false, as this is a "to-one" relationship.

func (One) IsNull

func (o One) IsNull() bool

IsNull returns true if the node value is nil.

func (One) Items

func (o One) Items() []*Resource

Items returns the underlying value in a collection.

func (One) MarshalJSON

func (o One) MarshalJSON() ([]byte, error)

MarshalJSON serializes the node to JSON.

func (*One) UnmarshalJSON

func (o *One) UnmarshalJSON(data []byte) error

UnmarshalJSON deserializes the node from JSON.

type PrimaryData

type PrimaryData interface {
	// Items returns the contained items as a collection of resources.
	//	- If the data node represents a null "to-one" relationship, then the slice will be empty.
	//	- If the data node represents a "to-one" relationship, then the slice will contain the
	//		associated resource at the first index.
	//	- If the data node represents a "to-many" relationship, then the slice will contain
	//		the associated resources.
	Items() []*Resource
	// IsMany returns true if the data represents a "to-many" relationship or collection of primary data.
	IsMany() bool
	// First returns the first item in a primary data node -- the node itself for single or "one"
	// primary data, or the first element in multi or "many" primary data.
	//
	// If the data node is set to "null" (a jsonapi.One instance with a nil value) then nil is returned.
	// If the data node itself is nil, First() panics.
	First() *Resource
}

PrimaryData interfaces provide document primary data or resource relationship data. Since data can be either a single resource or a collection of resources, PrimaryData has helper functions to both identify and iterate over said resources.

type RelatedLinksMarshaler

type RelatedLinksMarshaler interface {
	// MarshalRelatedLinksJSONAPI returns links associated with an instance's relationships when marshaled.
	MarshalRelatedLinksJSONAPI(name string) Links
}

RelatedLinksMarshaler creates links associated with an instance's relationships when marshaled.

type RelatedLinksUnmarshaler

type RelatedLinksUnmarshaler interface {
	// UnmarshalRelatedLinksJSONAPI extracts relationship links from a node and populate itself.
	UnmarshalRelatedLinksJSONAPI(name string, links Links)
}

RelatedLinksUnmarshaler can extract relationship links from a node and populate itself.

type RelatedMetaMarshaler

type RelatedMetaMarshaler interface {
	// MarshalRelatedMetaJSONAPI returns metadata associated with an instance's relationships when marshaled.
	MarshalRelatedMetaJSONAPI(name string) Meta
}

RelatedMetaMarshaler creates metadata associated with an instance's relationships when marshaled.

type RelatedMetaUnmarshaler

type RelatedMetaUnmarshaler interface {
	// UnmarshalRelatedMetaJSONAPI extracts relationship metadata from a node and populates itself.
	UnmarshalRelatedMetaJSONAPI(name string, meta Meta)
}

RelatedMetaUnmarshaler can extract relationship metadata from a node and populate itself.

type Relationship

type Relationship struct {
	Data  PrimaryData // Relationship data containing associated references.
	Links Links       // URL links related to the relationship.
	Meta  Meta        // Non-standard information related to the relationship.
}

Relationship describes a resource's relationships. Relationships are contain either "to-many" or "to-one" associations with the parent resource. See https://jsonapi.org/format/#document-resource-object-relationships for details.

func (Relationship) MarshalJSON

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

func (*Relationship) UnmarshalJSON

func (r *Relationship) UnmarshalJSON(data []byte) error

UnmarshalJSON deserializes this relationship from JSON.

type RelationshipsNode

type RelationshipsNode = map[string]*Relationship

RelationshipsNode contains the relationships defined within a resource.

type RequestContext

type RequestContext struct {
	ResourceType string                 // The request resource type, e.g, "users".
	ResourceID   string                 // The request resource ID, e.g, "123".
	Relationship string                 // The request relationship, e.g, "posts".
	Related      bool                   // If true, the server should fetch the resources associated with the relationship.
	FetchIDs     []string               // If nonempty, the server should fetch the resources with these IDs.
	Include      []string               // The list of resources associated with the request resource that should be included in the response.
	Document     *Document              // The JSON:API document that defines the request payload.
	Fields       []query.Fieldset       // The list of fields (attributes, relationships, etc.) that should be included in the response payload
	Filter       query.FilterExpression // The filter expression that was evaluated from the request query.
	Sort         []query.Sort           // The sort criteria that was evaluated from the request query.
	Pagination   query.Page             // The pagination criteria that was evaluated from the request query.
	// contains filtered or unexported fields
}

RequestContext contains information about the JSON:API request that defines it.

RequestContext decouples information relevant to the specification, such as the resource type, unique identifier, relationships, etc. from the request itself.

func FromContext

func FromContext(parent context.Context) *RequestContext

FromContext returns the JSON:API FromContext from the parent context. FromContext panics if the context was never set.

func (*RequestContext) Child

func (c *RequestContext) Child() *RequestContext

Child returns a new Context that is a child of the current Context; the new child context contains the same information as its parent.

func (RequestContext) Clone

func (c RequestContext) Clone() *RequestContext

Clone returns a new Context that is a clone of the current Context.

func (*RequestContext) EmptyChild

func (c *RequestContext) EmptyChild() *RequestContext

EmptyChild returns a new Context that is a child of the current Context.

func (RequestContext) Parent

func (c RequestContext) Parent() *RequestContext

Parent returns the parent Context of the current Context.

func (RequestContext) Root

func (c RequestContext) Root() *RequestContext

Root returns the root Context of the current Context. That is, the top-most parent that has no parent of its own.

type Resource

type Resource struct {
	ID            string            // ID is the unique identifier of the resource.
	LocalID       string            // LocalID is the unique identifier of the resource within the context of the document.
	Type          string            // Type is the type of resource.
	Attributes    map[string]any    // Attributes are the resource's attributes.
	Relationships RelationshipsNode // Relationships are the resource's relationships.
	Links         Links             // Links are the resource's associated URL links.
	Meta          Meta              // Meta contains any non-standard information about the resource.
	Extensions    ExtensionsNode    // Extensions contain any JSON:API extensions associated with the resource.
}

Resource represents a server resource. Resources can appear in documents as primary data, included resources, or referenced in other resources' relationships. See https://jsonapi.org/format/#document-resource-objects for details.

func MarshalResource

func MarshalResource(in any) (*Resource, error)

MarshalResource generates a JSON:API resource object based on the input struct's fields. Fields must be tagged with "jsonapi:" in order to be processed by the marshaler, or the struct type can implement MarshalResourceJSONAPI() to override the process.

func (Resource) MarshalJSON

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

MarshalJSON serializes this resource into JSON.

func (Resource) MarshalJSONAPI

func (r Resource) MarshalJSONAPI() (*Resource, error)

MarshalJSONAPI returns a shallow copy of this resource.

func (Resource) Ref

func (r Resource) Ref() *Resource

Ref returns a reference to this resource. Any non essential information -- information that is not required to identify the resource -- is omitted. Any resource metadata, however is included.

func (*Resource) UnmarshalJSON

func (r *Resource) UnmarshalJSON(data []byte) error

UnmarshalJSON deserializes this resource from JSON.

func (*Resource) UnmarshalJSONAPI

func (r *Resource) UnmarshalJSONAPI(other *Resource) error

UnmarshalJSONAPI extracts information from a resource node and populates itself.

type ResourceMarshaler

type ResourceMarshaler interface {
	// MarshalJSONAPI marshals this instance into a resource node.
	MarshalJSONAPI() (*Resource, error)
}

ResourceMarshaler can marshal its information into a resource node. Structs that implement this interface can override the default marshaling process.

type ResourceUnmarshaler

type ResourceUnmarshaler interface {
	// UnmarshalJSONAPI extracts information from a resource node and populates itself.
	UnmarshalJSONAPI(*Resource) error
}

ResourceUnmarshaler can extract information from a resource node and populate itself. This is an escape hatch from the default unmarshal process.

type URLResolver

type URLResolver interface {
	// ResolveURL creates a url based on the provided request context and base URL.
	ResolveURL(ctx RequestContext, baseURL string) string
}

URLResolver resolves urls based on the JSON:API request context.

type URLResolverFunc

type URLResolverFunc func(RequestContext, string) string

URLResolverFunc functions implement URLResolver.

func DefaultURLResolver

func DefaultURLResolver() URLResolverFunc

DefaultURLResolver returns a resolver that generates the following urls based on the request context (given a base url):

":base/:type" for search, create
":base/:type/:id" for fetch, update, delete
":base/:type/:id/relationships/:ref" for fetchRef
":base/:type/:id/:ref" for fetchRelated

func (URLResolverFunc) ResolveURL

func (fn URLResolverFunc) ResolveURL(ctx RequestContext, baseURL string) string

ResolveURL creates a url based on the provided request context and base URL.

type Version

type Version string

Version contains information regarding the JSON:API version supported by the server.

func (Version) MarshalJSON

func (v Version) MarshalJSON() ([]byte, error)

MarshalJSON serializes the version into JSON.

func (Version) Value

func (v Version) Value() string

Value returns the associated version, or the last version supported by this library if zero-value.

Directories

Path Synopsis
extra
internal
log

Jump to

Keyboard shortcuts

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