PAPI: Builder🔗
PAPI allows API endpoints to be defined as simply or robustly as needed. An expanded example of the JSONPlaceholder API's /albums
endpoint is demonstrated below:
Albums endpoint from JSONPlaceholder
import { papi } from '@studiokeywi/papi';
const albumShape/* (1)! */ = { userId: 0/* (2)! */, id: 0, title: '' };
const errShape = {};
const photoShape = { albumId: 0, id: 0, title: '', url: '', thumbnailUrl: '' };
const apiCaller = papi('https://jsonplaceholder.typicode.com')
.path/* (3)! */('albums', $albums =>
$albums
.get/* (4)! */([albumShape], $get => $get.error/* (5)! */(errShape).queryOpt(albumShape))
.post(albumShape, $post => $post.bodyOpt(albumShape).error(errShape))
.slug/* (6)! */($albumId =>
$albumId
.get(albumShape, $get => $get.error(errShape))
.delete({}, $del => $del.error(errShape))
.patch(albumShape, $patch => $patch.bodyOpt(albumShape).error(errShape))
.put(albumShape, $put => $put.bodyOpt(albumShape).error(errShape))
.path('photos', $photos => $photos.get([photoShape], $get => $get.error(errShape)))
)
)
.build();
- Commonly used shapes can be defined ahead of time if desired. See the specifity of responses section of the notes for more on response shapes
- PAPI infers the types inside an object, so placeholders like
0
and''
work - Nested routes are defined with builder functions inside of
.path()
- Endpoint functions provide shapes for the response type, and optional builder functions to modify how to interact with the endpoint/how it responds. PAPI supports
DELETE
,GET
,PATCH
,POST
, andPUT
- Endpoint builder functions can clarify how interacitons with an API work when passing data (as a body or via query parameters) and with known error shapes
- Paths that are used as slugs for values are defined with
.slug()
papi
🔗
The papi
function takes two arguments; the first is a string representing the base URL for an API, and the second is an optional shape used as the base shape of the builder. The second argument primarily used for internally updating the state of the builder, but is exposed for advanced/edge use cases as well as for possible feature enhancements in the future
Tip
See the composing builders and declarative building sections of the notes for more on advanced usage of the papi
function
General Functions🔗
The .build
function is used to create an API Caller tool for calling API endpoints. It accepts a single optional argument providing configuration to the built API Caller
Tip
The following configuration options are available:
Automatically attach Bearer [apiKey]
values to the Authorization header
Warning
As a reminder, PAPI does not enforce or guarantee response shapes. It is intended as an augment to developer experience
Convert the API caller tool into a temporary API caller
See the TAPI section of the notes for more information
The .path
function defines a subpath for the current level of the builder. Typically, the top level of a builder will include nothing but paths, and paths may be nested arbitrarily deep. It accepts two arguments; The first is a string of the path segment, and the second is a nested builder which is used to define the shape of the path
The .shared
function defines multiple subpaths for the current level of the builder. This is similar to a .slug
except where the values are known ahead of time instead of arbitrary values. It accepts two arguments; The first is an array of strings representing each path segment, and the second is a nested builder which is used to define the shape of each path
The .slug
function defines a subpath where the actual pathname is not fixed but may be replaced by a given value. Typically this is seen with ID values representing a path segment as opposed to using a query parameter to provide the ID. It accepts a single argument, which is a nested builder that defines the shape of the path represented by the slug value
Endpoint Functions🔗
The following functions follow a similar pattern and are used for defining endpoint responses:
The .delete
function defines the shape of the responses from calling an endpoint with an HTTP DELETE request. It accepts two arguments; The first is the shape of the response from the API, and the second is an optional endpoint builder that customizes the behavior of requesting/shape of responses from the API
The .get
function defines the shape of the responses from calling an endpoint with an HTTP GET request. It accepts two arguments; The first is the shape of the response from the API, and the second is an optional endpoint builder that customizes the behavior of requesting/shape of responses from the API
The .patch
function defines the shape of the responses from calling an endpoint with an HTTP PATCH request. It accepts two arguments; The first is the shape of the response from the API, and the second is an optional endpoint builder that customizes the behavior of requesting/shape of responses from the API
The .post
function defines the shape of the responses from calling an endpoint with an HTTP POST request. It accepts two arguments; The first is the shape of the response from the API, and the second is an optional endpoint builder that customizes the behavior of requesting/shape of responses from the API
The .put
function defines the shape of the responses from calling an endpoint with an HTTP PUT request. It accepts two arguments; The first is the shape of the response from the API, and the second is an optional endpoint builder that customizes the behavior of requesting/shape of responses from the API
Endpoint Builders🔗
The endpoint functions all can accept an optional endpoint builder function as the second argument. These can be used to provide more specific/nuanced information about how APIs should be called and the data they return:
The .bodyOpt
function is used to declare that an endpoint can receive some body of data. It accepts two arguments, an object defining the shape of accepted data for the endpoint and an optional object defining the shape the API responds with when sending a body of data
The .bodyReq
function is used to declare that an endpoint must receive some body of data. It accepts two arguments, an object defining the shape of accepted data for the endpoint and an optional object defining the shape the API responds with when sending a body of data
The .error
function defines the shape of the response for a given endpoint's error. When provided, the built API caller will return the union of the relevant response shape and the error shape to indicate that error responses must be handled. It accepts a single argument defining the shape of error responses
Tip
See the type narrowing section of the notes for more handling error response shapes
The .queryOpt
function defines query parameters that may be appended to an endpoint request. It accepts two arguments, an object defining the shape of query parameters that may be used when calling an endpoint, and an optional object defining the shape the API responds with when sending query parameters
The .queryReq
function defines query parameters that must be appended to an endpoint request. It accepts two arguments, an object defining the shape of query parameters that must be used when calling an endpoint, and an optional object defining the shape the API responds with when sending query parameters
Tip
See the response priority section of the notes to see how PAPI determines the shape of an API response when providing endpoint builders