Skip to main content

SDK customization options

The customizations section is used to customize your SDKs.

SettingTypeRequiredDefaultDescription
authenticationobjectN/ACustomization the API authentication settings
generateEnvbooltrueShould example .env files be generated?
licenseobjectN/AWhat license should the SDKs be covered under?
retryobjectN/ARetry functionality customization
injectedModelsarrayN/AA list of models to inject into their parent models
environmentVariablesarrayN/AA list of environment variables to inject into the SDKs
refreshTokenobjectN/ARefresh token customization
environmentsarrayN/AA list of deployment environments
inferServiceNamesboolfalseShould the SDKs infer service names from the spec?
responseHeadersboolfalseShould response headers be included in the response object.
devContainerboolfalseShould the generated SDKs contain the files to be able to run it as a dev container
includeOptionalSnippetParametersbooltrueShould optional parameters be included in the code snippets in generated documentation

authentication

Supported SDK languages and versions:

TypeScriptJavaPython v1Python v2C#Go

The authentication options allow you to configure the authentication that your API uses, that is set using the auth options. This section is an object with the following options:

OptionTypeRequiredDefaultDescription
accessobjectN/ACustom access token authentication options
apiKeyobjectN/AAPI key authentication options

You can read more on authentication in our authentication guide.

access

The access options allow you to configure the custom access token that is sent to your API when the auth option is set to custom. This section is an object with the following options:

OptionTypeRequiredDefaultDescription
prefixstringN/AThe prefix to use for the custom access token authentication

prefix

The prefix is used to define a custom prefix when using an access token. By default when using custom access token authentication, the Authorization header is passed as Bearer <token>. For example, if your bearer token is Passw0rd123!, the header would be:

HeaderValue
AuthorizationBearer Passw0rd123!

By setting the prefix, you can replace Bearer with the value of your choice.

For example, if you have the following:

{
...
"auth": [
"custom"
],
"customizations": {
"authentication": {
"access": {
"prefix": "Token"
}
}
}
...
}

Then the header would be:

HeaderValue
AuthorizationToken Passw0rd123!

apiKey

The apiKey option is used to configure the API key authentication for the SDKs. This is used if the auth setting is set to apikey. This is an object with the following options:

OptionTypeRequiredDefaultDescription
headerstringX-API-KEYThe header to use for the API key authentication

The header option sets the header to use for the API key authentication. This is used by the SDKs to set the header when making requests to the API. For example, if you have the following:

{
...
"customizations": {
"authentication": {
"apiKey": {
"header": "MY_CUSTOM_APIKEY_HEADER"
}
}
}
...
}

Then the API key will be passed to your API using the MY_CUSTOM_APIKEY_HEADER header.

If this is not set, then API keys by default will be passed using the X-API-KEY header.

generateEnv

Supported SDK languages and versions:

TypeScriptJavaPython v1Python v2C#Go

If this option is set to true, then an example .env file is created in the SDK with the name .env.example to set environment variables for authentication. This can be used by your SDK users to configure their environment variables.

For example, if you have an API that uses a bearer token then this will need to be passed to the SDK on initialization, and it is good practice for this to be read from an environment variable or other configuration instead of being hard coded.

In TypeScript you would initialize the SDK using code like this:

import { ExcitingSoda } from 'excitingsoda';

const sdk = new ExcitingSoda({ accessToken: process.env.EXCITINGSODA_ACCESS_TOKEN });

The EXCITINGSODA_ACCESS_TOKEN environment variable will be defined in the .env.example:

EXCITINGSODA_ACCESS_TOKEN=
info

The naming convention of .env.example is standard practice as .env files are normally not committed to source code control, and are usually ignored in .gitignore files.

license

Supported SDK languages and versions:

TypeScriptJavaPython v1Python v2C#Go

The license option sets the open source license for the SDKs, if wanted. This is used in the LICENSE file that is created with the SDKs, as well as in the package manifests (such as the TypeScript package.json or Java pom.xml files). This is an object with the following options:

