rest.js
GitHub REST API client for JavaScript
Usage
Node
Install with npm install @octokit/rest
.
const Octokit = require('@octokit/rest')
const octokit = new Octokit ()
octokit.repos.listForOrg({
org: 'octokit',
type: 'public'
}).then(({ data, status, headers }) => {
})
Browser
-
Download octokit-rest.min.js
from the latest release: https://github.com/octokit/rest.js/releases
-
Load it as script into your web application:
<script src="octokit-rest.min.js"></script>
-
Initialize octokit
const octokit = new Octokit()
octokit.repos.listForOrg({
org: 'octokit',
type: 'public'
}).then(({data, headers, status}) => {
})
Client options
All available client options with default values
const Octokit = require('@octokit/rest')
const octokit = new Octokit({
auth: undefined,
userAgent: 'octokit/rest.js v1.2.3',
previews: [],
baseUrl: 'https://api.github.com',
log: {
debug: () => {},
info: () => {},
warn: console.warn,
error: console.error
},
request: {
agent: undefined,
timeout: 0
}
})
Authentication
Most GitHub API calls don't require authentication. Rules of thumb:
- If you can see the information by visiting the site without being logged in, you don't have to be authenticated to retrieve the same information through the API.
- If you want to change data, you have to be authenticated.
To enable authenticated requests, pass an auth
option to the Octokit constructor:
const clientWithAuth = new Octokit({
auth: 'token secret123'
})
The auth
option can be
-
A string
The value will be passed as value for the Authorization
header,
see authentication.
new Octokit({
auth: 'token secret123'
})
Use this for
- personal access tokens
- OAuth access tokens
- GitHub App bearer tokens
- GitHub App installation tokens
-
As object with the properties username
, password
, on2fa
.
on2fa
is an asynchronous function that must resolve with two-factor
authentication code sent to the user.
new Octokit({
auth: {
username: 'octocat',
password: 'secret',
async on2fa () {
return prompt('Two-factor authentication Code:')
}
}
})
-
An object with the properties clientId
and clientSecret
OAuth applications can authenticate using their clientId
and clientSecret
in order to increase the unauthenticated rate limit.
-
A function
Must resolve with a string which then will be passed as value for the
Authorization
header. The function will be called before each request and
can be asynchronous.
new Octokit({
auth () {
return 'token secret123'
}
})
This is useful for GitHub apps, as installations need to renew their tokens each hour.
Here is an example on how to implement authentication for GitHub Apps
const App = require('@octokit/app')
const Octokit = require('@octokit/rest')
const app = new App({ id: process.env.APP_ID, privateKey: process.env.PRIVATE_KEY })
const octokit = new Octokit({
async auth () {
const installationAccessToken = await app.getInstallationAccessToken({
installationId: process.env.INSTALLATION_ID
});
return `token ${installationAccessToken}`;
}
})
See also: https://github.com/octokit/app.js#authenticating-as-an-installation.
API docs
Find all APIs documented at https://octokit.github.io/rest.js/.
API Previews
To enable any of GitHub’s API Previews,
pass the previews
option to the GitHub constructor
const octokit = new Octokit({
previews: [
'mercy-preview'
]
})
If you want to enable a preview for a single request, pass it as as the accept
header
const { data: { topics } } = await octokit.repos.get({
owner: 'octokit',
repo: 'rest.js',
headers: {
accept: 'application/vnd.github.mercy-preview+json'
}
})
Multiple preview headers can be combined by separating them with commas
const { data: { topics, codeOfConduct } } = await octokit.repos.get({
owner: 'octokit',
repo: 'rest.js',
headers: {
accept: 'application/vnd.github.mercy-preview+json,application/vnd.github.scarlet-witch-preview+json'
}
})
Custom requests
To send custom requests you can use the lower-level octokit.request()
method
octokit.request('GET /')
The baseUrl
, headers and other defaults are already set. For more information
on the octokit.request()
API see @octokit/request
All the endpoint methods such as octokit.repos.get()
are aliases of octokit.request()
with pre-bound default options. So you can use the @octokit/request
API to
get the default options or get generic request option to use with your preferred
request library.
const defaultOptions = octokit.repos.get.endpoint.DEFAULTS
const requestOptions = octokit.repos.get.endpoint()
All endpoint methods starting with .list*
do not return all responses at once but instead return the first 30 items by default, see also GitHub’s REST API pagination documentation.
To automatically receive all results across all pages, you can use the octokit.paginate()
method:
octokit.paginate('GET /repos/:owner/:repo/issues', { owner: 'octokit', repo: 'rest.js' })
.then(issues => {
})
octokit.paginate()
accepts the same options as octokit.request()
. You can optionally pass an additional function to map the results from each response. The map must return a new value, usually an array with mapped data.
octokit.paginate('GET /repos/:owner/:repo/issues', { owner: 'octokit', repo: 'rest.js' }, response => response.data.map(issue => issue.title))
.then(issueTitles => {
})
To stop paginating early, you can call the done()
function passed as 2nd argument to the response map function. Note that you still have to return the value you want to map the response to, otherwise the last response will be mapped to undefined.
octokit.paginate('GET /organizations', (response, done) => {
if (response.data.find(issues => issue.body.includes('something'))) {
done()
}
return response.data
})
To paginate responses for one of the registered endpoint methods such as octokit.issues.listForRepo()
you can use the .endpoint.merge()
method registered for all endpoint methods:
const options = octokit.issues.listForRepo.endpoint.merge({ owner: 'octokit', repo: 'rest.js' })
octokit.paginate(options)
.then(issues => {
})
If your runtime environment supports async iterators (such as Node 10+), you can iterate through each response
for await (const response of octokit.paginate.iterator(options)) {
}
octokit.paginate.iterator()
accepts the same options as octokit.paginate()
.
Hooks
You can customize Octokit’s request lifecycle with hooks. Available methods are
octokit.hook.before('request', async (options) => {
validate(options)
})
octokit.hook.after('request', async (response, options) => {
console.log(`${options.method} ${options.url}: ${response.status}`)
})
octokit.hook.error('request', async (error, options) => {
if (error.status === 304) {
return findInCache(error.headers.etag)
}
throw error
})
octokit.hook.wrap('request', async (request, options) => {
return request(options)
})
See before-after-hook for more
documentation on hooks.
Plugins
You can customize and extend Octokit’s functionality using plugins
const MyOctokit = require('@octokit/request')
.plugin([
require('./lib/my-plugin'),
require('octokit-plugin-example')
])
module.exports = (octokit, options = { greeting: 'Hello' }) => {
octokit.helloWorld = () => console.log(`${options.greeting}, world!`)
octokit.hook.wrap('request', async (request, options) => {
const time = Date.now()
const response = await request(options)
octokit.log.info(`${options.method} ${options.url} – ${response.status} in ${Date.now() - time}ms`)
return response
})
}
.plugin
accepts a function or an array of functions.
We recommend using Octokit’s log methods to help users of your plugin with debugging.
You can add new methods to the octokit
instance passed as the first argument to
the plugin function. The 2nd argument is the options object passed to the
constructor when instantiating the octokit
client.
const octokit = new MyOctokit({ greeting: 'Hola' })
octokit.helloWorld()
Register custom endpoint methods
You can register custom endpoint methods such as octokit.repos.get()
using
the octokit.registerEndpoints(routes)
method
octokit.registerEndpoints({
foo: {
bar: {
method: 'PATCH',
url: '/repos/:owner/:repo/foo',
headers: {
accept: 'application/vnd.github.foo-bar-preview+json'
},
params: {
owner: {
required: true,
type: 'string'
},
repo: {
required: true,
type: 'string'
},
baz: {
required: true,
type: 'string',
enum: [
'qux',
'quux',
'quuz'
]
}
}
}
}
})
octokit.foo.bar({
owner: 'octokit',
repo: 'rest.js',
baz: 'quz'
})
This is useful when you participate in private beta features and prefer the
convenience of methods for the new endpoints instead of using octokit.request()
.
Throttling
When you send too many requests in too little time you will likely hit errors due to quotas.
In order to automatically throttle requests as recommended in the best practices for integrators, we recommend you install the @octokit/plugin-throttling
plugin.
The throttle.onAbuseLimit
and throttle.onRateLimit
options are required. Return true
to automatically retry the request after retryAfter
seconds.
const Octokit = require('@octokit/rest')
.plugin(require('@octokit/plugin-throttling'))
const octokit = new Octokit({
auth: 'token ' + process.env.TOKEN,
throttle: {
onRateLimit: (retryAfter, options) => {
octokit.log.warn(`Request quota exhausted for request ${options.method} ${options.url}`)
if (options.request.retryCount === 0) {
console.log(`Retrying after ${retryAfter} seconds!`)
return true
}
},
onAbuseLimit: (retryAfter, options) => {
octokit.log.warn(`Abuse detected for request ${options.method} ${options.url}`)
}
}
})
Automatic retries
Many common request errors can be easily remediated by retrying the request. We recommend installing the @octokit/plugin-retry
plugin for Automatic retries in these cases
const Octokit = require('@octokit/rest')
.plugin(require('@octokit/plugin-retry'))
const octokit = new Octokit()
Logging
Octokit
has 4 built in log methods
octokit.log.debug(message[, additionalInfo])
octokit.log.info(message[, additionalInfo])
octokit.log.warn(message[, additionalInfo])
octokit.log.error(message[, additionalInfo])
They can be configured using the log
client option. By default, octokit.log.debug()
and octokit.log.info()
are no-ops, while the other two call console.warn()
and console.error()
respectively.
This is useful if you build reusable plugins.
Debug
The simplest way to receive debug information is to set the log
client option to console
.
const octokit = require('@octokit/rest')({
log: console
})
console.request('/')
This will log
request { method: 'GET',
baseUrl: 'https://api.github.com',
headers:
{ accept: 'application/vnd.github.v3+json',
'user-agent':
'octokit.js/0.0.0-semantically-released Node.js/10.15.0 (macOS Mojave; x64)' },
request: {},
url: '/' }
GET / - 200 in 514ms
If you like to support a configurable log level, we recommend using the console-log-level module
const octokit = require('@octokit/rest')({
log: require('console-log-level')({ level: 'info' })
})
console.request('/')
This will only log
GET / - 200 in 514ms
Contributing
We would love you to contribute to @octokit/rest
, pull requests are very welcomed! Please see CONTRIBUTING.md for more information.
Credits
@octokit/rest
was originally created as node-github
in 2012 by Mike de Boer from Cloud9 IDE, Inc.
It was adopted and renamed by GitHub in 2017
LICENSE
MIT