Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add Unified REST API docs #3919

Merged
merged 9 commits into from
Jun 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
548 changes: 548 additions & 0 deletions api/camunda/camunda-openapi.yaml

Large diffs are not rendered by default.

48 changes: 48 additions & 0 deletions api/camunda/generation-strategy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
const removeDuplicateVersionBadge = require("../remove-duplicate-version-badge");
const replace = require("replace-in-file");
const outputDir = "docs/apis-tools/camunda-api-rest/specifications";
const specFile = "api/camunda/camunda-openapi.yaml";

function preGenerateDocs() {
hackChangesetDescription();
}

function postGenerateDocs() {
removeDuplicateVersionBadge(`${outputDir}/camunda-8-rest-api.info.mdx`);
}

module.exports = {
outputDir,
preGenerateDocs,
postGenerateDocs,
};

function hackChangesetDescription() {
// This is a temporary hack, until https://github.com/camunda/camunda-docs/issues/3568 is resolved.
// The OpenAPI generator plugin we're using does not use the correct `description` property
// for the `UserTaskUpdateRequest` object. Instead of picking up the actual property description,
// it picks up the description of the first merged schema in the `allOf` property (i.e. from the `Changeset` schema).
// This adjustment replaces the description of the `Changeset` schema with the current description of
// the `UserTaskUpdateRequest.changeset` property.
console.log("hacking changeset description...");
replace.sync({
files: `${specFile}`,
from: /^ description: A map of changes.$/m,
to: ` description: |
JSON object with changed task attribute values.

The following attributes can be adjusted with this endpoint, additional attributes
will be ignored:

* \`candidateGroups\` - reset by providing an empty list
* \`candidateUsers\` - reset by providing an empty list
* \`dueDate\` - reset by providing an empty String
* \`followUpDate\` - reset by providing an empty String

Providing any of those attributes with a \`null\` value or omitting it preserves
the persisted attribute's value.

The assignee cannot be adjusted with this endpoint, use the Assign task endpoint.
This ensures correct event emission for assignee changes.`,
});
}
2 changes: 2 additions & 0 deletions api/generate-api-docs.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ const { execSync } = require("child_process");
const operate = require("./operate/generation-strategy");
const zeebe = require("./zeebe/generation-strategy");
const tasklist = require("./tasklist/generation-strategy");
const camunda = require("./camunda/generation-strategy");
const apiStrategies = {
operate,
zeebe,
tasklist,
camunda,
};