OptionTypeRequiredDefaultDescription
typestringNONEThe type of license to use. If this is not set, the default is to not set a license
urlstring""The URL of a custom license if the type is set to CUSTOM

type

The type of license - such as one of a set of popular licenses, or a custom license.

Valid values are:

ValueDescription
MITMIT
GPL3GPL 3.0
APACHEApache 2.0
NONENo license information will be set
CUSTOMUse a custom license

For example, to use an MIT license for your SDK:

{
...
"customizations": {
"license": {
"type": "MIT"
}
},
...
}

If you set this to CUSTOM, then you will need to set the url to the URL of the license file to use.

url

The URL to a custom license file. The liblab CLI will need to be able to access this file, so the remote URL will need to be public, for example a source-available Business Source License (BSL) license available publicly on your website or in a public GitHub repo.

This is only used if the type option is set to CUSTOM. For example, to point the SDK to a custom license file, use the following:

{
...
"customizations": {
"license": {
"type": "CUSTOM",
"url": "https://exciting.soda/sdk/license.txt"
}
},
...
}

You can find a list of OSI approved licenses on the Open Source Initiative licenses page.

retry

Supported SDK languages and versions:

TypeScriptJavaPython v1Python v2C#Go

The retry setting is used to configure the retry functionality for the SDKs. This is an object with the following options:

OptionTypeRequiredDefaultDescription
enabledboolfalseShould retry functionality be enabled?
maxAttemptsinteger3The maximum number of attempts to retry
retryDelayinteger150The delay between retries in milliseconds

If this setting is not set, the SDKs will not have retry functionality enabled.

enabled

The enabled option determines whether or not retry functionality is enabled. If this is set to true, then the SDK will retry requests that fail due to network errors or server errors. If this is set to false, then the SDK will not retry requests.

maxAttempts

The maxAttempts option sets the maximum number of attempts to retry a request. For example, if this is set to 3, then the SDK will retry a request up to 3 times before giving up.

retryDelay

The retryDelay option sets the delay between retries in milliseconds. For example, if this is set to 150, then the SDK will wait 150 milliseconds between retries.

injectedModels

Supported SDK languages and versions:

TypeScriptJavaPython v1Python v2C#Go

When liblab generates an SDK, it creates models for the request and response objects, as well as the different schemas defined in the components section of the API spec. Some schemas are composed of other schemas, and these are by default created as separate models.

For example, if you have:

"Message": {
"properties": {
"message": {
"type": "string",
"title": "Message"
},
"body": {
"$ref": "#/components/schemas/MessageBody"
}
},
"type": "object",
},
"MessageBody": {
"properties": {
"details": {
"type": "string",
"title": "Details"
}
},
"type": "object"
}

Then the SDK will create 2 models, Messageand MessageBody. If you don't want the separate MessageBody model created, you can add "MessageBody" to the injectedModels array, and the MessageBody model will be injected into the Message model:

{
...
"customizations": {
"injectedModels": [
"MessageBody"
]
},
...
}

You will get the following:

export interface Message {
message: string;
body: Body;
}
interface Body {
details: string;
}

environmentVariables

Supported SDK languages and versions:

TypeScriptJavaPython v1Python v2C#Go

The environmentVariables setting allows you to define environment variables that need to be set by the SDK user for the SDK to work - for example if you need values set that are used in code you create in a hook.

This setting is an array of objects, with each object having the following options:

OptionTypeRequiredDefaultDescription
namestringN/AThe name of the environment variable
descriptionstringN/AThe value of the environment variable

These environment variables will be declared in the .env.example files that are created with each SDK (assuming this is enabled with the generateEnv setting). They will also be documented in the README for the SDK.

For example, if you have the following:

{
...
"environmentVariables" : [
{
"name": "TEAM_NAME",
"description": "The team name for the SDK user"
}
],
...
}

This will add the following to the .env.example file:

TEAM_NAME=

And the following to the README:

## Environment Variables

You will need the following environment variables in order to access all the features of this SDK:

