interface-norel
v1.0.10
Published
`interface` is a toolchain for building JSON:API-compliant APIs.
Downloads
3
Readme
documentation
interface
is a toolchain for building JSON:API-compliant APIs.
what is JSON:API
If you’ve ever argued with your team about the way your JSON responses should be formatted, JSON:API can help you stop the bikeshedding and focus on what matters: your application.
By following shared conventions, you can increase productivity, take advantage of generalized tooling and best practices. Clients built around JSON:API are able to take advantage of its features around efficiently caching responses, sometimes eliminating network requests entirely.
interface
provides the following features:
- generating API controllers from resources definitions.
- generating authentication handlers from authentication schemes definitions.
- generating OpenAPI definition and documentation for the API with schemas for request bodies and responses.
- generating ExpressJS router.
- generating clients with support to different target languages (see supported).
- API testing.
- API versioning.
building an API with interface
consists of the following:
- defining API resources using a dialect of JSON schema.
- implementing datasources.
- defining authentication schemes.
resources, authentication schemes and datasources are the trinity on top of which an interface
API is built.
creating an interface project
$> npx interface be [--starter <starter>] <name>
- : name of the interface project.
- : specifying a starter project instead of starting from scratch, defaulting to starter “default”
interface project directory structure
- resources: contains resource definitions.
- datasource: contains datasource implementations.
- controllers: where generated controllers reside.
- authentication:
- schemes: contains authentication scheme definitions.
- handlers: where generated authentication handlers reside.
- index.js: api entrypoint.
- interface.configuration.json: contains
interface
configuration. - interface.openapi.json: contains API OpenAPI definition of the
interface
API. - package.json: contains dependencies and useful scripts.
defining API resources
according to JSON:API, a resource object consists of the following:
- id
- type
- attributes
- relationships
see Resource Objects.
interface
uses JSON Schema capabilities to define resources.
to create a resource, run the following command substituting:
- with the resource type (e.g. user, post, comment)
- with the resource datasource (e.g. database, firebase, redis)
$> npx interface create resource <name> <datasource>
- usage
implementing API datasources
a datasource is a set of functions that executes CRUD logic for each resource, interface
relies on the datasources to read/write resources and resource relationships.
$> npx interface create datasource <name>
- usage
when creating a datasource, it will be added to the datasources folder, it looks like this
module.exports = {
name: "database",
/**
* create
* @param {*} identity
* @param {*} resource
* @param {*} attributes
* @param {*} relationships
* @param {*} options
*/
async create(identity, resource, attributes, relationships, options) {},
/**
* readOne
* @param {*} identity
* @param {*} resource
* @param {*} id
* @param {*} options
*/
async readOne(identity, resource, id, options) {},
/**
*
* @param {*} identity
* @param {*} resource
* @param {*} options
*/
async readMany(identity, resource, options) {},
/**
*
* @param {*} identity
* @param {*} resource
* @param {*} id
* @param {*} attributes
* @param {*} relationships
* @param {*} options
*/
async update(identity, resource, id, attributes, relationships, options) {},
/**
*
* @param {*} identity
* @param {*} resource
* @param {*} id
* @param {*} options
*/
async delete(identity, resource, id, options) {},
/**
*
* @param {*} identity
* @param {*} resource
* @param {*} id
* @param {*} relationship
* @param {*} value
* @param {*} options
*/
async createRelationships(identity, resource, id, relationship, value, options) {},
/**
*
* @param {*} identity
* @param {*} resource
* @param {*} id
* @param {*} relationship
* @param {*} value
* @param {*} options
*/
async updateToOneRelationship(identity, resource, id, relationship, value, options) {},
/**
*
* @param {*} identity
* @param {*} resource
* @param {*} id
* @param {*} relationship
* @param {*} value
* @param {*} options
*/
async updateToManyRelationship(identity, resource, id, relationship, value, options) {},
/**
*
* @param {*} identity
* @param {*} resource
* @param {*} id
* @param {*} relationship
* @param {*} value
* @param {*} options
*/
async deleteRelationships(identity, resource, id, relationship, value, options) {},
}
the datasource exposed functions are loaded by interface in the controllers and serializers to CRUD the data when need be. interface
takes care of parsing request bodies, path and query parameters for inclusion of related resource, sparse fieldsets, filtering, sorting and pagination and passing them as arguments to the datasource functions.
defining authentication schemes
interface
supports all authentication schemes defined in the OpenAPI specification (see security schemes).
$> npx interface create authentication <identifier>
- usage
when an authentication scheme is defined, it’s added to the authentication/schemes directory. the available defined authentication schemes are added to the API OpenAPI definition.
generating API OpenAPI definition
interface
allows you to generate an OpenAPI definition for your API.
$> npx interface generate definition
- usage
the command will create the file .openapi.json containing the OpenAPI definition, where is the name of the interface
project.
generating controllers
$> npx interface generate controllers [resource]
- usage
the command generates controllers for all the endpoints in the controllers directory.
generating authentication handlers
$> npx interface generate authentication [authentication]
- usage
the command generates authentication handlers in the authentication/handlers directory.
generating API client
$> npx interface generate client [--target <target>] [--output <output]
- usage
the command generates client code to interact with the API.
running and testing the API
after defining your resources, creating your datasources and defining your authentication schemes, you are ready to run and start testing your API to continue with the implementation.
$> npx interface generate
- usage
the generate command performs all the necessary generations (OpenAPI definition, controllers, authentication handlers, client). once generation is done, you can start listening and responding to requests.
const interface = require("interface");
const api = require("express")();
api.use(interface.router());
api.listen(process.env.PORT, () => {
console.log(`api listening on port ${process.env.PORT}`);
});
in the above snippet, we are using the ExpressJS router that interface
provides to us. the returned router looks into the generated OpenAPI definition and loads controllers for each endpoint, taking into consideration:
- deserialization of requests.
- validation of requests.
- dependency injection of serializer, resource definition and datasource implementation, so that they are available to subsequent middlewares.
- loading the controller.
- serialization of responses.
- error handling.
API versioning
an API is not necessarily a still artifact, resource definitions can be altered or removed to accomodate changes in business logic and so applies to datasources and authentication schemes. thus, we need to have means to version our API, which is two folds:
- handling codebase breaking changes.
- communicating API version with the client.
handling codebase breaking changes
API versioning makes sense for breaking changes, a breaking change is defined as:
- removing a resource.
- removing a resource’s attribute.
- making a resource’s attribute required.
- removing a resource’s relationship.
interface
can detect breaking changes.
to list breaking changes run:
$> npx interface change status
to incorporate the list of breaking changes into a new version, run:
$> npx interface change apply
the command creates a new entry in the versions
directory, when receiving requests, interface
router takes care of dispatching the request to the controller in the corresponding version.
communicating API version with the client
configuration
the interface.configuration.json
file is used to set project-wide configuration.
| key | description | | | --- | --- | --- | | servers | list of OpenAPI servers objects that will be injected in the generated OpenAPI definition. | | | pagination | pagination configuration. | | | pagination.strategy | setting pagination strategy. | | | versioning | versioning configuration. | | | versioning.strategy | setting versioning strategy. | |