// Execute a command as if we were in the terminal
Expand Down
12 changes: 0 additions & 12 deletions api/zeebe/generation-strategy.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,3 @@ function hackChangesetDescription() {
This ensures correct event emission for assignee changes.`,
});
}

function removeDuplicateVersionBadge() {
// The generator adds a version badge to the Introduction file, but
// we already have a version badge from the main docs layout.
console.log("removing duplicate version badge...");
replace.sync({
files:
"docs/apis-tools/zeebe-api-rest/specifications/zeebe-rest-api.info.mdx",
from: /^.*Version: .*$/m,
to: "",
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
---
id: camunda-api-rest-authentication
title: "Authentication"
description: "Step through authentication options that can be used to access Camunda 8 REST API."
---

To access the API endpoint, you need an access token.

Your client must send a header in each request:

`Authorization: Bearer <Token>`

For example, send a request using _curl_:

```shell
curl -XGET -H'Accept: application/json' -H'Authorization: Bearer <TOKEN>' http://localhost:8080/v2/topology
```

### How to obtain the access token

You must obtain a token to use the Camunda 8 REST API. When you create a Zeebe [client](/guides/setup-client-connection-credentials.md), you get all the information needed to connect to Zeebe.

Refer to our guide on [building your own client](../build-your-own-client.md).

The following settings are needed:

| Name | Description | Default value |
| ------------------------ | ----------------------------------------------- | ------------------ |
| client id | Name of your registered client | - |
| client secret | Password for your registered client | - |
| audience | Permission name; if not given use default value | `zeebe.camunda.io` |
| authorization server url | Token issuer server | - |

Send a token issue _POST_ request to the authorization server with the following content:

```json
{
"client_id": "<client-id>",
"client_secret": "<client-secret>",
"audience": "<audience>",
"grant_type": "client_credentials"
}
```

Refer to the following example with _curl_:

```shell
curl -X POST --header 'content-type: application/json' --data '{"client_id": "<client-id>", "client_secret":"<client-secret>","audience":"<audience>","grant_type":"client_credentials"}' https://<authorization server url>
```

If the authentication is successful, the authorization server sends back the access token, when it expires, scope, and type:

```json
{
"access_token": "ey...",
"scope": "...",
"expires_in": 86400,
"token_type": "Bearer"
}
```
27 changes: 27 additions & 0 deletions docs/apis-tools/camunda-api-rest/camunda-api-rest-overview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
id: camunda-api-rest-overview
title: "Overview"
description: "Interact with Camunda 8 clusters. Activate jobs and run user task state operations for Zeebe user tasks."
---

The Camunda 8 REST API is a REST API designed to interact with a Camunda 8 cluster.

:::note
Ensure you [authenticate](./camunda-api-rest-authentication.md) before accessing the Camunda 8 REST API.
:::

## Context paths

For SaaS: `https://${REGION}.zeebe.camunda.io:443/${CLUSTER_ID}/v2/`, and for Self-Managed installations: `http://localhost:8080/v2/`.

:::note
Find your region and cluster id under **Connection information** in your client credentials (revealed when you click on your client under the **API** tab within your cluster).

For Self-Managed, the host and port depend on your configuration. The context path mentioned here is the default for the Zeebe component.
:::

## API Explorer

See [the interactive Camunda 8 REST API Explorer][camunda-api-explorer] for specifications, example requests and responses, and code samples of interacting with the Camunda 8 REST API.

[camunda-api-explorer]: ./specifications/camunda-8-rest-api.info.mdx
11 changes: 11 additions & 0 deletions docs/apis-tools/camunda-api-rest/sidebar-schema.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */

module.exports = {
"Camunda 8 API (REST)": [
"apis-tools/camunda-api-rest/camunda-api-rest-overview",
"apis-tools/camunda-api-rest/camunda-api-rest-authentication",
{
Specifications: require("./specifications/sidebar.js"),
},
],
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
---
id: activate-jobs
title: "Activate jobs"
description: "Iterate through all known partitions and activate jobs up to the requested maximum."
sidebar_label: "Activate jobs"
hide_title: true
hide_table_of_contents: true
api: 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
sidebar_class_name: "post api-method"
info_path: docs/apis-tools/camunda-api-rest/specifications/camunda-8-rest-api
custom_edit_url: null
hide_send_button: true
---

import ApiTabs from "@theme/ApiTabs";
import DiscriminatorTabs from "@theme/DiscriminatorTabs";
import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import SecuritySchemes from "@theme/ApiExplorer/SecuritySchemes";
import MimeTabs from "@theme/MimeTabs";
import ParamsItem from "@theme/ParamsItem";
import ResponseSamples from "@theme/ResponseSamples";
import SchemaItem from "@theme/SchemaItem";
import SchemaTabs from "@theme/SchemaTabs";
import Markdown from "@theme/Markdown";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";

<h1 className={"openapi__heading"}>Activate jobs</h1>

<MethodEndpoint method={"post"} path={"/jobs/activation"}></MethodEndpoint>

Iterate through all known partitions and activate jobs up to the requested maximum.

## Request

<MimeTabs className={"openapi-tabs__mime"}><TabItem label={"application/json"} value={"application/json-schema"}><details style={{}} className={"openapi-markdown__details mime"} data-collapsed={false} open={true}><summary style={{}} className={"openapi-markdown__details-summary-mime"}><h3 className={"openapi-markdown__details-summary-header-body"}>Body</h3><strong className={"openapi-schema__required"}>required</strong></summary><div style={{"textAlign":"left","marginLeft":"1rem"}}></div><ul style={{"marginLeft":"1rem"}}><SchemaItem collapsible={false} name={"type"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"description":"the job type, as defined in the BPMN process (e.g. <zeebe:taskDefinition type=\"payment-service\" />)\n","type":"string"}}></SchemaItem><SchemaItem collapsible={false} name={"worker"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"description":"the name of the worker activating the jobs, mostly used for logging purposes","type":"string"}}></SchemaItem><SchemaItem collapsible={false} name={"timeout"} required={false} schemaName={"int64"} qualifierMessage={undefined} schema={{"description":"a job returned after this call will not be activated by another call until the timeout (in ms) has been reached\n","type":"integer","format":"int64"}}></SchemaItem><SchemaItem collapsible={false} name={"maxJobsToActivate"} required={false} schemaName={"int32"} qualifierMessage={undefined} schema={{"description":"the maximum jobs to activate by this request","type":"integer","format":"int32"}}></SchemaItem><SchemaItem collapsible={false} name={"fetchVariable"} required={false} schemaName={"string[]"} qualifierMessage={undefined} schema={{"description":"a list of variables to fetch as the job variables; if empty, all visible variables at the time of activation for the scope of the job will be returned\n","type":"array","items":{"type":"string"}}}></SchemaItem><SchemaItem collapsible={false} name={"requestTimeout"} required={false} schemaName={"int64"} qualifierMessage={undefined} schema={{"description":"The request will be completed when at least one job is activated or after the requestTimeout (in ms). If the requestTimeout = 0, a default timeout is used. If the requestTimeout < 0, long polling is disabled and the request is completed immediately, even when no job is activated.\n","type":"integer","format":"int64"}}></SchemaItem><SchemaItem collapsible={false} name={"tenantIds"} required={false} schemaName={"string[]"} qualifierMessage={undefined} schema={{"description":"a list of IDs of tenants for which to activate jobs","type":"array","items":{"type":"string"}}}></SchemaItem></ul></details></TabItem></MimeTabs><div><div><ApiTabs label={undefined} id={undefined}><TabItem label={"200"} value={"200"}><div>