| Name | Description |
| :-------- | :----------|
| TEAM_NAME | The team name for the SDK user |

name

The name for the environment variable.

description

The description for the environment variable. This is used for the README file only.

refreshToken

Supported SDK languages and versions:

TypeScriptJavaPython v1Python v2C#Go

The refreshToken setting is used to configure the refresh token functionality for the SDKs, to allow the SDK user to remain authenticated after their authentication expires. This is an object with the following options:

OptionTypeRequiredDefaultDescription
endpointstringN/AThe endpoint to use for refreshing the token
bearerKeystringN/AThe response property to use to get the bearer token from the response
refreshKeystringN/AThe response property to use to get the refresh token from the response

If your API supports refresh tokens for authentication, then this needs to be set. If this section is not set, then the SDKs will not have refresh token functionality enabled. You can read more about refresh tokens in our authentication guide.

These values need to match your spec - the endpoint needs to be defined as a supported path that can receive POST requests, and the bearerKey and refreshKey must be valid fields in the response from the endpoint.

endpoint

This is the endpoint to use to refresh the token.

bearerKey

The bearerKey is the name of the key in the response from the refresh token endpoint that contains the access token that the SDK can use to continue authenticating with the API.

For example, if this is the response from the endpoint that is defined in your API spec:

"RefreshTokenPair": {
"properties": {
"accessToken": {
"type": "string"
},
"refreshToken": {
"type": "string"
}
},
"required": [
"accessToken",
"refreshToken"
],
"type": "object"
},

Then the bearerKey should be set to accessToken:

{
"customizations": {
"refreshToken": {
...
"bearerKey": "accessToken"
}
}
}

refreshKey

The refreshKey is the name of the key in the response from the refresh token endpoint that contains the refresh token that the SDK can use to continue refreshing the access token with the API.

For example, if this is the response from the endpoint that is defined in your API spec:


"RefreshTokenPair": {
"properties": {
"accessToken": {
"type": "string"
},
"refreshToken": {
"type": "string"
}
},
"required": [
"accessToken",
"refreshToken"
],
"type": "object"
},

Then the refreshKey should be set to refreshToken:

{
"customizations": {
"refreshToken": {
...
"refreshKey": "refreshToken"
}
}
}

environments

Supported SDK languages and versions:

TypeScriptJavaPython v1Python v2C#Go

Your API may have multiple environments or locations, such as preview and production, or NorthAmerica, EMEA, and APAC. This setting allows you to configure environments to be added to the SDKs as constant values that are passed in when creating the SDK client.

This is an array of objects, with each object having the following options:

OptionTypeRequiredDefaultDescription
namestringN/AThe name of the environment
urlstringN/AThe URL for the environment

You can read more about configuring URLs and setting these at run time in our URLs and environments guide.

name

The name option sets the name of the environment. This is used as the name of the constant in the SDK, and is used when creating the SDK client. This name must not have any invalid characters that would not be allowed in constant names. For example, DevNA is valid, Dev NA is not.

url

The url option sets the URL for the environment. This is used as the value of the constant in the SDK, and is used when creating the SDK client. This is validated to ensure it is a valid URL.

inferServiceNames

Supported SDK languages and versions:

TypeScriptJavaPython v1Python v2C#Go

The inferServiceNames flag determines if service names for the SDK should be inferred from the endpoint names rather than tags if they all share a common prefix.

The OpenAPI specification has tags that are used to group service endpoints. For example:

tags:
- name: Boba
description: Operations for boba
- name: Soda
description: Operations for soda
paths:
"/boba":
get:
tags:
- Boba
...
"/boba/{id}":
post:
tags:
- Boba
...
"/soda":
get:
tags:
- Soda
...

In this case, the Boba tag is used to group the GET and POST operations for the /boba endpoints, and the Soda tag is used for the /soda endpoint. Using tags means the services in your SDK will be created based on these tags - for example in this case you would have a BobaService with methods to get and post boba, and a SodaService with a method to get soda.

tags are optional, so you many not have these defined in your spec. You may also have a common prefix to your endpoint, such as a version number:

paths:
"/v2/boba":
get:
...
"/v2/boba/{id}":
post:
...
"/v2/soda":
get:
...

In this case the liblab CLI would default to creating a V2Service service with methods to get and post boba, and get soda. This may not be what you want, you may want to have a BobaService and SodaService service instead.

To avoid this set the inferServiceNames option to true to infer the service names from the endpoint paths.

{
...
"customizations": {
"inferServiceNames": true
},
...
}

In this case, this would look at all the endpoints, and if they have a common prefix, then this would be ignored for the service names. Instead of a V2Service service, you would get a BobaService and SodaService.

This only works if your endpoints all have the same common prefix. For example, if you have some endpoints that are v2 and some that are v3 then service names cannot be inferred, as this may lead to name clashes (for example both services having a GET endpoint for boba). In this case, it is recommended to use tags in your OpenAPI spec.

responseHeaders

Supported SDK languages and versions:

TypeScriptJavaPython v1Python v2C#Go
note

Response headers are currently always included in the Go SDKs.

When responses come back from API calls, they can contain data, as well as important information in the headers. By default, the SDKs will only return the data from the response, and ignore the headers. If you want to include the headers in the response, then set this option to true.

For example, if you have a response object like this:

paths:
/soda/{id}:
get:
operationId: getSoda
parameters:
- name: id
in: path
required: true
description: The id of the soda
schema:
type: string
responses:
'200':
description: Expected response to a valid request
content:
application/json:
schema:
$ref: '#/components/schemas/Soda'
components:
schemas:
Soda:
type: object
properties:
name:
type: string
id:
type: string

If the response headers option is not set, or set to false, then the generated getSoda method will look like this:

async getSoda(id: string): Promise<Soda> {
...
}

If you set the response headers option to true:

{
...
"customizations": {
"responseHeaders": true
},
...
}

The the return values from calls to the SDK services will be a wrapper object containing the response data, as well as a dictionary of the headers. The getSoda method will look like this:

async getSoda(id: string): Promise<Response<Soda>> {

With the Response<T> type looking like this:

export default interface Response<T> {
data: T;
headers: Record<string, string>;
}

If this call returned a header such as Content-Range, this would be in the headers dictionary.

devContainer

Supported SDK languages and versions:

TypeScriptJavaPython v1Python v2C#Go

The devContainer option determines if the generated SDKs should include the files to be able to open and run the SDK using a dev container.

A dev container is a development environment setup that is containerized using technologies like Docker, making it consistent and reproducible across different development machines. It contains everything needed for the development environment, including the programming language, dependencies, libraries, tools and extensions.

If you set this to true, every SDK generated will include a devcontainer.json file, allowing you to start using the SDK as soon as it's produced from inside any IDE that supports development containers, such as VS Code. Additionally, each SDK will have a VS Code launch.json file so you can run and debug the SDK example.

{
...
"customizations": {
"devContainer": true
},
...
}

You can read more on development containers in the development containers documentation.

includeOptionalSnippetParameters

TypeScriptJavaPython v1Python v2C#Go

The includeOptionalSnippetParameters option determines if optional and deprecated parameters should be included in the code snippets in generated documentation or not.

If this is set to true (the default), then optional parameters will be included in the code snippets in the generated documentation. If this is set to false, then optional parameters will not be included in the code snippets in the generated documentation.

For example, if you have an endpoint with an optional parameter:

paths:
/llamas:
get:
operationId: getAllLlamas
description: Retrieve a list of all llamas
parameters:
- name: age
in: query
description: Age of the llamas to get
example: 5
required: false
schema:
type: integer

With this option set to true, the code snippets in the generated documentation will include the optional parameter:

const result = await sdk.llamas.getAllLlamas({ age: 5 });

If this option is set to false, the code snippets in the generated documentation will not include the optional parameter:

const result = await sdk.llamas.getAllLlamas();