Abstract
JSON:API requires more than a JSON-shaped response. Resource identity, relationship linkage, included resources, and links have distinct meanings. ts-japi represents these concerns with composable TypeScript serializers so an API can share document construction across handlers and data sources. Its published package has no runtime dependencies. [1][2]
1. The problem
A controller that constructs a response by hand has to preserve the same rules every time it includes another resource. JSON:API compound documents require linkage to primary data and restrict duplicate resource objects. A nested JavaScript object and a valid compound document are not interchangeable. [3]
The maintenance problem grows when several endpoints return the same resource with different includes, links, or metadata. Repeating serialization logic in handlers makes each endpoint another place to update when a resource's representation changes. ts-japi puts that representation beside a reusable resource serializer. [1]
2. The design
Serializer handles the primary resource. Relator connects a resource to an asynchronously fetched related value and its serializer; Linker, Metaizer, and Paginator define the corresponding document elements. Include paths or a bounded depth control traversal into related resources. A serializer getter can break circular construction dependencies. [1]
The API uses generics for resource data and relationship callbacks. Separate error and polymorphic serializers cover error documents and mixed resource types. These facilities organize response construction; the application still owns authorization, data fetching, and the cost of fetching a relationship. [1]
3. Alternatives
The relevant distinction is the requirement each approach serves.
3.1 Hand-written JSON:API responses
- The constraint
- Every endpoint must preserve identity, linkage, and inclusion rules while constructing its own objects. A missing relationship can make an otherwise valid JSON response an invalid compound document. [3]
- Our approach
- Reusable serializers and relators centralize document construction and resource traversal. [1]
- The tradeoff
- For a small endpoint with a fixed response, a hand-written object and focused specification tests may be easier to maintain.
3.2 jsonapi-serializer
- The constraint
- jsonapi-serializer already supports relationships, included resources, links, and metadata. Its documented interface organizes those through nested option objects; it is not missing the JSON:API relationship model. [4]
- Our approach
- ts-japi offers a different composition model: resource-typed serializers and explicit asynchronous Relator callbacks, with separate link and metadata objects. [1]
4. Boundaries & adoption
Deep relationship traversal can multiply database work. Set inclusion rules deliberately and arrange batching or caching in the data layer where needed. A serializer is not an ORM or a query optimizer. [1]
The default declared JSON:API version is 1.0. Do not infer complete support for every JSON:API 1.1 extension from the project name. Use the options and behavior of the pinned implementation, and test the contract your API promises. This note makes no exclusivity claim about TypeScript or recursive inclusion.
5. References
Sources reviewed September 12, 2026. Mathematic source links retain the reviewed revision.
- [1]ts-japi: serialization, composition, includes, and scope Mathematic Inc. · 32bb6daf
- [2]ts-japi: package manifest Mathematic Inc. · 32bb6daf
- [3]JSON:API: compound document requirements jsonapi.org
- [4]