openapi-frontenddeprecated

JavaScript library for consuming OpenAPI-enabled APIs

Usage no npm install needed!

<script type="module">
  import openapiFrontend from 'https://cdn.skypack.dev/openapi-frontend';
</script>

README

OpenAPI Frontend

Build Status Dependencies npm version License Sponsored

JavaScript client library for consuming OpenAPI-enabled APIs

Also see: openapi-backend

Features

  • Create API clients by describing them in OpenAPI specification and importing them via YAML or JSON files or by just passing an object
  • Call API operations with your preferred syntax:
    • client.updatePet(1, pet) - operation methods
    • client.query('updatePet', 1, pet) - query method
    • client.put('/pets/1', pet) - axios method aliases
    • client({ method: 'put', url: '/pets/1', data: pet }) - axios basic
  • Built on top of the robust axios JavaScript library
  • Isomorphic, works both in browser and Node.js
  • Option to mock API backends using openapi-backend
  • TypeScript types included

Quick Start

npm install --save openapi-frontend

With promises / CommonJS syntax:

const OpenAPIFrontend = require('openapi-frontend').default;

const api = new OpenAPIFrontend({ definition: 'https://example.com/api/openapi.json' });
api.init()
  .then(client => client.getPetById(1))
  .then(res => console.log('Here is pet id:1 from the api', res));

With async-await / ES6 syntax:

import OpenAPIFrontend from 'openapi-frontend';

const api = new OpenAPIFrontend({ definition: 'https://example.com/api/openapi.json' });
api.init();

async function createPet() {
  const res = await api.client.createPet({ name: 'Garfield' });
  console.log('Pet created', res);
}

Calling API operations

After initalizing OpenAPIFrontend, an instance of OpenAPIClient is exposed.

Example:

const api = new OpenAPIFrontend({ definition: 'https://example.com/api/openapi.json' });
api.init().then((client) => {
  // ...
});

Each instance of OpenAPIClient is an axios instance extended with extra methods for calling API operations.

There are four different ways to call API operations with OpenAPIClient:

  1. client.updatePet(1, pet) - operation methods
  2. client.query('updatePet', 1, pet) - query method
  3. client.put('/pets/1', pet) - axios method aliases
  4. client({ method: 'put', url: '/pets/1', data: pet }) - axios basic

Example:

const api = new OpenAPIFrontend({
  definition: {
    openapi: '3.0.1',
    info: {
      title: 'Petstore',
      version: '1.0.0',
    },
    servers: [{ url: 'http://localhost:9000' }], // petstore api
    paths: {
      '/pets': {
        get: {
          operationId: 'getPets',
          responses: {
            200: { description: 'ok' },
          },
        },
      },
    },
  },
});

async function test() {
  const client = await api.init();

  const res1 = await client.getPets();
  const res2 = await client.query('getPets');
  const res3 = await client.get('/pets');
  const res4 = await client({ method: 'get', url: '/pets' });

  assert.deepEqual(res1.data, res2.data);
  assert.deepEqual(res1.data, res3.data);
  assert.deepEqual(res1.data, res4.data);
}
test();

Operation methods

OpenAPIFrontend operation methods take in 3 types of arguments:

operationId(...pathParams, data?, config?)

Path params

The first arguments are the path parameters of the operation in the order they appear in the URL.

Operation getPetOwner: GET /pets/{petId}/owners/{ownerId} can be called with:

client.getPetOwner(petId, ownerId)

Data / Payload

The first argument after all path parameters have been supplied is the data argument. This allows you to send request body payloads with your API call.

Operation updatePet: PUT /pets/{petId} can be called with:

client.updatePet(petId, { name: 'Odie' })

If there are no path parameters for the operation, the data argument will be the first argument.

client.createPet({ name: 'Garfield' })

Config object

The argument after the data argument is the config object.

The config object is an AxiosRequestConfig object. You can use it to override axios request config parameters, such as headers, params, timeout, withCredentials and many more.

Operation searchPets: GET /pets?query=dog can be called with:

client.searchPets(null, { params: { query: 'dog' } });

Any arguments passed after the config object will cause OpenAPI backend to throw an Error.

Mocking with OpenAPI Backend

Combining OpenAPI Frontend with openapi-backend allows you to easily mock your API backend while developing client applications.

OpenAPI Backend uses OpenAPI examples objects and JSON Schema definitions to mock responses using your OpenAPI specification document. Routing and input validation is also automatically enabled when using the handleRequest() method.

Example:

import OpenAPIFrontend from 'openapi-frontend';
import OpenAPIBackend from 'openapi-backend';

const definition = './openapi.yml';

// create the mock API
const mockApi = new OpenAPIBackend({ definition });
mockApi.register({
  notFound: () => [404, { err: 'not found' }],
  validationFail: (c) => [400, { err: c.validation.errors }],
  notImplemented: (c) => {
    const { status, mock } = mockApi.mockResponseForOperation(c.operation.operationId);
    return [status, mock];
  },
});

// create the client with a mockHandler using OpenAPIBackend.handleRequest()
const api = new OpenAPIFrontend({
  definition,
  mockHandler: (config) =>
    mockApi.handleRequest({
      method: config.method,
      path: config.url,
      query: config.params,
      body: config.data,
      headers: config.headers,
    }),
});

// init both the mock api backend and the client
mockApi.init()
  .then(() => api.init())
  .then((client) => {
    // all calls using OpenAPIClient will now be handled by the mocked OpenAPI backend
  });

Contributing

OpenAPI Frontend is Free and Open Source Software. Issues and pull requests are more than welcome!

The Chilicorn