Skip to main content

Back to the liblab blog

A Deep Dive into liblab's SDK Customization Features

| 5 min

In today's fast-paced development world, creating robust and adaptable Software Development Kits (SDKs) is crucial for seamless API integration. liblab excels at automating SDK generation, but its true power lies in its extensive customization capabilities. These features allow developers to tailor SDKs precisely to their needs, ensuring a perfect fit for any project.

Let's dive deep into some powerful customizations we provide with our SDKs Hooks with additionalConstructorParameters and Pagination.

The Power of liblab Customizations

liblab provides a centralized configuration file, liblab.config.json, where developers define their SDK's behavior. This file acts as the blueprint for everything from authentication and environment support to documentation and retry logic.

Hooks: Extend Your SDK's Runtime Behavior

Hooks in liblab provide a dynamic way to modify SDK behavior at runtime without altering the generated source code. They allow custom logic to run before requests, after responses, or when errors occur. These hooks can also take additional parameters that are defined in liblab.config.json. This opens up many possibilities:

  • Pre-processing requests: Add headers, modify payloads, or log outbound calls.
  • Post-processing responses: Transform responses, track usage, or update internal state.
  • Error handling: Capture exceptions, retry under specific conditions, or notify monitoring tools.
  • Runtime Parameters: Pass parameters to hooks at runtime so their behavior can be changed based on the needs of each client.

Hooks are available in major programming languages supported by liblab, including TypeScript, Python, Java, C#, Go, PHP, and Terraform.

For example, you can inject a custom correlation ID into outgoing requests or wrap responses in a logging function for performance analysis.

Add Hooks to Your SDK

Before adding hooks to your project you'll need to initialize them by running:

liblab hooks add

This generates a hooks directory organized by language. You can then implement any combination of lifecycle hooks tailored to your needs.

Hooks must reside in the same directory as your liblab.config.json file. liblab bundles these hooks into the generated SDK, ensuring they are invoked at the correct stages.

A Hooks Example: Using Hooks for Tracking Client-side Performance

Here's an example in TypeScript to create custom actions post processing a response, ​​the HttpResponse class lives in the hook.ts file:

export interface HttpResponse<T> {
data?: T;
metadata: HttpMetadata;
raw: ArrayBuffer;
}

The afterResponse method is implemented in the CustomHook class in the custom-hook.ts file, in this example we wrap responses in a logging function for performance analysis. In a real world example this data could report to an application monitoring service.

// custom-hook.ts
public async afterResponse(request: HttpRequest, response: HttpResponse<any>, params: Map<string, string>): Promise<HttpResponse<any>> {
const startTime = performance.now();
const result = await response; // Wait for the original response

const endTime = performance.now();
const responseTimeMs = endTime - startTime;

console.log(`Request to ${request.url} took ${responseTimeMs.toFixed(2)}ms`); // Log performance

return {
data: result.data,
metadata: result.metadata,
raw: result.raw,
responseTimeMs: responseTimeMs, // Include response time in custom response
};
}

Flexibility at Runtime

One of the most powerful features within hooks is the ability to define additionalConstructorParameters. This allows injecting custom arguments into SDK constructors, providing runtime flexibility without hardcoding values.

Consider a scenario where different SDK consumers need different client ID strategies. With additionalConstructorParameters, you can pass these dependencies into the constructor and use them within your hooks.

Here's an example in TypeScript (using the liblab config file):

{
...
"additionalConstructorParameters": [
{
"name": "client-id",
"example": "myClientId"
},
{
"name": "client-secret",
"example": "an-example-client-secret"
}
]
...
}

And in your custom hook:

beforeRequest(request: HttpRequest, params: Map<string, string>): HttpRequest {
// Get the client Id and secret from the params
const clientId = params.get("clientId");
const clientSecret = params.get("clientSecret");
if (!clientId || !clientSecret) {
throw new Error("clientId and clientSecret are required");
}
return request;
}

This approach offers significant modularity, allowing SDK consumers to control behavior while leveraging a shared SDK.

Note: Parameters specified in the hooks files might be automatically adapted to match the casing conventions of the target programming language or to avoid collisions with other variables with the same name. For example, parameters will be converted to camelCase for TypeScript SDKs to adhere to idiomatic coding styles.

Pagination: Handling Large Datasets

liblab makes handling paginated API responses seamless by automatically adding pagination support to any endpoint in your specification file that returns data in chunks—like lists of users, products, or events. Beyond just out-of-the-box functionality, liblab also supports advanced customization for pagination, allowing you to define how your SDK handles large datasets.

You can configure parameters like default page size to match your API's behavior, ensuring efficient data retrieval and a smoother experience when working with high-volume responses. Then a user of your API could use something like the code below to request a list where up to 5 items are returned in each response and the first 3 items are skipped.

All of this is supported automatically without any additional work from you. As long as your endpoints support pagination, the generated SDK will implement it.

import { TypeScriptSdk } from 'typescript-sdk';

(async () => {
const typeScriptSdk = new TypeScriptSdk({
token: 'YOUR_TOKEN',
});

const pages = await typeScriptSdk.pokemon.pokemonList({
limit: 5,
offset: 3,
});

for await (const page of pages) {
console.log(page.data);
}
})();

Conclusion

liblab's SDK customization features provide unparalleled flexibility and control. By leveraging Hooks, additionalConstructorParameters, and built-in pagination support, developers can tailor SDKs to meet specific requirements, enhancing both functionality and user experience. Pagination, in particular, plays a crucial role in efficiently managing large datasets.

Combined with comprehensive documentation and clear best practices, liblab empowers developers to create robust, adaptable, and highly efficient SDKs that are optimized for both performance and developer experience.


Before you go, are you ready to transform your API strategy with automated SDK generation? Explore how liblab can help you generate consistent, high-quality SDKs across 6 programming languages from your OpenAPI specification. Your developers—and your budget—will thank you.Build an SDK For Any API

Hooks

Pagination

Customization

Best Practices

Software Engineering