npm i @dinevillar/adonis-json-api-serializer
Create/edit config/jsonApi.js
.
module.exports = {
"globalOptions": {
"convertCase": "snake_case",
"unconvertCase": "camelCase"
},
// Register JSON API Types here..
"registry": {
"user": {
"model": 'App/Models/User'
"structure": {
"links": {
self: (data) => {
return '/users/' + data.id
}
},
"topLevelLinks": {
self: '/users'
}
}
}
}
};
Add as provider (start/app.js)
const providers = [
'@dinevillar/adonis-json-api-serializer/providers/JsonApiProvider'
]
Add to your Models
static get Serializer() { return 'JsonApi/Serializer/LucidSerializer'; // Override Lucid/VanillaSerializer };
Add as named Middleware in start/kernel.js
const namedMiddleware = { jsonApi: 'JsonApi/Middleware/Specification' };
Use in your routes
// All request and response to /user must conform to JSON API v1 Route.resource('user', 'UserController') .middleware(['auth', 'jsonApi'])
You can use the "cn" and "ro" schemes of the middleware.
- Adding "cn" (jsonApi:cn) will allow middleware to check for Content Negotiation
- Adding "ro" (jsonApi:ro) will allow middleware to check if request body for POST and PATCH conforms with JSON API resource object rules
- Adding "ro" (jsonApi:ro) also will automatically deserialize resource objects.
- If none is specified then both will be applied
getUser({request, response}) {
const user = await User.find(1);
response.send(user.toJSON());
};
config/jsonApi.js
"registry": { "company": { "model": 'App/Models/Company', "structure": { id: "id", links: { self: (data) => { return '/companies/' + data.id } } } } "user": { "model": 'App/Models/User', "structure": { "links": { self: (data) => { return '/users/' + data.id } }, "relationships": { company: { type: 'company', links: { self: '/companies' } } } "topLevelLinks": { self: '/users' } } } }
App/Models/Company
static get Serializer() { return 'JsonApi/Serializer/LucidSerializer'; };
App/Models/User
static get Serializer() { return 'JsonApi/Serializer/LucidSerializer'; };
Somewhere:
getUser({request, response}) { const user = await User.find(1); await user.load('company'); // load relation response.send(user.toJSON()); };
const Company = use('App/Models/Company')
const JsonApiRB = use('JsonApiRecordBrowser');
const companies = await JsonApiRB
.model(Company)
.request(request.get()) //handle request
.paginateOrFetch();
response.send(companies.toJSON());
The record browser supports:
You can use JsonApi to handle errors and be able to return valid JSON Api error responses.
Create a global ehandler using adonis make:ehandler
and use JsonApi in handle()
function.
See examples/Exception/Handler.js
async handle(error, options) {
JsonApi.handleError(error, options);
}
Sample Validator (see examples)
const {formatters} = use('Validator'); const JsonApi = use('JsonApi'); class UserValidator { get rules(){ return { 'username': 'required|accepted|max:255', 'contact_number': 'required|accepted|max:50', 'email': 'required|email|unique:companies,email|max:100' } }
get formatter() {
return formatters.JsonApi;
}
async fails({errors}) {
for (const error of errors) {
const jsonError = JsonApi.JSE.UnprocessableResourceObject.invoke();
jsonError.detail = error.detail;
jsonError.source = error.source;
JsonApi.pushError(jsonError);
}
return this.ctx.response
.status(JsonApi.getJsonErrorStatus())
.send(JsonApi.getJsonError());
}
}
#### Serializer Library:
> [Serializer functions](https://github.com/danivek/json-api-serializer/blob/master/lib/JSONAPISerializer.js)
``` javascript
const {JsonApiSerializer} = use('JsonApi');
const user = await User.find(1);
JsonApiSerializer.serialize("user", user);