octokit/rest.js

repository·main·Indexed 20 days ago

https://github.com/octokit/rest.js

The official GitHub REST API client for JavaScript, providing a structured, programmatic way to interact with GitHub's REST API in Node.js and browser environments. It includes support for authentication strategies, pagination via octokit.paginate(), custom requests, and plugin extensibility.

Tokens
9.2K
Snippets
34
Records
36
Agent score
70%

What's inside @octokit/rest

  1. How to write an Octokit plugin

    main

    An Octokit plugin is a function with the following signature: const plugin = (octokit, options) => { ... }

    Key Capabilities:

    • Hook into the request lifecycle: Use octokit.hook.wrap(name, callback) to intercept and modify requests or responses. For example, wrapping "request" allows you to log timing or modify headers.
    • Add custom methods: Return an object from the plugin function. The keys in this object become new methods available on the octokit instance.
    • Access configuration: The second argument (options) is the configuration object passed to the constructor when the client is instantiated.

    It is recommended to use octokit.log methods within plugins to assist users with debugging.

    const plugin = (octokit, options = { greeting: "Hello" }) => {
      // 1. Hook into the request lifecycle
      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;
      });
    
      // 2. Add a custom method
      return {
        helloWorld: () => console.log(`${options.greeting}, world!`),
      };
    };
    
    export default plugin;
  2. Understand the @octokit/rest request lifecycle

    main

    The request lifecycle in @octokit/rest follows a specific sequence of merging, transforming, and executing:

    1. Endpoint Options Generation: The library merges global defaults (from the new Octokit() constructor), endpoint defaults (specific to the method being called, like method and url), and user options (passed directly to the method) into a single set of endpoint options.
    2. Transformation: These endpoint options are transformed into final request options (resolving URL variables and query parameters into a full URL).
    3. Hooks Execution: Hooks can intercept the process at various stages (before transformation, after the request, or on error).
    4. Request & Response: The request is sent via @octokit/request (using fetch or node-fetch), and the resulting response is returned to the user.
  3. How endpoint options are merged

    main

    When you call a REST method, the final options used for the request are a result of merging three layers of configuration:

    1. Global Defaults: Settings applied to all requests, such as baseUrl, user-agent, and accept headers, typically defined during new Octokit(options) initialization.
    2. Endpoint Default Options: Hardcoded defaults for a specific API endpoint (e.g., the specific method and url template for repos.listForOrg).
    3. User Options: The specific arguments you pass into the method call (e.g., { org: 'octokit' }).

    Example: Calling octokit.rest.repos.listForOrg({ org: 'octokit', type: 'public' }) merges the global baseUrl, the endpoint's GET method and /orgs/{org}/repos URL, and your provided org and type parameters.

    // Example of merging layers
    // 1. Global: baseUrl: 'https://api.github.com'
    // 2. Endpoint: method: 'GET', url: '/orgs/{org}/repos'
    // 3. User: { org: 'octokit', type: 'public' }
    
    // Resulting Endpoint Options:
    // { baseUrl: 'https://api.github.com', method: 'GET', url: '/orgs/{org}/repos', org: 'octokit', type: 'public' }
    
    // Resulting Request Options (after transformation):
    // { method: 'GET', url: 'https://api.github.com/orgs/octokit/repos?type=public', ... }
    
    octokit.rest.repos.listForOrg({ org: "octokit", type: "public" });
  4. Use custom authentication strategies

    main

    To use authentication strategies other than the default token strategy (such as OAuth Apps, GitHub Apps, or GitHub Actions), set the authStrategy option in the Octokit constructor to the strategy function, and provide the necessary credentials in the auth option.

    Supported strategies include:

    • @octokit/auth-token: Default strategy for personal access tokens.
    • @octokit/auth-oauth-app: For OAuth Apps using client_id and client_secret or user access tokens.
    • @octokit/auth-app: For GitHub Apps using installation access tokens or JWT.
    • @octokit/auth-action: For GitHub Actions using the GITHUB_TOKEN secret.
    import { Octokit } from "@octokit/rest";
    import { createAppAuth } from "@octokit/auth-app";
    
    const appOctokit = new Octokit({
      authStrategy: createAppAuth,
      auth: {
        appId: 123,
        privateKey: process.env.PRIVATE_KEY,
        // optional: this will make appOctokit authenticate as app (JWT)
        //           or installation (access token), depending on the request URL
        installationId: 123,
      },
    });
    
    const { data } = await appOctokit.request("/app");
  5. Request alternative response formats using mediaType

    main

    Some GitHub API endpoints support alternative response formats (e.g., requesting a pull request as a diff instead of JSON). To request a specific format, include a mediaType object in your request options and set the format property to the desired value.

    Refer to the GitHub Media Types documentation for a full list of supported formats.

    const { data: prDiff } = await octokit.rest.pulls.get({
      owner: "octokit",
      repo: "rest.js",
      pull_number: 1278,
      mediaType: {
        format: "diff",
      },
    });
  6. Instantiate Octokit with configuration options

    main

    Create an instance of the Octokit API by passing an options object to the Octokit constructor. While most options are optional, authentication is strongly encouraged.

    Key configuration options include:

    • auth: A personal access token string.
    • userAgent: A string identifying your app or script (required by GitHub).
    • previews: An array of API Preview headers to enable globally (e.g., ['jean-grey']).
    • timeZone: A default time zone string (e.g., 'Europe/Amsterdam').
    • baseUrl: Used for GitHub Enterprise instances.
    • log: An object containing debug, info, warn, and error methods for custom logging.
    • request: An object for custom request settings like agent, fetch, or timeout.
    const octokit = new Octokit({
      auth: "secret123",
      userAgent: 'myApp v1.2.3',
      previews: ['jean-grey', 'symmetra'],
      timeZone: 'Europe/Amsterdam',
      baseUrl: 'https://api.github.com',
      log: {
        debug: () => {},
        info: () => {},
        warn: console.warn,
        error: console.error
      },
      request: {
        agent: undefined,
        fetch: undefined,
        timeout: 0
      }
    });
  7. Enable automatic retries using @octokit/plugin-retry

    main

    To automatically retry requests that fail due to recoverable errors, install the @octokit/plugin-retry plugin. You can integrate it into your Octokit instance by using the Octokit.plugin() method to create a custom constructor. Once configured, all requests sent through that instance will be retried up to 3 times for recoverable errors by default.

    import { Octokit } from "@octokit/rest";
    import { retry } from "@octokit/plugin-retry";
    
    // Create a custom Octokit class that includes the retry plugin
    const MyOctokit = Octokit.plugin(retry);
    
    // Instantiate the custom class
    const octokit = new MyOctokit();
    
    // All requests sent with this `octokit` instance are now retried up to 3 times for recoverable errors.
  8. Install @octokit/rest in Node.js

    main

    To use the GitHub REST API client in a Node.js environment, install the package via npm.

    Important TypeScript Configuration: Because the package uses conditional exports, you must update your tsconfig.json to ensure proper module resolution. Set the following values:

    • "moduleResolution": "node16"
    • "module": "node16"
    npm install @octokit/rest
  9. Extend Octokit using plugins

    main

    You can customize and extend Octokit's functionality by using the Octokit.plugin() method. This method allows you to inject custom logic, such as request lifecycle hooks or new instance methods, into the Octokit client.

    To use plugins:

    1. Define a plugin function that accepts octokit as the first argument and an options object as the second.
    2. The plugin function can return an object containing new methods to be added to the octokit instance.
    3. Use Octokit.plugin(...plugins) to create a new constructor (e.g., MyOctokit) that includes the plugin logic.
    4. Instantiate your new constructor with the desired configuration options.
    import { Octokit } from "@octokit/rest";
    import myPlugin from "./lib/my-plugin.js";
    
    // Create a new constructor with the plugin applied
    const MyOctokit = Octokit.plugin(myPlugin);
    
    // Instantiate with options that will be passed to the plugin
    const octokit = new MyOctokit({ greeting: "Hola" });
    
    // Use methods added by the plugin
    octokit.helloWorld();
    // Output: Hola, world!
  10. Run the documentation website locally

    main

    The documentation for @octokit/rest is a static website built with Gatsby. To run the documentation site on your local machine for development or inspection, follow these steps:

    1. Install dependencies for the main repository.
    2. Navigate to the docs directory.
    3. Install the documentation-specific dependencies.
    4. Start the development server.
    npm install
    cd /docs
    npm install
    npm start
  11. Configure log levels using console-log-level

    main

    If you need more granular control over the verbosity of logs, you can use the console-log-level module. Pass the result of consoleLogLevel({ level: "your-level" }) to the log option in the Octokit constructor. This allows you to filter logs by level (e.g., info, warn, error).

    import { Octokit } from "@octokit/rest";
    import consoleLogLevel from "console-log-level";
    
    const octokit = new Octokit({
      log: consoleLogLevel({ level: "info" }),
    });
    
    octokit.request("/");