The list of activated jobs.

</div><div><MimeTabs className={"openapi-tabs__mime"} schemaType={"response"}><TabItem label={"application/json"} value={"application/json"}><SchemaTabs className={"openapi-tabs__schema"}><TabItem label={"Schema"} value={"Schema"}><details style={{}} className={"openapi-markdown__details response"} data-collapsed={false} open={true}><summary style={{}} className={"openapi-markdown__details-summary-response"}><strong>Schema</strong></summary><div style={{"textAlign":"left","marginLeft":"1rem"}}></div><ul style={{"marginLeft":"1rem"}}><SchemaItem collapsible={true} className={"schemaItem"}><details style={{}} className={"openapi-markdown__details"}><summary style={{}}><span className={"openapi-schema__container"}><strong className={"openapi-schema__property"}>jobs</strong><span className={"openapi-schema__name"}> object[]</span></span></summary><div style={{"marginLeft":"1rem"}}><li><div style={{"fontSize":"var(--ifm-code-font-size)","opacity":"0.6","marginLeft":"-.5rem","paddingBottom":".5rem"}}>Array [</div></li><SchemaItem collapsible={false} name={"key"} required={false} schemaName={"int64"} qualifierMessage={undefined} schema={{"description":"the key, a unique identifier for the job","type":"integer","format":"int64"}}></SchemaItem><SchemaItem collapsible={false} name={"type"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"description":"the type of the job (should match what was requested)","type":"string"}}></SchemaItem><SchemaItem collapsible={false} name={"processInstanceKey"} required={false} schemaName={"int64"} qualifierMessage={undefined} schema={{"description":"the job's process instance key","type":"integer","format":"int64"}}></SchemaItem><SchemaItem collapsible={false} name={"bpmnProcessId"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"description":"the bpmn process ID of the job's process definition","type":"string"}}></SchemaItem><SchemaItem collapsible={false} name={"processDefinitionVersion"} required={false} schemaName={"int32"} qualifierMessage={undefined} schema={{"description":"the version of the job's process definition","type":"integer","format":"int32"}}></SchemaItem><SchemaItem collapsible={false} name={"processDefinitionKey"} required={false} schemaName={"int64"} qualifierMessage={undefined} schema={{"description":"the key of the job's process definition","type":"integer","format":"int64"}}></SchemaItem><SchemaItem collapsible={false} name={"elementId"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"description":"the associated task element ID","type":"string"}}></SchemaItem><SchemaItem collapsible={false} name={"elementInstanceKey"} required={false} schemaName={"int64"} qualifierMessage={undefined} schema={{"description":"the unique key identifying the associated task, unique within the scope of the process instance\n","type":"integer","format":"int64"}}></SchemaItem><SchemaItem collapsible={true} className={"schemaItem"}><details style={{}} className={"openapi-markdown__details"}><summary style={{}}><span className={"openapi-schema__container"}><strong className={"openapi-schema__property"}>customHeaders</strong><span className={"openapi-schema__name"}> object</span></span></summary><div style={{"marginLeft":"1rem"}}><div style={{"marginTop":".5rem","marginBottom":".5rem"}}>

