Kitsu
A simple, lightweight & framework agnostic JSON:API client using Axios
Migration guide for v9 & previous major releases
Features
- JSON-API 1.0 compliant
- Automatically links relationships to data
- Works in Node & browsers
- Uses the Promise API
Node / Browser Support
Package | Package Size* | Node | Chrome | Firefox | Safari | Edge |
---|
kitsu | ≤ 8.2 kb | 10+ | 83+ | 78+ | 13.1+ | 95+ |
* Including all dependencies & minified with brotli
Response Comparison
Object from a GET Response by a JSON:API Server
{
data: {
id: '1'
type: 'articles'
attributes: {
title: 'JSON API paints my bikeshed'
}
relationships: {
author: {
data: {
id: '42'
type: 'people'
}
}
}
}
included: [
{
id: '42'
type: 'people'
attributes: {
name: 'John'
}
}
]
}
Object from a GET Response with kitsu:
{
data: {
id: '1'
type: 'articles'
title: 'JSON API paints my bikeshed'
author: {
data: {
id: '42'
type: 'people'
name: 'John'
}
}
}
}
Install
Yarn / NPM
yarn add kitsu
npm install kitsu
import Kitsu from "kitsu";
const Kitsu = require("kitsu");
Quick Start
const api = new Kitsu()
const api = new Kitsu({
baseURL: 'https://api.example/2'
})
const res = await api.get('anime')
api.get('anime')
.then(res => { ... })
.catch(err => { ... })
api.fetch('anime')
api.fetch('anime', { filter: { id: 1 } })
api.fetch('anime/1/episodes')
api.fetch('anime/1/relationships/episodes')
api.create('post', {
content: 'some content'
})
api.update('post', {
id: '1',
content: 'new content'
})
api.remove('post', 1)
api.get('users', {
include: 'followers,waifu.character',
fields: {
users: 'slug,followers,waifu'
},
filter: {
slug: 'wopian'
},
sort: '-id',
page: {
limit: 5,
offset: 0
}
})
More Examples
If you're working with Kitsu.io's API, their API docs lists all available resources with their attributes & relationships
API
Table of Contents
Kitsu
packages/kitsu/src/index.js:30-476
Creates a new kitsu
instance
Parameters
Examples
Using with Kitsu.io's API
const api = new Kitsu()
Using another API server
const api = new Kitsu({
baseURL: 'https://api.example.org/2'
})
Setting headers
const api = new Kitsu({
headers: {
'User-Agent': 'MyApp/1.0.0 (github.com/username/repo)',
Authorization: 'Bearer 1234567890'
}
})
plural
packages/kitsu/src/index.js:52-53
If pluralization is enabled (default, see Kitsu constructor docs) then pluralization rules can be added
Examples
Adding an uncountable pluralization rule
api.plural.plural('paper')
api.plural.addUncountableRule('paper')
api.plural.plural('paper')
packages/kitsu/src/index.js:67-67
Get the current headers or add additional headers
Examples
Get all headers
api.headers
Get a single header's value
api.headers['User-Agent']
Add or update a header's value
api.headers['Authorization'] = 'Bearer 1234567890'
Returns Object All the current headers
interceptors
packages/kitsu/src/index.js:112-112
Axios Interceptors (alias of axios.interceptors
)
You can intercept responses before they are handled by get
, post
, patch
and delete
and before requests are sent to the API server.
Examples
Request Interceptor
api.interceptors.request.use(config => {
return config
}, error => {
return Promise.reject(error)
})
Response Interceptor
api.interceptors.response.use(response => {
return response
}, error => {
return Promise.reject(error)
})
Removing Interceptors
const myInterceptor = api.interceptors.request.use(function () {...})
api.interceptors.request.eject(myInterceptor)
get
packages/kitsu/src/index.js:198-218
Fetch resources (alias fetch
)
Parameters
-
model
string Resource to fetch data from. Expected formats are :resource
, :resource/:id
, :resource/:id/:relationship
or :resource/:id/relationships/:relationship
-
params
Object? JSON-API request queries. Any JSON:API query parameter not mentioned below is supported out of the box. (optional, default {}
)
-
params.page
Object? JSON:API Pagination. All pagination strategies are supported, even if they are not listed below.
params.page.limit
number? Number of resources to return in request (Offset-based) - Note: For Kitsu.io, max is 20
except on libraryEntries
which has a max of 500
params.page.offset
number? Number of resources to offset the dataset by (Offset-based)params.page.number
number? Page of resources to return in request (Page-based) - Note: Not supported on Kitsu.ioparams.page.size
number? Number of resources to return in request (Page-based and cursor-based) - Note: Not supported on Kitsu.ioparams.page.before
string? Get the previous page of resources (Cursor-based) - Note: Not Supported on Kitsu.ioparams.page.after
string? Get the next page of resources (Cursor-based) - Note: Not Supported on Kitsu.io
-
params.fields
Object? Return a sparse fieldset with only the included attributes/relationships - JSON:API Sparse Fieldsets
-
params.filter
Object? Filter dataset by attribute values - JSON:API Filtering
-
params.sort
string? Sort dataset by one or more comma separated attributes (prepend -
for descending order) - JSON:API Sorting
-
params.include
string? Include relationship data - JSON:API Includes
-
headers
Object? Additional headers to send with the request (optional, default {}
)
Examples
Getting a resource with JSON:API parameters
api.get('users', {
fields: {
users: 'name,birthday'
},
filter: {
name: 'wopian'
}
})
Getting a collection of resources with their relationships
api.get('anime', {
include: 'categories'
})
Getting a single resource by ID (method one)
api.get('anime/2', {
include: 'categories'
})
Getting a single resource by ID (method two)
api.get('anime', {
include: 'categories',
filter: { id: '2' }
})
Getting a resource's relationship data only
api.get('anime/2/categories')
Getting a resource with nested JSON:API filters (not supported by Kitsu.io's API)
api.get('resource', {
filter: {
x: {
y: 'value'
}
}
}
Handling errors (async/await)
try {
const { data } = await api.get('anime')
} catch (err) {
if (err.errors) err.errors.forEach(error => { ... })
err.name
err.message
err.config
err.response
}
Handling errors (Promises)
api.get('anime')
.then(({ data }) => { ... })
.catch(err => {
if (err.errors) err.errors.forEach(error => { ... })
err.name
err.message
err.config
err.response
})
Returns Object JSON-parsed response
patch
packages/kitsu/src/index.js:251-272
Update a resource (alias update
)
Parameters
Examples
Update a resource
api.update('posts', {
id: '1',
content: 'Goodbye World'
})
Update a resource with relationships
api.update('posts', {
content: 'Hello World',
uploads: {
id: '167585',
type: 'uploads'
}
})
Clear to-one relationships from a resource
api.update('posts/1/relationships/uploads', null)
Clear to-many relationships from a resource
api.update('posts/1/relationships/uploads', [])
Update multiple resources (API must support the Bulk Extension)
api.update('posts', [
{ id: '1', content: 'Hello World' },
{ id: '2', content: 'Another post' }
])
Returns (Object | Array<Object>) JSON-parsed response
post
packages/kitsu/src/index.js:300-319
Create a new resource (alias create
)
Parameters
Examples
Create a post on a user's profile feed
api.create('posts', {
content: 'Hello World',
targetUser: {
id: '42603',
type: 'users'
},
user: {
id: '42603',
type: 'users'
}
})
Create multiple resources (API must support the Bulk Extension)
api.create('posts', [
{ content: 'Hello World' },
{ content: 'Another post' }
])
Returns (Object | Array<Object>) JSON-parsed response
delete
packages/kitsu/src/index.js:334-363
Remove a resource (alias remove
)
Parameters
Examples
Remove a single resource
api.delete('posts', 123)
Remove multiple resources (API must support the Bulk Extension)
api.delete('posts', [ 1, 2 ])
Returns (Object | Array<Object>) JSON-parsed response
self
packages/kitsu/src/index.js:385-392
Get the authenticated user's data
Note Requires the JSON:API server to support filter[self]=true
Parameters
-
params
Object? JSON-API request queries (optional, default {}
)
-
headers
Object? Additional headers to send with the request (optional, default {}
)
Examples
Get the authenticated user's resource
api.self()
Using JSON:API parameters
api.self({
fields: {
users: 'name,birthday'
}
})
Returns Object JSON-parsed response
request
packages/kitsu/src/index.js:453-475
Send arbitrary requests
Note Planned changes to the get
, patch
, post
and delete
methods in a future major release may make this method redundent. See https://github.com/wopian/kitsu/issues/415 for details.
Parameters
-
config
Object? Request configuration
-
config.body
(Object | Array<Object>)? Data to send in the request
-
config.method
string? Request method - GET
, PATCH
, POST
or DELETE
(defaults to GET
, case-insensitive)
-
config.params
Object? JSON-API request queries. Any JSON:API query parameter not mentioned below is supported out of the box.
-
config.type
string The resource type
-
config.url
string The URL path of the resource
-
headers
Object? Additional headers to send with the request (optional, default {}
)
Examples
Raw GET request
api.request({
url: 'anime/1/mappings',
type: 'mappings',
params: { filter: { externalSite: 'aozora' } }
})
Raw PATCH request
api.request({
method: 'PATCH',
url: 'anime',
type: 'anime',
body: { id: '1', subtype: 'tv' }
})
Raw POST request
api.request({
method: 'PATCH',
url: 'anime',
type: 'anime',
body: { subtype: 'tv' }
})
Raw DELETE request
api.request({
method: 'DELETE',
url: 'anime/1',
type: 'anime',
body: { id: '1' }
})
Bulk Extension support (PATCH
, POST
& DELETE
)
api.request({
method: 'PATCH',
url: 'anime',
type: 'anime',
body: [
{ id: '1', subtype: 'tv' }
{ id: '2', subtype: 'ona' }
]
})
Returns Object JSON-parsed response
Contributing
See CONTRIBUTING
Releases
See CHANGELOG
License
All code released under MIT