Kitsu
A simple, lightweight & framework agnostic JSON:API client for Kitsu.io and other APIs
Migration guide for v9 and previous major releases
Features
- JSON-API 1.0 compliant
- Automatically links relationships to data
- Works in Node and on the web
- Uses the Promise API
Node / Browser Support
Package | Package Size* | Node | Chrome | Firefox | Safari | Edge |
---|
kitsu | ≤ 8.9 kb | 10+ | 67+ | 68+ | 12+ | 18+ |
* Including all dependencies, minified & gzipped
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 and relationships
API
Table of Contents
Kitsu
packages/kitsu/src/index.js:30-447
Creates a new kitsu
instance
Parameters
options
Object? Options (optional, default {}
)
options.baseURL
string Set the API endpoint (optional, default https://kitsu.io/api/edge
)options.headers
Object? Additional headers to send with the requestsoptions.camelCaseTypes
boolean If true, the type
value will be camelCased, e.g library-entries
and library_entries
become libraryEntries
(optional, default true
)options.resourceCase
string kebab
, snake
or none
. If kebab
, /libraryEntries
will become /library-entries
. If snake
, /libraryEntries
will become /library_entries
, If none
, /libraryEntries
will be unchanged (optional, default kebab
)options.pluralize
boolean If true
, /user
will become /users
in the URL request and type
will be pluralized in POST, PATCH and DELETE requests (optional, default true
)options.timeout
number Set the request timeout in milliseconds (optional, default 30000
)options.axiosOptions
Object? Additional options for the axios instance (see axios/axios#request-config for details)
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:185-204
Fetch resources (alias fetch
)
Parameters
model
string Model to fetch data fromparams
Object? JSON-API request queries (optional, default {}
)
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')
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:225-245
Update a resource (alias update
)
Parameters
model
string Model to update data inbody
(Object | Array<Object>) Data to send in the requestheaders
Object? Additional headers to send with the request (optional, default {}
)
Examples
Update a post
api.update('posts', {
id: '1',
content: 'Goodbye World'
})
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:273-292
Create a new resource (alias create
)
Parameters
model
string Model to create a resource underbody
(Object | Array<Object>) Data to send in the requestheaders
Object? Additional headers to send with the request (optional, default {}
)
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:307-336
Remove a resource (alias remove
)
Parameters
model
string Model to remove data fromid
(string | number | Array<number>) Resource ID to remove. Pass an array of IDs to delete multiple resources (Bulk Extension)headers
Object? Additional headers to send with the request (optional, default {}
)
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:358-365
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:426-446
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 requestconfig.method
string? Request method - GET
, PATCH
, POST
or DELETE
(defaults to GET
, case-insensitive)config.params
Object? JSON-API request queries
config.params.page
Object? JSON:API Pagination
config.params.page.limit
number? Number of resources to return in request (Max 20
for Kitsu.io except on libraryEntries
which has a max of 500
)config.params.page.offset
number? Number of resources to offset the dataset by
config.params.fields
Object? Return a sparse fieldset with only the included attributes/relationships - JSON:API Sparse Fieldsetsconfig.params.filter
Object? Filter dataset by attribute values - JSON:API Filteringconfig.params.sort
string? Sort dataset by one or more comma separated attributes (prepend -
for descending order) - JSON:API Sortingconfig.params.include
string? Include relationship data - JSON:API Includes
config.type
string The resource typeconfig.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