Package Exports
- api
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (api) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
🚀 api
Automatic SDK generation from an OpenAPI definition.
Installation
npm install api --save
Usage
Using api
is as simple as supplying it an OpenAPI and using the SDK as you would any other!
const sdk = require('api')('https://raw.githubusercontent.com/readmeio/oas/master/packages/examples/3.0/json/petstore.json');
sdk.listPets().then(res => res.json()).then(res => {
console.log(`My pets name is ${res[0].name}!`);
});
The OpenAPI definition is automatically downloaded, cached, and transformed into a chainable fetch
Promise that you can use to make API requests.
Authentication
api
supports API authentication through an .auth()
method that you can chain to your requests, as such:
sdk.auth('myApiToken').listPets().then(...);
With the exception of OpenID, it supports all forms of authentication supported by the OpenAPI specification! Just give .auth()
your credentials and it'll figure out how to use it according to the API you're using.
For example:
- HTTP Basic auth:
sdk.auth('username', 'password')
- Bearer tokens (HTTP or OAuth 2):
sdk.auth('myBearerToken')
- API Keys:
sdk.auth('myApiKey')
Parameters and Payloads
When supplying parameters and/or request body payloads to an API request, you don't need to explicitly define what goes where since the API definition contains all that information. All you need to do is supply either one or two objects:
body
: This will contain all data required for a request body payload for a POST, PUT, etc. request. It can either be an array or an object — whichever you need to use the API operation you're using.metadata
: This is an object where all parameters (path, query, header, cookie) go. Again, don't worry about telling the SDK that a path parameter is for the path, that's all handled for you.
For example, if you wanted to make a simple GET request:
sdk.showPetById({ petId: 1234 }).then(...)
Since petId
matches up with the petId
path parameter, the SDK here will issue a GET request against /pets/1234
.
What about a POST request?
sdk.createPets({ name: 'Buster' }).then(...)
Since name
here would correspond on createPets
to request body payload, this will issue a POST request against /pets
to make a new pet named "Buster".
What about operations that require both? Well you can mix them too!
sdk.updatePet({ name: 'Buster 2' }, { petId: 1234 }).then(...)
Since we've supplied two objects here, the SDK automatically knows that you're supplying both a body
and metadata
, and can make a PUT request against /pets/1234
for you.
What about a multipart/form-data
request? That works too, and you don't even have to worry about the fun of multipart boundaries!
sdk.uploadFile({ file: '/path/to/a/file.txt' }).then(...)
You can also give it a stream and it'll handle all of the hard work for you.
sdk.uploadFile({ file: fs.createReadStream('/path/to/a/file.txt') }).then(...)
HTTP requests
If the API you're using doesn't have any documented operation IDs, you can make requests with HTTP verbs instead:
sdk.get('/pets/{petId}', { petId: 1234 }).then(...)
The SDK supports GET, PUT, POST, DELETE, OPTIONS, HEAD, and TRACE requests.
Server configurations
If the API you're using offers alternate server URLs and server variables in its servers
definition you can supply this to the SDK with .server()
:
sdk.server('https://{region}.api.example.com/{basePath}', {
name: 'eu',
basePath: 'v14',
});
sdk.get('/pets').then(...)
When your request is executed it will be made to https://eu.api.example.com/v14/pets
. Alternatively if you don't want to deal with URL templates you can opt to pass the full URL in instead:
sdk.server('https://eu.api.example.com/v14');
How does it work?
Behind the scenes, api
will:
- Download the supplied OpenAPI definition, either from a publically accessible URLs or an absolute/relative path.
- Dereference the definition so it's easier for us to handle.
- Hash the definition and cache it into a directory in
node_modules/.cache/api/
. - Process the definition and instantiate chainable methods for HTTP verbs and operation IDs the API contains via a JS Proxy.
On subsequent requests, api
will look in its cache, and if the supplied definition exists there, it'll retrieve it from the cache instead of re-retrieving it again.
Interested in contributing?
Welcome! Have a look at CONTRIBUTING.md.
FAQ
Does this support YAML definitions?
Yes! YAML definitions will be automatically converted to JSON before they're cached and loaded as an SDK.
Does this support Swagger 2.0 definitions?
At the moment it does not. If you wish to use an API that has a Swagger 2.0 file, you'll need to first convert it to an OpenAPI 3 definition.
Does this support traditional OAuth 2 flows of creating tokens?
Not yet, unfortunately. For APIs that use OAuth 2, you'll need a fully-qualified token already for api
to make requests.
Does this support APIs that use multiple forms of authentication on a single request?
Not yet! This is something we're thinking about how to handle, but it's difficult with the simple nature of the .auth()
method as it currently does not require the user to inform the SDK of what kind of authentication scheme the token they're supplying it should match up against.
Will this work in browsers?
Not at the moment as the library requires some filesystem handling in order to manage its cache state, but it's something we're actively thinking about. If you'd like to help us out in making this compatible with browsers we'd love to help you out on a pull request.
Will this validate my data before it reaches the API?
Not yet! This is something we've got planned down the road.
Does this support OpenAPI definitions that require authentication to download?
Not yet! The URL that you give the module must be publicy accessible. If it isn't, you can download it to your computer/server and then use the absolute path to that file instead.
const sdk = require('api')('/path/to/downloaded.json');
How do I access the Response object (for status and headers)?
By default we parse the response based on the content-type
header for you. You can disable this by doing the following:
sdk.config({ parseResponse: false });