This package provides support for working with JSON:API in Koa, taking all guesswork out of the equation.
npm i koa-jsonapi-zod
pnpm add koa-jsonapi-zod
In order to serialize your entities into valid JSON:API responses, you have to set up a serialize manager which is composed of several entity serializers. You also have access to several utility functions meant for parsing incoming requests, as well as a middleware which takes care of handling requests and responses.
For a complete example, have a look under examples/complete.
This package exports two middlewares, jsonApiRequestMiddleware
and jsonApiErrorMiddleware
.
The former takes care of validating incoming requests and formatting responses accordingly. You can exclude specific paths from being handled by the middleware (e.g. RPC endpoints). This middleware should be registered as early as possible.
The error middleware is a convenience middleware which traps all errors and creates appropriate error responses. You can also supply a logger function as an option, which allows you to log specific errors. This middleware should be registered right after the request middleware.
For more details, see index.ts
in the complete example.
In some instances your serializers might require context about a request. One instance of this is where you want to expose specific fields of an entity only when the user has permission to access these. In that case you should define your serialization context first:
type SerializerContext = {
permissions?: string[];
};
Each serializer can define its own context, and it will be accessible separately for each serializer. Since the context
is always an optional property, you can then perform checks like this in e.g. your getAttributes()
implementation:
const attributes: Record<string, unknown> = {
foo: "bar",
baz: "bat",
};
if (options.context?.permissions?.includes("read:secret")) {
attributes.secret = "super secrtet information";
}
You can then serialize your entities in the following way:
serializeManager.createResourceDocument("my_entity", entity, {
context: {my_entity: {permissions: "foo"}},
});
Additionally, when you define a relationship in a serializer as an entity, you can pass down additional context which will be merged with the parent context.
You can add filters to list handlers as well. JSON:API does not define the structure of filters itself, except that the
filter
property should be used for this. Whether you make that property an object or a plain string is up to you.
Simply provide a Zod
schema to the filterSchema
property, and you will get a filter
property on the result back.
Similar to filters you can also supply a pageSchema
property, which will result in a page
result.