Skip to content

Generate a q client

Create a q client SDK from an OpenAPI specification

The client walkthrough for Java and JavaScript used Swagger Codegen directly. Here we use our q generator. There are two ways:

  • run a JAR natively on a machine with Java installed
  • run as a Docker image

The corresponding commands to run the generator:

java -jar kxi-openapi-codegen-<version>-shaded.jar <command line args>
docker run --rm -v $PWD:/opt/kx registry.dl.kx.com/kxi-openapi-codegen:<version> <command line args>

In the examples we refer to this generically as gen-cmd for ‘generator command’. Substitute one of the versions above, Java or Docker.

The Docker command mounts in a volume so that the files created by the generator are accessible from outside the container. When generating clients the -o flag should point to somewhere inside the mounted volume.

This generator supports the same versions of the OpenAPI specification as the equivalent swagger-codegen-cli version. To view it:

gen-cmd version

Generate a client

Here we use the Petstore example.

We can generate a client from the Petstore swagger.json:

gen-cmd generate -l q \
  -i https://petstore.swagger.io/v2/swagger.json \
  -o /opt/kx/qpetstore

For the example, -o is under /opt/kx to match the volume mounted into the Docker container. If running locally, this could be any path.

YAML specifications

Currently, generating a client from a specification via URL supports only JSON specifications.

To use a YAML specification, download the file locally and reference it with -i.

This generates a q SDK for the Petstore API in the folder qpetstore.

Inside qpetstore, a README explains how to set up the SDK for use:

Set up the client

cd qpetstore
chmod +x setup.sh
./setup.sh
Docker permissions

When using Docker, qpetstore will be owned by root, so you may need to change ownership for these commands to succeed.

Build and run the client

Use QPacker to build the client:

qp build && qp run

This loads a .com_kx_api namespace.

q)key `.com_kx_api
``home`modelHome`basePath`cfg`setBasePath`init`headerName`request`getArgsFrom..

Initialize the generated library:

.com_kx_api.init[`.pets]

This loads the generated code into the .pets namespace.

q)key .pets
``help`addPet`deletePet`findPetsByStatus`findPetsByTags`getPetById`updatePet`..

Each path in the OpenAPI specification has a corresponding function. The help dictionary tells you what arguments each function takes. These are grouped by the tags field from the OpenAPI spec.

q).pets.help`pet
operation         arg                dataType
---------------------------------------------
addPet            body               pet     
deletePet         petId              Long    
deletePet         apiKey             String  
findPetsByStatus  status             #any    
findPetsByTags    tags               #any    
getPetById        petId              Long    
updatePet         body               pet     
updatePetWithForm petId              Long    
updatePetWithForm name               String  
updatePetWithForm status             String  
uploadFile        petId              Long    
uploadFile        additionalMetadata String  
uploadFile        file               byte[]  

Each function takes two dictionary arguments: args and opts.

args are the arguments required for the HTTP request. For example, for findPetsByStatus

q).pets.findPetsByStatus[enlist[`status]!enlist `available; ()!()]
"[{\"id\":9223127596080634282,\"category\":{\"id\":0,\"name\":\"string\"},\"n..

For getPetsById:

q).j.k .pets.getPetById[enlist[`petId]!enlist 9223127596080634282; ()!()]
id       | 9.223128e+18
category | `id`name!(0f;"string")
name     | "fish"
photoUrls| ,"string"
tags     | +`id`name!(,0f;,"string")
status   | "available"

opts is a dictionary of options in the generated API itself, not directly part of the OpenAPI specification.

Supported options:

  • useAsync: whether to use an async request
  • any other options that can be passed as part of the options parameter in the Kurl requests API

We could make the same getPetById call as before using an async request:

q).pets.getPetById[enlist[`petId]!enlist 9223127596080634282; `useAsync`callback!(1b; {show x})]
200i
"{\"id\":9223127596080634282,\"category\":{\"id\":0,\"name\":\"string\"},\"na..

To make a request that requires a body, pass it as part of the body key in the args parameter. This must be in the raw format expected by the server – most likely a JSON object.

Base path of the API

If generating a client for an OpenAPI specification that does not define a list of servers, you can set the base path of the API using .com_kx_api.basePath.

In our Petstore example this is automatically set by the generator.

q).com_kx_api.basePath
"https://petstore.swagger.io/v2"