a set of custom headers defined during modelling; returned as a serialized JSON document

</div><SchemaItem name={"property name*"} required={false} schemaName={"any"} qualifierMessage={undefined} schema={{"description":"a set of custom headers defined during modelling; returned as a serialized JSON document","type":"object","additionalProperties":true}} collapsible={false} discriminator={false}></SchemaItem></div></details></SchemaItem><SchemaItem collapsible={false} name={"worker"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"description":"the name of the worker which activated this job","type":"string"}}></SchemaItem><SchemaItem collapsible={false} name={"retries"} required={false} schemaName={"int32"} qualifierMessage={undefined} schema={{"description":"the amount of retries left to this job (should always be positive)","type":"integer","format":"int32"}}></SchemaItem><SchemaItem collapsible={false} name={"deadline"} required={false} schemaName={"int64"} qualifierMessage={undefined} schema={{"description":"when the job can be activated again, sent as a UNIX epoch timestamp","type":"integer","format":"int64"}}></SchemaItem><SchemaItem collapsible={true} className={"schemaItem"}><details style={{}} className={"openapi-markdown__details"}><summary style={{}}><span className={"openapi-schema__container"}><strong className={"openapi-schema__property"}>variables</strong><span className={"openapi-schema__name"}> object</span></span></summary><div style={{"marginLeft":"1rem"}}><div style={{"marginTop":".5rem","marginBottom":".5rem"}}>

All variables visible to the task scope, computed at activation time

</div><SchemaItem name={"property name*"} required={false} schemaName={"any"} qualifierMessage={undefined} schema={{"description":"All variables visible to the task scope, computed at activation time","type":"object","additionalProperties":true}} collapsible={false} discriminator={false}></SchemaItem></div></details></SchemaItem><SchemaItem collapsible={false} name={"tenantId"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"description":"the id of the tenant that owns the job","type":"string"}}></SchemaItem><li><div style={{"fontSize":"var(--ifm-code-font-size)","opacity":"0.6","marginLeft":"-.5rem"}}>]</div></li></div></details></SchemaItem></ul></details></TabItem><TabItem label={"Example (from schema)"} value={"Example (from schema)"}><ResponseSamples responseExample={"{\n \"jobs\": [\n {\n \"key\": 0,\n \"type\": \"string\",\n \"processInstanceKey\": 0,\n \"bpmnProcessId\": \"string\",\n \"processDefinitionVersion\": 0,\n \"processDefinitionKey\": 0,\n \"elementId\": \"string\",\n \"elementInstanceKey\": 0,\n \"customHeaders\": {},\n \"worker\": \"string\",\n \"retries\": 0,\n \"deadline\": 0,\n \"variables\": {},\n \"tenantId\": \"string\"\n }\n ]\n}"} language={"json"}></ResponseSamples></TabItem></SchemaTabs></TabItem></MimeTabs></div></TabItem></ApiTabs></div></div>
Loading
Loading