This library is a Go implementation of the Json:API v1.1 spec for both clients and servers.
Project goals:
- Full marshalling and unmarshalling that works with
json.Marshalandjson.Unmarshal. - Spec-compliant validation with clear, actionable errors.
- Type-safe resources and attributes using generics, with first-class support for nullable values and sparse fields.
Features:
- Works with
json.Unmarshalandjson.Marshal. - Strictly typed attributes using Go generics.
- Support for nullable values and distinguishing “absent” from “present but null”.
- Validation powered by ProtoValidate (Go package:
proto.zip/studio/validate). - Errors that comply with the Json:API error object format.
- Validation rules that can vary by HTTP method.
Supported Json:API v1.1 features:
- Request and response compliance checking.
- Sparse field sets, filters, sorting.
- Error objects and version/meta information.
- Include and compound documents.
- Links (nullable, string, and structured) and relationships (including nullable).
- Extensions and @-members (captured and round-tripped).
You can use any extension or profile. The following profile is directly supported:
go get proto.zip/studio/jsonapiSimple usage:
package main
import (
"context"
"fmt"
"proto.zip/studio/jsonapi"
"proto.zip/studio/validate/pkg/rules"
)
func main() {
attributesRuleSet := jsonapi.Attributes().
WithJson().
WithKey("title", rules.String().Any())
ruleSet := jsonapi.NewSingleRuleSet[map[string]any]("articles", attributesRuleSet)
ctx := context.Background()
doc := `{"data":{"type":"articles","id":"1","attributes":{"title":"Hello"}}}`
envelope, errs := ruleSet.Apply(ctx, doc)
if errs != nil {
fmt.Println(errs)
return
}
fmt.Println(envelope.Data.Attributes["title"]) // Hello
}A nil value is different in Json:API than a value that is not present.
When patching an attribute, an explicit null means “remove this attribute.” Omitting the member means “leave it unchanged.” The same applies to relationships. In responses, a nil link or relationship means the server is explicitly indicating it is not present.
The library provides custom types with MarshalJSON and UnmarshalJSON so you can distinguish absent from null. When unmarshaling, Datum.Fields is set to the list of attribute names that appeared in the JSON, so you can tell which attributes were explicitly set (including to empty or null) and which were omitted.
This package follows conventional Go versioning. Any version before 1.0.0 is considered unstable and the API may change. Backwards incompatible changes in unstable releases will, when possible, deprecate first and be documented in release notes.
For community support, join the ProtoStudio Discord Community. For commercial support, contact Curioso Industries.