Skip to main content

Customize your SDK with hooks

Hooks are a powerful way to customize your SDK. They allow you to hook into the API calls and modify the request or response. You can also use them to add custom functionality to your SDK.

Some examples of ways you can use hooks:

  • Add custom headers to all requests
  • Add an API version as a header or a query string parameter
  • Customize authentication, such as copying an API key from a header to a URL parameter
  • Add telemetry
  • Add logging to API errors

In this tutorial, we'll show you how to use hooks to add API versions to your SDK using the Accept-version header.

Prerequisites

This tutorial assumes you already have:

  • The liblab CLI installed and you are logged in
  • An API spec
  • A liblab config file created using liblab init

Steps

In this tutorial you'll:

  1. Create the hooks
  2. Add the hook code
  3. Build the SDK

Create the hooks

First we'll create the hooks code. Run the following command in the same folder as your config file:

liblab hooks add

This will create a hooks folder with hooks for each SDK language defined in your config file:

hooks
├── java
├── python
└── typescript

You may see a smaller set of hooks folders depending on the languages you have defined in your config file.

For each language, you will need to install the necessary dependencies.

To install the TypeScript dependencies, run the following command from the hooks/typescript folder:

npm install

Add the hook code

In the hooks folder, you will find a project for each of the languages you have generated. The API version will be added to a header in the before request hook.

Locate the before request hook

Open the relevant file and inspect the hook code.

The beforeRequest method is implemented in the CustomHook class in the src/index.ts file:

export default class CustomHook implements Hook {
async beforeRequest(request: Request): Promise<void> {
// Your code goes here
}
}

Each request object has a headers property, which is a dictionary of headers. We can add the API version to this dictionary.

The Request class lives in the src/index.ts file:

export interface Request {
method: string;
url: string;
input?: object;
headers: object;
}

These request objects are mutable, and any changes you make will be used by the SDK when making the API call.

Add the version header

To add the version header, make the following code changes to the before request hooks:

async beforeRequest(request: Request): Promise<void> {
// Add the Accept-version header to the request with version 1.0
request.headers = {
...request.headers,
"Accept-version": "1.0"
};
}

This will insert the new header into the headers dictionary, and this will then be used by the SDK when making the API call.

Add tests

The hook code includes a test project for you to build unit tests against your hook code.

The tests live in the tests folder. An example test is included in the hook.spec.ts file.

Rename the test from example passing test to given the custom hook, when before request is called, then the API version header is added:

it('given the custom hook, when before request is called, then the API version header is added', async () => {

Add the following assertion to the end of the test code, below the existing assertion:

// Assert the version header is added
assert(request.headers['Accept-version'] === '1.0');
Expand to see the complete test code

import { beforeEach } from 'mocha';
import { expect } from 'chai';
import CustomHook, { Request } from "../src/index";
import * as dotenv from 'dotenv';
import { assert } from 'console';

dotenv.config();

describe('test custom hook', () => {
let hook = new CustomHook();

beforeEach(() => {
hook = new CustomHook();
});

it('given the custom hook, when before request is called, then the API version header is added', async () => {

const request: Request = {
method: 'GET',
url: 'https://api.example.com',
input: {},
headers: {
'Content-Type': 'application/json',
},
};

await hook.beforeRequest(request);
console.log(request.headers)

// Assert the headers are correct
assert(request.headers['Content-Type'] === 'application/json');
// Assert the version header is added
assert(request.headers['Accept-version'] === '1.0');
});
});

Run the tests:

npm test

You will see the test pass:

  test custom hook
{ 'Content-Type': 'application/json', 'Accept-version': '1.0' }
✓ empty passing test


1 passing (3ms)

Build the SDK

Now that your hook code is ready, you can build the SDK with the following command:

liblab build
Packaging hooks...
✓ Java built
✓ Python built
✓ TypeScript built
SDKs downloaded successfully. You can find them inside the "output" folder

This will send your hook code along with your spec and config to liblab to use in the SDK generation. You can see the results in the SDKs that are generated and downloaded to the output folder.

The hooks can be found in the src/hooks folder:

hooks
├── CustomHook.ts
└── Hook.ts

Your hook code is in the Hook.ts file.