Skip to main content

Comlink Map Reference

Comlink Map is a format for describing how an API provider's services map to the use-cases in a Comlink Profile.

Map Details

  • profile - the profile identifier to which the map corresponds
    • can be written without version: starwars/character-information
    • can be written with version omitting the patch number: starwars/character-information@1.1
  • provider - corresponds to the provider identifier found in the Provider Definition
  • variant (optional) - allows for multiple maps for the same profile and provider
Map details example
profile = "conversation/send-message"
provider = "some-telco-api"

map SendMessage {
...
}

map RetrieveMessageStatus {
...
}

Use-Case Maps

Map to a use-case using the map <use-case-name> statement. Use-cases may define and expect inputs from the user. These inputs are defined in the profile. A Use-Case Map can have multiple HTTP Calls defined within it.

HTTP Call

The HTTP Call uses http and defines the information needed to make a call and map the inputs, result, and error to the profile use-cases.

The example below shows an HTTP Call that uses the HTTP method POST and the URI template /api/messages.

HTTP transaction example
profile = "<profile-name>@<version>"
provider = "<provider-name>"

map UseCaseName {
http POST "/api/messages" {

}
}

HTTP Security

You can define the security requirements for an HTTP transaction that align with the security schemes in a provider definition. If no security requirement is provided, the default is none. The security requirement is enclosed within double quotes ".

This example shows a POST HTTP call to the provider's default service on path /api/messages.

Default security requirement
http GET "/public-endpoint" {
security "api_key_scheme_id"

response {
# ...
}
}

HTTP Request

The HTTP Request uses request and is optional. It defines the request for the HTTP Transaction. It can include URL query parameters, HTTP headers, and a body. It can also include the content type and specify different services included in the provider definition.

This shows an example of an HTTP request.

HTTP Request example with content type
profile = "<profile-name>@<version>"
provider = "<provider-name>"

map UseCaseName {
http POST "/api/messages" {
security "scheme-id"

request "application/json" {
query {
from = input.from
}

body {
to = input.to
text = input.text
}
}
}
}

The definition makes a call to /api/messages?from=... with body of content type application/json including object with two parameters to and text.

Path Parameters

You can reference variables in URI template with {variable} syntax. This is a simple variable substitution, non-string values are converted to their JSON equivalents.

Path parameter
http GET "/messges/{input.id}" {
response {
# ...
}
}

Query Parameters

A query maps query parameters to their values. Variables are accessible here, so input may be used to map profile inputs to query parameters.

This example shows how to map an HTTP Request with a myName query parameter to the value "John".

Query parameter
http GET "/greeting" {
request {
query {
myName = "John"
}
}
}

HTTP Headers

The headers property maps HTTP headers to their values. Variables are accessible here, so input may be used to map profile inputs to HTTP headers. If an HTTP header name contains a hyphen, enclose the name in double quotes.

HTTP Headers
http POST "/users" {
request "application/json" {
headers {
"my-header" = 42
}
}
}

HTTP Request Body

The body property maps body properties to their values.

This example shows a request body mapped to an object.

HTTP Request Body object
http POST "/users" {
request "application/json" {
body = {
key = 1
}
}
}

Arrays may also be used.

HTTP Request Body array
http POST "/users" {
request "application/json" {
body = [1, 2, 3]
}
}

HTTP Response

An HTTP Response describes the responses for a transaction that map the response to the profile's result or error. An HTTP Transaction can have multiple responses based on HTTP status codes and content types. This allows for handling many different types of responses and mapping them into the use-case's result and error definitions.

A response has a:

  • status code
  • content type
  • content language (optional)
  • response block

Response variables

The following variables are available in a response block. These can be used to map response data to use-case results or errors. They can also be used to conditionally map to results or errors.

  • statusCode (number): HTTP response status code
  • headers (object): HTTP response headers
  • body (object): HTTP response body

This example shows where response variables are available.

Accessing variables in a response block
profile = "<profile-name>@<version>"
provider = "<provider-name>"

map UseCaseName {
http POST "/api/messages" {
security "scheme-id"

request "application/json" { /* ... */ }

response 201 "application/json" {
// code in this block can reference `statusCode`, `headers` and `body`
}
}
}

Map a Use-Case Result

You can map to a use-case result using a map result statement. You must resolve the same result as defined in the use-case.

Mapping to a use-case result
profile = "<profile-name>@<version>"
provider = "<provider-name>"

map UseCaseName {
http POST "/api/messages" {
security "scheme-id"

request "application/json" { /* ... */ }

response 201 "application/json" {
map result {
messageId = body.message_sid
remainingMessages = headers["X-CREDIT-LEFT"] / 0.3
}
}
}
}

The above definition maps the two expected result fields. One from the response's body and the other is from the headers, which is then transformed with a Comlink expression.

Map to a Use-Case Error

You can also map a response to a use-case error using the map error statement. Like when mapping to a result, you must resolve the same error as defined in the use-case.

<profile-name>.<provider-name>.suma
profile = "<profile-name>@<version>"
provider = "<provider-name>"

map UseCaseName {
http POST "/api/messages" {
security "scheme-id"

request "application/json" { /* ... */ }

response 201 "application/json" { /* ... */ }

response 429 {
map error {
title = "Sending messages too frequently"
details = (`You can send more message after ${headers['Retry-After']} seconds`)
}
}
}
}

This maps to the two expected error fields when the server responds with status 429 (Too Many Requests). One is hardcoded as it describes the error scenario, the other constructs a helpful message with a value from response headers using a simple Comlink expression.

note

map error Comlink statement and can happen from anywhere inside the use-case mapping, not only from an inside of the response handler.

Multiple Response Mappings

You may map multiple responses in a single HTTP Transaction. This is how to match different status codes for a single request.

The example belows shows a single POST with responses for multiple success and error HTTP Responses.

Multiple Response Mappings
profile = "communication/send-email@1.1"
provider = "postmark"

map SendEmail {
http POST "/email" {
security "server_token"

request "application/json" {
body {
From = input.from
To = input.to
Subject= input.subject
TextBody = input.text
HtmlBody = input.html
}
}

response 200 "application/json" {
map result {
messageId = body.MessageID
}
}

response 422 "application/json" {
map error {
title = "Invalid inputs"
detail = body.Message
}
}

response 401 "application/json" {
map error {
title = "Unauthorized"
detail = body.Message
}
}

response 403 "application/json" {
map error {
title = "Forbidden"
detail = body.Message
}
}

response 500 "application/json" {
map error {
title = "Internal server Error"
detail = body.Message
}
}
}
}

Conditional Response Mappings

Sometimes more conditions are needed to map HTTP responses to the profile results and errors. For this, you can conditionally handle mappings.

This example shows how to map a result if body.ok is truthy or map an error if body.ok is falsey.

Conditionally handling responses
http POST "/users" {
response 201 "application/json" {
map result if(body.ok) {
...
}

map error if(!body.ok) {
...
}
}
}

Specification

There are more features of the Comlink Map. Please refer to the specifications for more information.

Examples