Examples
This page demonstrates common integration patterns with popular frameworks.
Express
import express from "express";
import {
serialize,
serializeErrors,
belongsTo,
createResource,
} from "@emelon/jsonapi-nano";
import { fieldsFromQuery } from "@emelon/jsonapi-nano/query";
const app = express();
const PORT = 3000;
const mockAuthors = [{ id: "99", name: "Jane Doe" }];
const mockArticles = [
{
id: "1",
title: "Why local testing matters",
body: "Using yalc is easy.",
authorId: "99",
},
];
// Resource schemas
const authorResource = createResource("authors", {
attributes: (a) => ({ name: a.name }),
});
const articleResource = createResource("articles", {
attributes: (a) => ({ title: a.title, body: a.body }),
relationships: (a) => ({
author: belongsTo("authors", a.authorId),
}),
});
app.get("/articles", (req, res) => {
const jsonapiResponse = serialize(mockArticles, articleResource, {
context: req,
links: { self: `${req.protocol}://${req.get("host")}${req.originalUrl}` },
include: {
author: [mockAuthors, authorResource],
},
fields: fieldsFromQuery(req.query),
});
res.setHeader("Content-Type", "application/vnd.api+json");
res.json(jsonapiResponse);
});
app.listen(PORT);
Fastify
import Fastify from "fastify";
import { serialize, createResource } from "@emelon/jsonapi-nano";
import { fieldsFromQuery } from "@emelon/jsonapi-nano/query";
const fastify = Fastify();
const articleResource = createResource("articles", {
attributes: (a) => ({ title: a.title, body: a.body }),
});
fastify.get("/articles/:id", async (request, reply) => {
const article = {
id: request.params.id,
title: "Hello World",
body: "Fastify example",
};
reply.header("Content-Type", "application/vnd.api+json");
return serialize(article, articleResource, {
fields: fieldsFromQuery(request.query as Record<string, unknown>),
});
});
await fastify.listen({ port: 3000 });
NestJS
import { Controller, Get, Req, HttpCode, Injectable } from "@nestjs/common";
import { Request } from "express";
import { serialize, createResource, belongsTo } from "@emelon/jsonapi-nano";
import { fieldsFromQuery } from "@emelon/jsonapi-nano/query";
const authorResource = createResource("authors", {
attributes: (a) => ({ name: a.name }),
});
const articleResource = createResource("articles", {
attributes: (a) => ({ title: a.title, body: a.body }),
relationships: (a) => ({ author: belongsTo("authors", a.authorId) }),
});
@Injectable()
export class ArticlesService {
getArticles() {
return [
{
id: "1",
title: "NestJS Integration",
body: "Super clean presentation layers.",
authorId: "10",
},
];
}
getAuthors() {
return [{ id: "10", name: "Nest Developer" }];
}
}
@Controller("articles")
export class ArticlesController {
constructor(private readonly articlesService: ArticlesService) {}
@Get()
@HttpCode(200)
findAll(@Req() req: Request) {
const articles = this.articlesService.getArticles();
const authors = this.articlesService.getAuthors();
// NestJS route handlers will respect your returned object
// and stream it down as valid JSON automatically
return serialize(articles, articleResource, {
context: req,
include: {
author: [authors, authorResource],
},
fields: fieldsFromQuery(req.query),
});
}
}
See the Examples for more examples.