@dinevillar/adonis-json-api-serializer

AdonisJS Agnostic JSON Rest Api Specification Wrapper

Downloads in past

Stats

StarsIssuesVersionUpdatedCreatedSize
@dinevillar/adonis-json-api-serializer
1620.5.75 years ago5 years agoMinified + gzip package size for @dinevillar/adonis-json-api-serializer in KB

Readme

Installation

npm i @dinevillar/adonis-json-api-serializer

Setup

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

Usage

model.toJSON():

getUser({request, response}) {
  const user = await User.find(1);
  response.send(user.toJSON());
};

with relations:

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());
};

Record Browser in your Controllers

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:

Exceptions

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);
}

Validator

Sample Validator (see examples)
```` javascript 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
const {JsonApiSerializer} = use('JsonApi');
const user = await User.find(1);
JsonApiSerializer.serialize("user", user);