README
Website · Installation · Configuration
Benefits
- Composition API
- Extremely customizable
- Plugins and Middlewares systems give you total control
Simple Example
const { createClient } = require("dvori");
const client = createClient();
const { status, data } = await client.get({ url: "https://www.reddit.com/r/sausagetalk/new.json" });
Documentation
Install
Use the package manager npm to install dvori.
npm install dvori
Why
We needed a flexible API client that would allow use to make requests to multiple 3rd party API's with vastly different requirements all while not reinventing the wheel for each one. The client needed to be simple and modular, allowing us to write bits of functionality once and reuse them while at the same time not having them be tightly coupled and dependent on each other.
Functional programming and more speficly functional composition gave us the perfect solution to this problem. If you want to see how we did it, continue reading the guide or jump striaght to the API.
Guide
Below is a basic walkthrough of dvori's features, taking you from beginner to advanced
Basic Concepts
At it's core dvori is just a set of functions. You use these functions to create a HTTP client and then use the client to make HTTP requests. It's composition API makes it easy to cleanly build reusable modules.
When you first start to use dvori you will see that it's slightly more verbose than Axios or other HTTP clients. Once you use dvori it becomes clear how powerful it's functional approach is and how quickly it solves complex problems for you.
Making requests
The first thing you need to do to make a HTTP request is create a HTTP client. The createClient
function makes this easy.
const { createClient } = require("dvori");
const client = createClient();
By default you can use a dvori HTTP client to make request just like you would with other HTTP clients. It supports standard REST verbs "get", "post", "put", "patch", "delete", "options", "head", "trace"
. Each verb is defined as the property of your client object and is a function that accepts request configs, returning a promise.
const { status, data } = await client.get({
url: "httpbin.org/get",
});
So far this isn't really anything special or different, but once you start using plugins dvori really starts to shine.
Plugins
Plugins allow you to hook into specific points of the clients request / response / error lifecycle.
composePlugins(...plugins)
is a function that takes an array of plugins as arguements. Each plugin is a function that returns an object with at least one of 3 hooks:
onRequest(config)
Hook:
onRequest: config => config
const reqPlugin = (options) => {
return {
//the onRequest hook gets passed the request config
onRequest: (config) => {
/* modify the request config here */
//the onRequest hook must return the config object
return config;
},
};
};
onResponse(response)
Hook:
onResponse: response => response
const resPlugin = (options) => {
return {
//the onResponse hook gets passed the response object
onResponse: (response) => {
/* modify or use the response obj here */
//the onResponse hook must return the response object
return response;
},
};
};
onError(err)
Hook:
onError: err => err;
const errPlugin = (options) => {
return {
//the onError hook gets passed the error
onError: (err) => {
/* do something with the error here. ex: log it */
console.error(err);
//the onError hook must return the err object
return err;
},
};
};
Simple Example:
This creates a custom plugin that adds a header to request before it's sent.
const { createClient, composePlugins } = require("dvori");
const addHeader = (key, val) => ({
onRequest: (config) => {
config.headers[key] = val;
return config;
},
});
// composePlugin accepts multiple plugins and composes them into one function
const onReqHandler = composePlugins(
addHeader("Content-Type", "application/json"),
addHeader("User-Agent", "MyCustomUserAgent:v1")
);
const client = createClient({
plugins: {
onRequest: onReqHandler,
},
});
const response = await client.get({ ...config });
Plugins become even more useful if you have multiple API's or API endpoints that have different requirements. Checkout the examples to see how plugins can be mixed and matched to create multiple easy to use API clients.
Default Plugins
dvori comes with some useful plugins already written for you.
Request
baseUrl
headers
userAgent
params
data
Response
json
Middleware
Ogres & middleware are like onions, they both have layers
Middleware give you complete control over the request / response lifecycle.
Example:
const { createClient, composeMiddleware } = require("dvori");
const myMiddleware = (next) => async (config) => {
// You can modify the config here
let response = await next(config);
// You can modify the response here
return response;
};
const client = createClient({
middleware: composeMiddleware(myMiddleware),
});
Default Middleware
- Retry
- Pagination
- OAuth2
Contributing
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
Please make sure to update tests as appropriate.
License
Apache-2.0