Operation Functions
Each API operation in the spec produces a single APL function file at:
APLSource/_tags/<tag>/<OperationId>.aplf
These functions are the primary interface for making API calls. They are accessed through the Client class as client.<tag>.<OperationId>. Operations with no tag in the spec are placed under _tags/default/ and accessed as client.default.<OperationId>.
Function signature
response ← OperationId argsNs
The right argument argsNs is a namespace whose fields correspond to the operation's parameters. The return value is the HttpCommand response namespace, unless mock is set — see Mock mode.
Passing parameters
All parameters — path, query, header, and body — are passed as fields on the argsNs namespace. This includes parameters the spec declares for every operation on a path, as well as those declared for the operation itself:
response ← client.user.GetById (id: 42)
For operations with no parameters, pass an empty namespace:
response ← client.user.List ()
A parameter whose name is not a valid APL name is passed under its mangled name, formed in the same way as Dyalog's JSON name mangling: the name is prefixed with ⍙, and each invalid character is replaced with ⍙<UCS code>⍙. The original name is used in the request. For example, an X-Request-ID header is passed as ⍙X⍙45⍙Request⍙45⍙ID, and a page[size] query parameter as ⍙page⍙91⍙size⍙93⍙:
response ← client.user.List (⍙page⍙91⍙size⍙93⍙: 50)
The pages generated in docs/ give the name to use for each parameter.
Path parameters
Path parameters are always required. The value must be a character vector or a scalar number — anything else signals an error. Numbers are written as in JSON (-0.5, not ¯0.5), and the value is percent-encoded, so a value containing /, ? or a space stays within its own path segment.
The path parameters are those named in the path, such as {petId} in /pets/{petId}. If the spec does not declare one, it is still required, as a string.
Query and header parameters
These are read from argsNs by name. Required parameters signal an error if absent; optional parameters are simply omitted from the request if not set on the namespace. Numbers in query parameters are written as in JSON, as for path parameters.
An array query parameter that the spec declares with explode: false is sent as one value, its items joined by the delimiter for its style: , for form (the default), a space for spaceDelimited, | for pipeDelimited. Pass a vector of strings or numbers, or a single string:
response ← client.weather.GetForecast (latitude:'51.5' ⋄ longitude:'-0.12' ⋄ hourly:'temperature_2m' 'rain')
⍝ GET /v1/forecast?hourly=temperature_2m%2Crain&latitude=51.5&longitude=-0.12
Request body
How the body parameter is named on argsNs depends on the content type declared in the spec:
| Content type | Field name on argsNs |
|---|---|
application/json |
Named after the body's schema in camelCase — see below |
application/octet-stream |
body |
multipart/form-data |
One field per form field — see Multipart form fields below |
| Other | data |
A JSON body's field depends on its schema:
| Schema | Field name | Value |
|---|---|---|
A named object schema, e.g. User |
user |
A namespace, or a models.User instance |
An array of a named schema, e.g. of User |
user |
A vector of namespaces or models.User instances |
A named schema that is an array, e.g. UserList, an array of User |
userList |
A vector of namespaces or models.User instances |
A named schema that is anything else, e.g. Note, a string |
note |
Any value that ⎕JSON can convert |
| An object defined in the operation itself, including a free-form one | <operationId>Request, e.g. createUserRequest |
A namespace, or an instance of the model generated for it |
| An array of objects defined in the operation itself | <operationId>RequestItem |
A vector of namespaces or instances of the model generated for them |
| Anything else defined in the operation itself (a string, an array of strings, …) | body |
Any value that ⎕JSON can convert |
An optional request body that is not given is left out of the request altogether, with no Content-Type header.
For example, for an operation that takes a User:
⍝ A namespace…
response ← client.user.CreateUser (user: (name: 'Ada' ⋄ email: 'ada@example.com'))
⍝ …or a model instance, which checks required fields and enum values as it is built
user ← ⎕NEW models.User (name: 'Ada' ⋄ email: 'ada@example.com')
response ← client.user.CreateUser (user: user)
The page generated in docs/ for each tag shows the fields of each request body.
Multipart form fields
For multipart/form-data operations, each form field in the spec becomes a field on argsNs. The value of each field follows the HttpCommand multipart convention: it is either a simple value (e.g. a character vector) or a 1–3 element vector of:
(content) (mime-type) (filename)
mime-type and filename are optional.
HttpCommand sends each form field under its name in the namespace, so a field whose name is not a valid APL name (such as include[]) cannot be sent; supplying it signals an error. For the same reason, a form field that is an array cannot be sent as repeated parts. For file uploads, content may be a file path prefixed with:
@— upload the file's content and include its original filename in the request<— upload only the file's content, omitting the filename
When no MIME type is given, HttpCommand defaults to 'text/plain' for .txt files and 'application/octet-stream' for all others.
Function name derivation
The function name is derived from the operationId in the spec:
- The
operationIdis converted to PascalCase (e.g.list_users→ListUsers) - Any characters not valid in an APL identifier are replaced using delta-underbar escaping: the name is prefixed with
⍙, and each invalid character is replaced with⍙<UCS code>⍙. This functions in a similar manner to Dyalog's JSON name mangling.
Most well-formed operationId values produce a plain PascalCase name with no escaping.