Skip to main content

Hooks

Hooks are a way to add custom code to your SDK or Terraform provider 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.

Supported SDK languages and versions:

TypeScriptJavaPython v1Python v2C#GoTerraform

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, or providing Terraform plan modifiers.

liblab can extend your SDKs in each of the languages generated, using our Hooks framework. The SDK hooks 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 returns 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 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 exception 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 exception"

For Terraform you can hook into the terraform plan command to modify the plan before it is applied. You can read more on this in our Terraform provider hooks and custom plan modifiers documentation.

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

src/index.ts
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
}
}
note

If you are generating a Terraform provider as well as a standalone Go SDK, hooks are not shared between the Go SDK generated for the terraform provider and the standalone Go SDK.

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. To be included in our SDK, this hooks folder must live in the same folder as your liblab config file.

This hooks folder will contain a folder for each of the languages specified in your config file.

.
├── hooks
│ ├── go
│ ├── csharp
│ ├── java
│ ├── python
│ ├── terraform
│ └── typescript
├── customPlanModifiers // hooks that are triggered on the `terraform plan` command
│ ├── attributes
│ └── resources
└── liblab.config.json

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>

If you are creating hooks for a Terraform provider, you will get an additional folder called customPlanModifiers which contains the hooks for the internal Go SDK that is used by the Terraform provider. You can read more on this in our Terraform provider hooks and custom plan modifiers documentation.

Hooks can be written for the underlying Go SDK that is used by the Terraform provider by updating the code in the hooks/terraform folder. These hooks are written in the same way as writing hooks for the Go SDK.

You can read more about adding hooks in our CLI hooks documentation.

Implement hooks

In the hooks folder, you will find hooks code 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 hook 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:

src/index.ts
export interface Request {
method: string;
url: string;
input?: object;
headers: object;
}

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

src/index.ts
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:

src/index.ts
export interface Response {
data: object;
headers: object;
status: number;
}

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

src/index.ts
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 original request object for reference, along with details of the error.

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

src/index.ts
export interface Exception extends Error {
title: string;
type?: string;
detail?: string;
instance?: string;
statusCode: number;
}

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

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

Additional constructor parameters

Supported SDK languages and versions:

TypeScript v1TypeScript v2JavaPython v1Python v2C#GoPHPTerraform

If you need to pass additional data from the code that calls your SDK into hooks, you can enable this by adding additional constructor parameters to your SDK client. These are defined in your liblab config file.

Additional constructor parameters are not supported in v1 of the TypeScript SDK generation.

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.

note

If you have terraform as one of the languages in your config file, this command will also delete the customPlanModifiers directory.