npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

oa-client

v0.10.0

Published

Harness all the power of your backend's OpenAPI spec files by generating a client object in a few lines.

Downloads

103

Readme

oa-client

Harness all the power of your backend's OpenAPI v3 spec files by generating a client object in a few lines

Features

🚀 Creates at runtime a client object in a few lines (read more in Getting Started)

// Creation
import { createClient } from 'oa-client';
const client = createClient(specs, callers, {
  origin: 'https://my.api.com',
  validationLevel: 'error',
});
// Usage
client[/* path */][/* method */](/* optional params */).then(apiResponse => { /* ... */ })

🚀 Optionally throws for invalid path, query, or body

# OpenAPI specs
paths:
  /users/{userId}:
    get:
      parameters:
        - in: path
          name: userId
          schema:
            type: integer
client["/users/{userId}"].get({ pathParams: { userId: "john" } });
// throws [oa-client:103] Data does not pass validation: data.userId should be an integer

🚀 Compiles the path and query params

client["/new-user/{job}"].post({
  pathParams: { job: "director" },
  queryParams: { name: "Gaspar Noé" },
});
// calls /new-user/director?name=Gaspar+No%C3%A9

Getting started

1. Install the package

npm install --save oa-client

2. Import the package

This package is isomorphic: it can be used both as an ESM or a CommonJS

// ok
import { createClient } from "oa-client";
// also ok
const { createClient } = require("oa-client");

3. Have somewhere your OpenAPI specs as a JS object

You don't need to add anything compared to normal specs, except for an optional .paths[path][method]['x-type'], that defines the caller, more on them below. If this key is omitted, its value defaults to the request type (e.g. "get" or "post").

Note that oa-client does not resolve specs for you. If you have $refs, you should use a package like json-schema-ref-parser to resolve them.

const specs = {
  openapi: "3.0.0",
  info: {
    /* ... */
  },
  paths: {
    "/users/{userId}": {
      get: {
        "x-type": "authorizedGet", // will use the "authorizedGet" caller
        parameters: [
          {
            in: "path",
            name: "userId",
            required: true,
            schema: {
              type: "integer",
            },
          },
        ],
        responses: {
          /* ... */
        },
      },
    },
    "/status": {
      get: {
        // no x-type -> will use the "get" caller
        responses: {
          /* ... */
        },
      },
    },
  },
};

4. Write your callers

These are generic functions that handle requests at the HTTP level.

They are not handled by this package, because they can be very different from one codebase to another; but usually you don't have to write a lot of them.

url is an URL, body is a plain JS object.

const callers = {
  get: async (url) => {
    const resp = await fetch(url);
    const json = await resp.json();
    return json;
  },
  authorizedGet: async (url) => {
    const headers = new Headers();
    headers.append("Content-Type", "application/json");
    headers.append("Authorization", `Bearer ${localStorage.token}`);
    const resp = await fetch(url, { headers });
    const json = await resp.json();
    return json;
  },
  authorizedPost: async (url, body) => {
    const headers = new Headers();
    headers.append("Content-Type", "application/json");
    headers.append("Authorization", `Bearer ${localStorage.token}`);
    const resp = await fetch(url, {
      method: "POST",
      headers,
      body: JSON.stringify(body),
    });
    const json = await resp.json();
    return json;
  },
};

5. Create your client

You do this once and client can be used in the rest of your code afterward.

origin defaults to specs.servers[0].url. Optional if it's defined, else required.

validationLevel is one of 'off' (default), 'warn', or 'error'. It checks the path params, the query params, and the body against the schema present in the specs.

const client = createClient(specs, callers, {
  origin: "https://my.api.com",
  validationLevel: "error",
});

6. Use your client

Thereafter, oa-client does all the work of building the full URL and validating input data for you!

In this example, this

const data = await client["/users/{userId}"].get({
  pathParams: { userId: 123 },
});

is equivalent to

const url = new URL("https://my.api.com/users/123");
const data = await callers.authorizedGet(url);

Differences with openapi-client

The openapi-client package is similar but accomplishes things differently.

openapi-client is a code generation package. You use it as a command line so that it consumes OpenAPI specs and outputs code that will call your server. It is not ideal because you don't own and control all of your code, and it adds complexity.

oa-client is simpler - it exposes createClient, a factory that take specs as input and builds the client at runtime. If your API updates, you don't have to write or generate a single line of code.

openapi-client handles all the HTTP calls and authentication for you. That can seem powerful, but actually the system is very rigid, even for small customizations, and doesn't cover all cases you'll face along the way.

In oa-client, you fully own your generic HTTP callers: you write them yourself, but you probably won't write more than five of them during your whole project lifetime: who needs more than get, post, authorized get, authorized post and file upload?

+-------------------------------+
| Written with <3 by Nino Filiu |
|  Contributions are welcomed!  |
+-------------------------------+
         \   ^__^
          \  (oo)\_______
             (__)\       )\/\
                 ||----w |
                 ||     ||