Generating API clients
Compas supports generating API clients for all previously mentioned targets. There are two main ways to get started with API client generation
- Based on an OpenAPI specification
- Based on a (remote) Compas structure
Importing an OpenAPI specification
To import an OpenAPI specification, make sure it is in JSON instead of YAML. Then it can be converted to a Compas structure and added to the generator.
js
import { readFileSync } from "fs";
import { loadApiStructureFromOpenAPI } from "@compas/code-gen";
import { Generator } from "@compas/code-gen/experimental";
const generator = new Generator();
const spec = JSON.parse(readFileSync("./specs/openapi.json", "utf-8"));
generator.addStructure(loadApiStructureFromOpenAPI("pet", spec));
Compas (remote) structure
Loading a Compas structure works almost the same as loading an OpenAPI specification.
js
import { readFileSync } from "fs";
import { loadApiStructureFromRemote } from "@compas/code-gen";
import { Generator } from "@compas/code-gen/experimental";
const generator = new Generator();
const structure = JSON.parse(
readFileSync("./src/generated/common/structure.json", "utf-8"),
);
// Or loading from remote. This will call `/_compas/structure.json`.
// const structure = await loadApiStructureFromRemote(Axios, "https://compasjs.com/");
generator.addStructure(structure);
Generating
After adding a structure to the generator it is time to generate.
js
const generator = new Generator();
// ...
generator.addStructure(/* ... */);
generator.generate({
targetLanguage: "ts",
outputDirectory: "./src/generated",
generators: {
apiClient: {
target: {
library: "axios",
targetRuntime: "browser",
globalClient: true,
},
},
},
});
js
const generator = new Generator();
// ...
generator.addStructure(/* ... */);
generator.generate({
targetLanguage: "ts",
outputDirectory: "./src/generated",
generators: {
apiClient: {
target: {
library: "axios",
targetRuntime: "browser",
includeWrapper: "react-query",
globalClient: true,
},
},
},
});
js
const generator = new Generator();
// ...
generator.addStructure(/* ... */);
generator.generate({
targetLanguage: "js",
outputDirectory: "./src/generated",
generators: {
apiClient: {
target: {
library: "axios",
targetRuntime: "node.js",
globalClient: true,
},
},
},
});
Executing the script should give you a bunch of files in ./src/generated
. Using the newly created API client is now only a quest for calling the correct function to use.
tsx
import { useQuery } from "@tanstack/react-query";
import { apiUserList } from "src/generated/user/apiClient";
function MyComponent() {
const { data } = useQuery({
queryFn: () =>
apiUserList({
offset: 0,
limit: 10,
}),
});
}
tsx
import { useUserList } from "src/generated/user/reactQueries";
function MyComponent() {
const { data } = useUserList({
query: {
offset: 0,
limit: 10,
},
});
}
js
import { apiUserList } from "../generated/user/apiClient.js";
async function getFilteredUsers() {
return await apiUserList(
{ offset: 0, limit: 10 },
{
filters: {
emailStartsWith: "foo",
},
},
);
}