UNPKG

5.67 kBMarkdownView Raw
1# axios-url-template
2
3[![npm version](https://img.shields.io/npm/v/axios-url-template.svg?style=flat-square)](https://www.npmjs.org/package/axios-url-template)
4![Build status](https://github.com/rafw87/axios-url-template/actions/workflows/test.yml/badge.svg)
5[![Coverage Status](https://coveralls.io/repos/github/rafw87/axios-url-template/badge.svg?branch=master)](https://coveralls.io/github/rafw87/axios-url-template?branch=master)
6[![install size](https://packagephobia.now.sh/badge?p=axios-url-template)](https://packagephobia.now.sh/result?p=axios-url-template)
7
8This package adds support for URL templates to [Axios](https://www.npmjs.com/package/axios),
9according to [RFC 6570 URI Template specification](https://datatracker.ietf.org/doc/html/rfc6570).
10
11It uses [url-template](https://www.npmjs.com/package/url-template) package and wraps it into Axios interceptor.
12
13## Installation
14
15```bash
16$ npm install axios-url-template
17```
18or
19```bash
20$ yarn add axios-url-template
21```
22
23
24## Usage
25
26```typescript
27import { urlTemplateInterceptor } from "axios-url-template";
28
29// attaching interceptor to Axios global instance
30axios.interceptors.request.use(urlTemplateInterceptor());
31
32// passing options
33axios.interceptors.request.use(urlTemplateInterceptor({
34 urlAsTemplate: false,
35}));
36
37// attaching interceptor to Axios instance
38const instance = axios.create({ /* ... */});
39instance.interceptors.request.use(urlTemplateInterceptor());
40
41// example requests
42
43const response1 = await axios.get('/test/{id}', {
44 urlTemplateParams: { id: 123 },
45});
46// config:
47// {
48// url: '/test/123',
49// urlTemplate: '/test/{id}',
50// urlTemplateParams: { id: 123 }
51// }
52
53const response2 = await axios.get('/test{?foo,bar}', {
54 urlTemplateParams: { foo: 'foo1', bar: 'bar1' },
55});
56// config:
57// {
58// url: '/test?foo=foo1&bar=bar1',
59// urlTemplate: '/test{?foo,bar}',
60// urlTemplateParams: { foo: 'foo1', bar: 'bar1' },
61// }
62
63const response3 = await axios.request({
64 urlTemplate: '/test/{id}',
65 urlTemplateParams: { id: 123 },
66});
67// config:
68// {
69// url: '/test/123',
70// urlTemplate: '/test/{id}',
71// urlTemplateParams: { id: 123 },
72// }
73```
74Interceptor may be also registered using shortcut method:
75```typescript
76import { useUrlTemplateInterceptor } from "axios-url-template";
77
78useUrlTemplateInterceptor(axios);
79
80const instance = axios.create({ /* ... */});
81useUrlTemplateInterceptor(instance, { urlAsTemplate: false });
82```
83
84
85### Options
86- `urlAsTemplate`: when set to `true`, then `url` is treated as template and possibly interpolated.
87 When set to `false` it does not touch `url` unless `urlTemplate` is explicitly specified. Default: `true`.
88
89
90## Behavior
91
92When `urlTemplate` (and optional `urlTemplateParams`) is provided in Axios config object,
93this interceptor uses it to generate `url`. Those template fields are persisted in config object,
94so after execution config will contain all of those fields:
95- `url`
96- `urlTemplate`
97- `urlTemplateParams` - when no parameter are provided it will be an empty object
98
99When `urlAsTemplate` option is set to `true` (default), then `url` will be also treated as url template
100and passed through interpolation. In this case, `urlTemplate` and `urlTemplateParams`
101will be added accordingly, and `url` will be replaced with interpolated value,
102giving the same effect as for `urlTemplate`.
103
104When no `urlTemplate` is provided and `urlAsTemplate` option is set to `false` then
105the interceptor passes request config without any changes.
106
107
108## Use cases
109This interceptor helps to automate things like structural logging and/or request metrics,
110where low cardinality route is preferred over full URL with dynamic parts.
111
112When request is performed in traditional way, there is no easy option to retrieve such route
113from full URL provided in call to Axios. It may be provided as custom fields,
114but it increases overhead and may generate mistakes.
115
116The interceptor ensures consistency, as actual URL provided to Axios is computed
117from route (url template) and parameters.
118
119Example (in TypeScript):
120```typescript
121import axios, { AxiosResponse } from 'axios';
122import { useUrlTemplateInterceptor } from "axios-url-template";
123
124// example logging interceptor
125function loggingInterceptor(response: AxiosResponse) {
126 const { status, statusText } = response;
127 const { urlTemplate, urlTemplateParams } = response.config;
128 const url = axios.getUri(response.config);
129
130 const logObject = {
131 status,
132 statusText,
133 url,
134 route: urlTemplate, // low cardinality value is preferred
135 routeParams: urlTemplateParams, // dynamic route parts
136 };
137
138 // do something with such log object
139 console.log(JSON.stringify(logObject, null, 2));
140}
141
142// attach url template interceptor
143useUrlTemplateInterceptor(axios, { urlAsTemplate: true })
144
145// attach logging interceptor
146axios.interceptors.response.use(loggingInterceptor);
147
148async function execute() {
149 await axios.get("https://postman-echo.com/status/{status}", {
150 urlTemplateParams: { status: 201 },
151 });
152
153 await axios.get("https://postman-echo.com/get{?foo,bar}", {
154 urlTemplateParams: { foo: "foo1", bar: "bar1" },
155 params: { baz: 'baz1' }, // additional param, not being part of route
156 });
157}
158execute().catch(console.error);
159```
160
161Result:
162```jsonl
163{
164 "status": 201,
165 "statusText": "Created",
166 "url": "https://postman-echo.com/status/201",
167 "route": "https://postman-echo.com/status/{status}",
168 "routeParams": {
169 "status": 201
170 }
171}
172{
173 "status": 200,
174 "statusText": "OK",
175 "url": "https://postman-echo.com/get?foo=foo1&bar=bar1&baz=baz1",
176 "route": "https://postman-echo.com/get{?foo,bar}",
177 "routeParams": {
178 "foo": "foo1",
179 "bar": "bar1"
180 }
181}
182```
183
184## License
185MIT