Automate SDK generation for Remix APIs
Supported SDK languages:
TypeScript / Javascript | Java / Kotlin | Python | C# | Go | PHP |
---|---|---|---|---|---|
✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
- Before getting started make sure you have a liblab account and the liblab CLI installed.
- If you don't have an existing project but want to try out liblab then check out our standalone tutorials.
Providing an SDK for your API can significantly ease the development process for users, ensuring quicker integration and encouraging wider adoption due to the streamlined development experience.
In this doc you'll learn how to take your existing Remix API and generate user-friendly SDKs for most major programming languages using the liblab SDK generator. After a short bit of setup you'll have a pipeline that will automatically generate SDKs for your API whenever you make changes.
Initializing the SDK
First, create a new directory to store your SDK. This directory should be separate from your existing project directory:
mkdir Remix-sdk
cd Remix-sdk
And initialize your project to create a liblab.config.json
file:
liblab init -y
Getting an OpenAPI Spec File
In order to auto-generate SDKs from a Remix project, you need an OpenAPI Spec File. The OpenAPI specification is a standardized format that describes RESTful APIs, including endpoints, parameters, responses, and authentication methods.
Remix doesn't generate OpenAPI specs natively, but you can create and serve them using the swagger-jsdoc
package to generate OpenAPI specs based on JSDoc annotations in your API routes.
This guide will walk you through the steps to use swagger-jsdoc
to generate the OpenAPI spec from your Remix API.
Installation
To install the required packages, navigate to your Remix project directory and run:
npm install swagger-jsdoc
If you're using TypeScript, you can also install @types/swagger-jsdoc
package. They provide type definitions that enable autocompletion, type checking, and better integration with your editor.
npm install -D @types/swagger-jsdoc
Setting Up OpenAPI Configuration
After installation, you'll need to create a configuration file for swagger-jsdoc
, which you'll use to specify metadata about your API. Create a utils directory and a configuration file:
mkdir -p app/utils
touch app/utils/swagger.ts
Here are the key configuration options you can use:
info
: Define the API's title, description, version, and other metadata.servers
: Specify your API servers, such as production and development URLs.security
: Configure authentication mechanisms used by API operations.components
: Add reusable objects like schemas and security schemes.tags
: Group endpoints under categories for better organization.
You can use all properties defined in OpenAPI V3 to customize your OpenAPI spec.
The following code snippet shows a configuration example for the app/utils/swagger.ts
file:
import swaggerJSDoc from 'swagger-jsdoc';
import path from 'path';
// Get the root directory of the project
const rootDir = process.cwd();
const options = {
definition: {
openapi: '3.0.0',
info: {
title: 'My Remix Project API',
version: '1.0.0',
description: 'API documentation for Remix project',
contact: {
name: 'API Support',
email: '[email protected]'
},
license: {
name: 'MIT',
url: 'https://opensource.org/licenses/MIT'
}
},
servers: [
{
url: 'http://localhost:5173',
description: 'Development server',
},
{
url: 'https://api.example.com',
description: 'Production server',
},
],
components: {
securitySchemes: {
bearerAuth: {
type: 'http',
scheme: 'bearer',
bearerFormat: 'JWT',
},
},
schemas: {
User: {
type: 'object',
properties: {
id: {
type: 'string',
description: 'The user ID'
},
name: {
type: 'string',
description: 'The user name'
},
email: {
type: 'string',
description: 'The user email'
}
}
}
}
},
tags: [
{
name: 'Users',
description: 'Endpoints related to user operations'
}
]
},
// Path to API route files
apis: [path.join(rootDir, 'app/routes/**/*.{js,jsx,ts,tsx}')],
};
export const swaggerSpec = swaggerJSDoc(options);
You can customize the available options for your project. In addition, you don't need to add all the properties used in the example.
Annotating API Routes with JSDoc
You don't need to annotate every part of your API at once. You've already defined enough of your API to take the generated openapi.json
specification file. You can skip to the Serving the Spec section after defining the basic spec configuration.
This is an iterative process. You can always return to it later.
Remix allows you to create API endpoints in the app/routes
directory. To generate the best SDK and documentation possible for your SDK's users, you should provide additional metadata alongside the definitions of your endpoints. The metadata will be included in the generated OpenAPI spec. To document these endpoints for OpenAPI using swagger-jsdoc
, you must use JSDoc annotations.
When using JSDoc to add annotations, you can use all the properties available in OpenAPI. Here's a short list of these properties:
path
: The endpoint's URL pattern (e.g.,/api/users/{userId}
).- HTTP Method: The request method used (e.g.,
get
). operationId
: A unique identifier for the operation (e.g.,getUser
).summary
anddescription
: A brief summary and a detailed description of the endpoint's function.tags
: Categories to group related endpoints (e.g.,Users
).parameters
: Input values required by the endpoint (e.g.,name
as a path parameter).responses
: Possible responses, including status codes and schemas (e.g.,200
for a successful request).security
: Security mechanisms required for the endpoint.
The following code snippet shows how to define a example endpoint with JSDoc annotations:
/**
* @swagger
* /api/users/{userId}:
* get:
* operationId: getUser
* summary: Get user details
* description: Returns detailed information about a specific user.
* tags:
* - Users
* security:
* - bearerAuth: []
* parameters:
* - name: userId
* in: path
* required: true
* schema:
* type: string
* description: ID of the user
* responses:
* 200:
* description: User data
* content:
* application/json:
* schema:
* $ref: '#/components/schemas/User'
* example:
* id: "123"
* name: "User Name"
* email: "[email protected]"
* 404:
* description: User not found
* content:
* application/json:
* schema:
* type: object
* properties:
* error:
* type: string
* description: Error message explaining that the user was not found
* example:
* error: "User not found"
*/
import { json } from '@remix-run/node';
import type { LoaderFunctionArgs } from '@remix-run/node';
export const loader = async ({ params }: LoaderFunctionArgs) => {
const { userId } = params;
return json({ id: userId, name: 'User Name', email: '[email protected]' });
};
Serving the spec
By default, swagger-jsdoc
doesn't expose the OpenAPI spec automatically. You must create a new route to serve the OpenAPI spec as a JSON file. Create a new route for this purpose:
mkdir -p app/routes/api.openapi
touch app/routes/api.openapi/route.ts
Add the following code to serve the OpenAPI spec:
import { json } from '@remix-run/node';
import { swaggerSpec } from '../../utils/swagger';
export const loader = async () => {
return json(swaggerSpec);
};
Accessing the Documentation
Now start your Remix development server:
npm run dev
To view your OpenAPI spec, navigate to the /api/openapi
endpoint on your server (e.g., [http://localhost:3000/api/openapi](http://localhost:3000/api/openapi
)).
Click to see the OpenAPI spec example for the users
API.
{
"openapi": "3.0.0",
"info": {
"title": "My Remix Project API",
"version": "1.0.0",
"description": "API documentation for Remix project",
"contact": {
"name": "API Support",
"email": "[email protected]"
},
"license": {
"name": "MIT",
"url": "https://opensource.org/licenses/MIT"
}
},
"servers": [
{
"url": "http://localhost:5173",
"description": "Development server"
},
{
"url": "https://api.example.com",
"description": "Production server"
}
],
"components": {
"securitySchemes": {
"bearerAuth": {
"type": "http",
"scheme": "bearer",
"bearerFormat": "JWT"
}
},
"schemas": {
"User": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "The user ID"
},
"name": {
"type": "string",
"description": "The user name"
},
"email": {
"type": "string",
"description": "The user email"
}
}
}
}
},
"paths": {
"/api/users/{userId}": {
"get": {
"operationId": "getUser",
"summary": "Get user details",
"description": "Returns detailed information about a specific user.",
"tags": [
"Users"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "userId",
"in": "path",
"required": true,
"schema": {
"type": "string"
},
"description": "ID of the user"
}
],
"responses": {
"200": {
"description": "User data",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/User"
},
"example": {
"id": "123",
"name": "User Name",
"email": "[email protected]"
}
}
}
},
"404": {
"description": "User not found",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"error": {
"type": "string",
"description": "Error message explaining that the user was not found"
}
}
},
"example": {
"error": "User not found"
}
}
}
}
}
}
}
},
"tags": [
{
"name": "Users",
"description": "Endpoints related to user operations"
}
]
}
Copy your spec
Now save your openapi.json
file to the liblab project directory you created during the initializing step. This is typically something like:
cd ../Remix-sdk
curl -o openapi.json http://localhost:3000/api/openapi
Configuring liblab
Now you'll need to make some minor updates to your liblab.config.json
file in your Remix-sdk folder:
- Point the
specFilePath
parameter to the location of your OpenAPI spec file (ex../openapi.json
). - Specify the
baseUrl
of your API. This is the URL that the SDK will use to make requests to your API.
The top of the file should then looks something like this:
{
"sdkName": "Remix-sdk",
"apiVersion": "1.0.0",
"apiName": "Remix-api",
"specFilePath": "./openapi.json",
"baseUrl": "http://localhost:PORT",
"languages": [
"go",
"java",
"python",
"typescript",
"csharp",
"php"
],
"auth": [
"bearer"
]
}
liblab's SDK generator supports many more advanced URL and environment configuration options than the basic configuration shown here.
Explore the configuration documentation to discover all the available settings and enhancements or review the SDK customization options for tailored adjustments.
Generate the SDK
During build you might see warnings about the OpenAPI spec. These are often minor issues that can be fixed later.
Now that you have an OpenAPI spec file and have finished setting the liblab.config.json
file, it's time to generate our SDK:
liblab build -y
The CLI will validate the OpenAPI spec and notify you about any issues with it or the liblab.config.json
.
The output will look something like this:
✓ No issues detected in the liblab config file.
No hooks found, SDKs will be generated without hooks.
⚠ Validation succeeded with warnings
Created /Users/username/projects/Remix-sdk/output/api-schema-validation.json with the full linting results
Next you'll see the builds started and once they're done you'll see a message like this:
Your SDKs are being generated. Visit the liblab portal (https://app.liblab.com/apis/Remix-sdk/builds/1234) to view more details on your build(s).
✓ C# built
✓ Go built
✓ Java built
✓ PHP built
✓ Python built
✓ TypeScript built
✓ Generate package-lock.json for TypeScript
Successfully generated SDKs for Python, Java, Go, TypeScript, C#, PHP. ♡ You can find them inside: /Users/username/projects/Remix-sdk/output
If we go inside the output
directory, we will see a directory for each of our SDKs:
ls output/
api-schema-validation.json go php typescript
csharp java python
Try out your SDK
The following instructions assume you have already set up the respective development environment for the language you are testing. If necessary refer to each language's official documentation before proceeding.
Learn more about the language versions liblab generated SDKs support.
The generated SDKs are intended to be deployed to package managers for end users. The instructions below to test your SDK locally will differ from user-facing instructions.
- TypeScript / JavaScript
- Python
- Java
- C#
cd output/typescript/examples
npm run setup
npm run start
cd output/python/examples
chmod +x install.sh
./install.sh
source .venv/bin/activate
python3 sample.py
cd output/java/example
chmod +x run.sh
./run.sh
cd output/csharp/Example
dotnet run --framework net9.0
Next Steps
Now that you've packaged your SDKs you can learn how to integrate them with your CI/CD pipeline and publish them to their respective package manager repositories.
We currently have guides for: