Skip to main content

Hooks

Hooks are a way to add custom code to your SDK to hook into the API invocation lifecycle. This document will guide you through extending the liblab generated SDK with your custom logic using our Hooks framework.

What are Hooks?

In some use cases, you need to extend the SDK created by liblab, and add your own custom code into the SDK at the generation process. Examples of such use cases include custom authentication or auditing requirements.

liblab can extend your SDKs in each of the languages generated, using our Hooks framework. The framework lets you hook in your code into three events in the API invocation lifecycle:

  • Before Request - Code implemented in this section will run before the request. You can use the request object and update the request itself before it goes out to your API.
  • After Response - Code implemented in this section will run after the call returns from your API. You can use the request objects to get context for the API call made and the response object for the response provided.
  • On Error - Code implemented in this section will run in case of an API call error. You can use the request objects to get context for the API call and the exception object for information about the error that accrued.

Happy path

The hook flow for a successful call. SDK is called, request is prepared, the before request hook is called, the request is sent, the response is received, the after response hook is called, and the sdk call returnsThe hook flow for a successful call. SDK is called, request is prepared, the before request hook is called, the request is sent, the response is received, the after response hook is called, and the sdk call returns

Error path

The hook flow for an unsuccessful call. SDK is called, request is prepared, the before request hook is called, the request is sent, an error is received, the on error hook is called, and the sdk raises an exceptionThe hook flow for an unsuccessful call. SDK is called, request is prepared, the before request hook is called, the request is sent, an error is received, the on error hook is called, and the sdk raises an exception

To implement hooks, you need to implement one or more of the three hooks - before request, after response or on error.

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

async afterResponse(request: Request, response: Response): Promise<void> {
// Your code goes here
}

async onError(error: Exception): Promise<void> {
// Your code goes here
}
}

Add hooks to your liblab project

To add the hooks framework, run the following command:

liblab hooks add

This will generate a hooks folder which you can modify to extend the SDK. This hooks folder will contain a folder for each of the languages specified in your config file.

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

Each folder will contain a full code project that you can add your custom hook code to. This code is then sent to liblab when your SDK is generated. The presence of the hooks folder is all liblab needs to generate hooks in your SDK.

You can also add hooks for a single language by running liblab hooks add --language=<language>

Implement hooks

In the hooks folder, you will find a project for each of the languages you have generated.

typescript
├── src
│ └── index.ts
├── tests
│ └── hook.spec.ts
├── package-lock.json
├── package.json
├── prettier.config.js
├── tsconfig.eslint.json
└── tsconfig.json

Hook dependencies

Each hook project has relevant files to add dependencies, for example in a Python hook there is a requirements.txt file, in Java there is a pom.xml. If you want to add any dependencies to your hooks code, for example an SDK to add telemetry, you must add them to the relevant file so that they can be picked up during the SDK generation process.

note

If you do not add dependencies to these files, the SDK generation will not know to add them and your final SDK may not build or run

Before request

The before request hook is called just before the request is sent to your API. The hok receives a request object with the URL being called, the relevant verb (GET, POST etc.), the body as JSON, and the headers.

In this hook, you can modify the request object or the headers, and the changes will be sent to your API.

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

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

The beforeRequest function 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
}
}

After response

The after response hook is called once the response has been received from the SDK. The hook receives the request object, and the response object. The response object contains the response body as JSON, the headers, and the status code.

In this hook you can modify the response body or headers, and the changes will be returned to the SDK caller.

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

export interface Response {
data: object;
headers: object;
status: number;
}

The afterResponse function is implemented in the CustomHook class in the src/index.ts file:

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

On error

The on error hook is called if the API returns an error, such as a 4xx status code. This hook passes the request object, along with details of the error.

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

export interface Exception extends Error {
title: string;
type?: string;
detail?: string;
instance?: string;
statusCode: number;
}

The onError function is implemented in the CustomHook class in the src/index.ts file:

export default class CustomHook implements Hook {
async onError(error: Exception): Promise<void> {
// Your code goes here
}
}

Build your SDK with hooks

When you next run the liblab build command, liblab will send the code in the hooks folder to our servers, and the resulting SDKs will have your code integrated automatically into the SDKs. Any package dependencies that your hooks have will be merged with the SDK dependencies.

Remember to add the hooks folder to your source control, so that your hooks code is always available when you build your SDKs. It should live in the same folder in the same repo as your liblab config file.

Remove hooks

To remove hooks you can use the command liblab hooks remove, or manually delete your hooks folder. Once this is done, the next time you run liblab build, your SDK will be generated without your custom hook code.