diff --git a/src/main/kotlin/dev/restate/sdktesting/infra/RestateDeployer.kt b/src/main/kotlin/dev/restate/sdktesting/infra/RestateDeployer.kt index dc1580b9..2ca18cb1 100644 --- a/src/main/kotlin/dev/restate/sdktesting/infra/RestateDeployer.kt +++ b/src/main/kotlin/dev/restate/sdktesting/infra/RestateDeployer.kt @@ -390,7 +390,8 @@ private constructor( } private fun discoverDeployment(client: DeploymentApi, uri: String) { - val request = RegisterDeploymentRequest(RegisterHttpDeploymentRequest().uri(uri).force(false)) + val request = + RegisterDeploymentRequest(RegisterHttpDeploymentRequest().uri(URI.create(uri)).force(false)) val response = Unreliables.retryUntilSuccess(20, TimeUnit.SECONDS) { diff --git a/src/main/kotlin/dev/restate/sdktesting/tests/BackwardCompatibilityTest.kt b/src/main/kotlin/dev/restate/sdktesting/tests/BackwardCompatibilityTest.kt index 6df35d9a..406ef5e5 100644 --- a/src/main/kotlin/dev/restate/sdktesting/tests/BackwardCompatibilityTest.kt +++ b/src/main/kotlin/dev/restate/sdktesting/tests/BackwardCompatibilityTest.kt @@ -280,7 +280,8 @@ class BackwardCompatibilityTest { // For each deployment, update its URI for (deployment in deployments.deployments) { val updateRequest = - UpdateDeploymentRequest(UpdateHttpDeploymentRequest().uri(localEndpointURI.toString())) + UpdateDeploymentRequest( + UpdateHttpDeploymentRequest().uri(URI.create(localEndpointURI.toString()))) try { adminApi.updateDeployment(deployment.httpDeploymentResponse.id, updateRequest) diff --git a/src/main/kotlin/dev/restate/sdktesting/tests/ForwardCompatibilityTest.kt b/src/main/kotlin/dev/restate/sdktesting/tests/ForwardCompatibilityTest.kt index 3b179b0e..3aefcd38 100644 --- a/src/main/kotlin/dev/restate/sdktesting/tests/ForwardCompatibilityTest.kt +++ b/src/main/kotlin/dev/restate/sdktesting/tests/ForwardCompatibilityTest.kt @@ -269,7 +269,8 @@ class ForwardCompatibilityTest { // For each deployment, update its URI for (deployment in deployments.deployments) { val updateRequest = - UpdateDeploymentRequest(UpdateHttpDeploymentRequest().uri(localEndpointURI.toString())) + UpdateDeploymentRequest( + UpdateHttpDeploymentRequest().uri(URI.create(localEndpointURI.toString()))) try { adminApi.updateDeployment(deployment.httpDeploymentResponse.id, updateRequest) diff --git a/src/main/kotlin/dev/restate/sdktesting/tests/Kafka.kt b/src/main/kotlin/dev/restate/sdktesting/tests/Kafka.kt index 3dda243b..49a3efdd 100644 --- a/src/main/kotlin/dev/restate/sdktesting/tests/Kafka.kt +++ b/src/main/kotlin/dev/restate/sdktesting/tests/Kafka.kt @@ -8,8 +8,10 @@ // https://github.com/restatedev/sdk-test-suite/blob/main/LICENSE package dev.restate.sdktesting.tests +import dev.restate.admin.api.KafkaClusterApi import dev.restate.admin.api.SubscriptionApi import dev.restate.admin.client.ApiClient +import dev.restate.admin.model.CreateKafkaClusterRequest import dev.restate.admin.model.CreateSubscriptionRequest import dev.restate.sdktesting.infra.KafkaContainer import dev.restate.sdktesting.infra.runtimeconfig.IngressOptions @@ -22,7 +24,7 @@ import org.apache.kafka.clients.producer.Producer import org.apache.kafka.clients.producer.ProducerRecord object Kafka { - fun produceMessagesToKafka(port: Int, topic: String, values: List>) { + fun produceMessagesToKafka(port: Int, topic: String, values: List>) { val props = Properties() props["bootstrap.servers"] = "PLAINTEXT://localhost:$port" props["key.serializer"] = "org.apache.kafka.common.serialization.StringSerializer" @@ -35,6 +37,20 @@ object Kafka { producer.close() } + fun registerKafkaCluster( + adminURI: URI, + ) { + val kafkaClustersClient = + KafkaClusterApi(ApiClient().setHost(adminURI.host).setPort(adminURI.port)) + kafkaClustersClient.createKafkaCluster( + CreateKafkaClusterRequest() + .name("my-cluster") + .properties( + mapOf( + "bootstrap.servers" to + "PLAINTEXT://kafka:${KafkaContainer.KAFKA_NETWORK_PORT}"))) + } + fun createKafkaSubscription( adminURI: URI, topic: String, @@ -45,8 +61,8 @@ object Kafka { SubscriptionApi(ApiClient().setHost(adminURI.host).setPort(adminURI.port)) subscriptionsClient.createSubscription( CreateSubscriptionRequest() - .source("kafka://my-cluster/$topic") - .sink("service://$serviceName/$handlerName") + .source(URI.create("kafka://my-cluster/$topic")) + .sink(URI.create("service://$serviceName/$handlerName")) .options(mapOf("auto.offset.reset" to "earliest"))) } diff --git a/src/main/kotlin/dev/restate/sdktesting/tests/KafkaDynamicSetupTest.kt b/src/main/kotlin/dev/restate/sdktesting/tests/KafkaDynamicSetupTest.kt new file mode 100644 index 00000000..18e932ae --- /dev/null +++ b/src/main/kotlin/dev/restate/sdktesting/tests/KafkaDynamicSetupTest.kt @@ -0,0 +1,149 @@ +// Copyright (c) 2023 - Restate Software, Inc., Restate GmbH +// +// This file is part of the Restate SDK Test suite tool, +// which is released under the MIT license. +// +// You can find a copy of the license in file LICENSE in the root +// directory of this repository or package, or at +// https://github.com/restatedev/sdk-test-suite/blob/main/LICENSE +package dev.restate.sdktesting.tests + +import dev.restate.client.Client +import dev.restate.sdk.annotation.Handler +import dev.restate.sdk.annotation.Name +import dev.restate.sdk.annotation.Service +import dev.restate.sdk.annotation.VirtualObject +import dev.restate.sdk.common.StateKey +import dev.restate.sdk.endpoint.Endpoint +import dev.restate.sdk.kotlin.Context +import dev.restate.sdk.kotlin.ObjectContext +import dev.restate.sdk.kotlin.stateKey +import dev.restate.sdktesting.infra.* +import dev.restate.sdktesting.tests.Kafka.createKafkaSubscription +import dev.restate.sdktesting.tests.Kafka.produceMessagesToKafka +import dev.restate.sdktesting.tests.Kafka.registerKafkaCluster +import java.net.URI +import java.util.* +import kotlinx.serialization.Serializable +import kotlinx.serialization.json.Json +import org.assertj.core.api.Assertions.assertThat +import org.awaitility.kotlin.await +import org.awaitility.kotlin.withAlias +import org.junit.jupiter.api.BeforeAll +import org.junit.jupiter.api.Tag +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.RegisterExtension +import org.junit.jupiter.api.parallel.Execution +import org.junit.jupiter.api.parallel.ExecutionMode +import org.junit.jupiter.api.parallel.Isolated + +@Tag("only-single-node" /* This test depends on metadata propagation happening immediately */) +@Isolated +class KafkaDynamicSetupTest { + + @VirtualObject + @Name("Counter") + class Counter { + companion object { + private val COUNTER_KEY: StateKey = stateKey("counter") + } + + @Handler + suspend fun add(ctx: ObjectContext, value: Long): Long { + val current = ctx.get(COUNTER_KEY) ?: 0L + val newValue = current + value + ctx.set(COUNTER_KEY, newValue) + return newValue + } + + @Handler + suspend fun get(ctx: ObjectContext): Long { + return ctx.get(COUNTER_KEY) ?: 0L + } + } + + @Service + @Name("EventHandler") + class EventHandler { + @Serializable data class ProxyRequest(val key: String, val value: Long) + + @Handler + suspend fun oneWayCall(ctx: Context, request: ProxyRequest) { + KafkaDynamicSetupTestCounterClient.fromContext(ctx, request.key).send().add(request.value) + } + } + + companion object { + private const val COUNTER_TOPIC = "counter" + private const val EVENT_HANDLER_TOPIC = "event-handler" + + @RegisterExtension + val deployerExt: RestateDeployerExtension = RestateDeployerExtension { + withEndpoint(Endpoint.bind(Counter()).bind(EventHandler())) + withContainer("kafka", KafkaContainer(COUNTER_TOPIC, EVENT_HANDLER_TOPIC)) + } + + @JvmStatic + @BeforeAll + fun beforeAll( + @InjectAdminURI adminURI: URI, + ) { + registerKafkaCluster(adminURI) + } + } + + @Test + @Execution(ExecutionMode.CONCURRENT) + fun handleEventInCounterService( + @InjectAdminURI adminURI: URI, + @InjectContainerPort(hostName = "kafka", port = KafkaContainer.KAFKA_EXTERNAL_PORT) + kafkaPort: Int, + @InjectClient ingressClient: Client + ) = runTest { + val counter = UUID.randomUUID().toString() + + // Register subscription + createKafkaSubscription(adminURI, COUNTER_TOPIC, "Counter", "add") + + // Produce message to kafka + produceMessagesToKafka( + kafkaPort, COUNTER_TOPIC, listOf(counter to "1", counter to "2", counter to "3")) + + await withAlias + "Updates from Kafka are visible in the counter" untilAsserted + { + assertThat(KafkaDynamicSetupTestCounterClient.fromClient(ingressClient, counter).get()) + .isEqualTo(6L) + } + } + + @Test + @Execution(ExecutionMode.CONCURRENT) + fun handleEventInEventHandler( + @InjectAdminURI adminURI: URI, + @InjectContainerPort(hostName = "kafka", port = KafkaContainer.KAFKA_EXTERNAL_PORT) + kafkaPort: Int, + @InjectClient ingressClient: Client + ) = runTest { + val counter = UUID.randomUUID().toString() + + // Register subscription + createKafkaSubscription(adminURI, EVENT_HANDLER_TOPIC, "EventHandler", "oneWayCall") + + // Produce message to kafka + produceMessagesToKafka( + kafkaPort, + EVENT_HANDLER_TOPIC, + listOf( + null to Json.encodeToString(EventHandler.ProxyRequest(counter, 1)), + null to Json.encodeToString(EventHandler.ProxyRequest(counter, 2)), + null to Json.encodeToString(EventHandler.ProxyRequest(counter, 3)))) + + await withAlias + "Updates from Kafka are visible in the counter" untilAsserted + { + assertThat(KafkaDynamicSetupTestCounterClient.fromClient(ingressClient, counter).get()) + .isEqualTo(6L) + } + } +} diff --git a/src/main/kotlin/dev/restate/sdktesting/tests/PauseResumeChangingDeploymentTest.kt b/src/main/kotlin/dev/restate/sdktesting/tests/PauseResumeChangingDeploymentTest.kt index efbf1151..0132b362 100644 --- a/src/main/kotlin/dev/restate/sdktesting/tests/PauseResumeChangingDeploymentTest.kt +++ b/src/main/kotlin/dev/restate/sdktesting/tests/PauseResumeChangingDeploymentTest.kt @@ -10,6 +10,7 @@ package dev.restate.sdktesting.tests import dev.restate.admin.api.InvocationApi import dev.restate.admin.client.ApiClient +import dev.restate.admin.model.RestartAsNewInvocationDeploymentParameter import dev.restate.client.Client import dev.restate.client.kotlin.attachSuspend import dev.restate.sdk.annotation.Handler @@ -92,7 +93,10 @@ class PauseResumeChangingDeploymentTest { // Resume the paused invocation on the specific endpoint val adminClient = ApiClient().setHost(adminURI.host).setPort(adminURI.port) val invocationApi = InvocationApi(adminClient) - retryOnServiceUnavailable { invocationApi.resumeInvocation(invocationId, local.deploymentId) } + retryOnServiceUnavailable { + invocationApi.resumeInvocation( + invocationId, RestartAsNewInvocationDeploymentParameter(local.deploymentId)) + } assertThat(sendResult.attachSuspend().response()).isEqualTo("Success in new version!") diff --git a/src/main/kotlin/dev/restate/sdktesting/tests/PauseResumeTest.kt b/src/main/kotlin/dev/restate/sdktesting/tests/PauseResumeTest.kt index d3c06276..81836dca 100644 --- a/src/main/kotlin/dev/restate/sdktesting/tests/PauseResumeTest.kt +++ b/src/main/kotlin/dev/restate/sdktesting/tests/PauseResumeTest.kt @@ -10,6 +10,7 @@ package dev.restate.sdktesting.tests import dev.restate.admin.api.InvocationApi import dev.restate.admin.client.ApiClient +import dev.restate.admin.model.RestartAsNewInvocationDeploymentParameter import dev.restate.client.Client import dev.restate.client.kotlin.attachSuspend import dev.restate.sdk.annotation.Handler @@ -90,7 +91,10 @@ class PauseResumeTest { // Resume the paused invocation on the specific endpoint val adminClient = ApiClient().setHost(adminURI.host).setPort(adminURI.port) val invocationApi = InvocationApi(adminClient) - retryOnServiceUnavailable { invocationApi.resumeInvocation(invocationId, null) } + retryOnServiceUnavailable { + invocationApi.resumeInvocation( + invocationId, RestartAsNewInvocationDeploymentParameter("keep")) + } assertThat(sendResult.attachSuspend().response()).isEqualTo("input") diff --git a/src/main/kotlin/dev/restate/sdktesting/tests/RestartAsNewInvocationTest.kt b/src/main/kotlin/dev/restate/sdktesting/tests/RestartAsNewInvocationTest.kt index 710771e2..239ac45b 100644 --- a/src/main/kotlin/dev/restate/sdktesting/tests/RestartAsNewInvocationTest.kt +++ b/src/main/kotlin/dev/restate/sdktesting/tests/RestartAsNewInvocationTest.kt @@ -10,6 +10,7 @@ package dev.restate.sdktesting.tests import dev.restate.admin.api.InvocationApi import dev.restate.admin.client.ApiClient +import dev.restate.admin.model.RestartAsNewInvocationDeploymentParameter import dev.restate.client.Client import dev.restate.client.IngressException import dev.restate.client.kotlin.* @@ -100,7 +101,10 @@ class RestartAsNewInvocationTest { val invocationApi = InvocationApi(adminClient) val newInvocationId = retryOnServiceUnavailable { - invocationApi.restartAsNewInvocation(sendResult.invocationId(), null, null) + invocationApi.restartAsNewInvocation( + sendResult.invocationId(), + null, + RestartAsNewInvocationDeploymentParameter("latest")) } .newInvocationId @@ -158,7 +162,8 @@ class RestartAsNewInvocationTest { val invocationApi = InvocationApi(adminClient) val newInvocationId = retryOnServiceUnavailable { - invocationApi.restartAsNewInvocation(sendResult.invocationId(), 1, null) + invocationApi.restartAsNewInvocation( + sendResult.invocationId(), 1, RestartAsNewInvocationDeploymentParameter("latest")) } .newInvocationId diff --git a/src/main/kotlin/dev/restate/sdktesting/tests/utils.kt b/src/main/kotlin/dev/restate/sdktesting/tests/utils.kt index 77daa31b..c2a08a86 100644 --- a/src/main/kotlin/dev/restate/sdktesting/tests/utils.kt +++ b/src/main/kotlin/dev/restate/sdktesting/tests/utils.kt @@ -205,7 +205,8 @@ fun startAndRegisterLocalEndpoint(endpoint: Endpoint, adminURI: URI): LocalEndpo try { deploymentApi .createDeployment( - RegisterDeploymentRequest(RegisterHttpDeploymentRequest().uri(uri).force(false))) + RegisterDeploymentRequest( + RegisterHttpDeploymentRequest().uri(URI.create(uri)).force(false))) .id } catch (e: Exception) { LOG.error("Failed to register new deployment {}: {}", uri, e.message) diff --git a/src/main/openapi/admin.json b/src/main/openapi/admin.json index 8c630a95..ba3ee665 100644 --- a/src/main/openapi/admin.json +++ b/src/main/openapi/admin.json @@ -1,8 +1,15 @@ { - "openapi": "3.0.0", + "openapi": "3.1.0", "info": { "title": "Admin API", "description": "This API exposes the admin operations of a Restate cluster, such as registering new service deployments, interacting with running invocations, register Kafka subscriptions, retrieve service metadata. For an overview, check out the [Operate documentation](https://docs.restate.dev/operate/). If you're looking for how to call your services, check out the [Ingress HTTP API](https://docs.restate.dev/invoke/http) instead.", + "contact": { + "name": "restate.dev" + }, + "license": { + "name": "MIT", + "url": "https://opensource.org/license/mit" + }, "version": "1.6.0-dev" }, "paths": { @@ -11,12 +18,11 @@ "tags": [ "cluster_health" ], - "summary": "Cluster health", - "description": "Get the cluster health.", + "summary": "Cluster state endpoint", "operationId": "cluster_health", "responses": { "200": { - "description": "", + "description": "Cluster health information", "content": { "application/json": { "schema": { @@ -25,48 +31,8 @@ } } }, - "400": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } - }, - "403": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } - }, - "404": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } - }, - "409": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } - }, "500": { - "description": "", + "description": "Internal Server Error", "content": { "application/json": { "schema": { @@ -76,7 +42,7 @@ } }, "503": { - "description": "", + "description": "The cluster does not seem to be provisioned yet.", "content": { "application/json": { "schema": { @@ -85,7 +51,8 @@ } } } - } + }, + "deprecated": true } }, "/deployments": { @@ -94,11 +61,11 @@ "deployment" ], "summary": "List deployments", - "description": "List all registered deployments.", + "description": "Returns a list of all registered deployments, including their endpoints and associated services.", "operationId": "list_deployments", "responses": { "200": { - "description": "", + "description": "List of all registered deployments with their metadata", "content": { "application/json": { "schema": { @@ -113,11 +80,8 @@ "tags": [ "deployment" ], - "summary": "Create deployment", - "description": "Create and register a new deployment. Restate will invoke the endpoint to gather additional information required for registration, such as the services exposed by the deployment. If the deployment is already registered, this method will return 200 and no changes will be made. If the deployment updates some already existing services, schema breaking changes checks will run. If you want to bypass them, use `breaking: true`. To overwrite an already existing deployment, use `force: true`", - "externalDocs": { - "url": "https://docs.restate.dev/operate/registration" - }, + "summary": "Register deployment", + "description": "Registers a new deployment (HTTP or Lambda). Restate will invoke the endpoint to discover available services and handlers,\nand make them available for invocation. For more information, see the [deployment documentation](https://docs.restate.dev/services/versioning#registering-a-deployment).", "operationId": "create_deployment", "requestBody": { "content": { @@ -131,17 +95,15 @@ }, "responses": { "200": { - "description": "Already exists. No change if force = false, overwritten if force = true", - "content": { - "application/json": { + "description": "Deployment already exists. No change if force = false, services overwritten if force = true", + "headers": { + "Location": { "schema": { - "$ref": "#/components/schemas/RegisterDeploymentResponse" - } + "type": "string" + }, + "description": "URI of the deployment" } - } - }, - "201": { - "description": "Created", + }, "content": { "application/json": { "schema": { @@ -150,65 +112,38 @@ } } }, - "400": { - "description": "", - "content": { - "application/json": { + "201": { + "description": "Deployment created successfully and services discovered", + "headers": { + "Location": { "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } + "type": "string" + }, + "description": "URI of the created deployment" } - } - }, - "403": { - "description": "", + }, "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" + "$ref": "#/components/schemas/RegisterDeploymentResponse" } } } }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, "404": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } + "$ref": "#/components/responses/NotFound" + }, + "405": { + "$ref": "#/components/responses/MethodNotAllowed" }, "409": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } + "$ref": "#/components/responses/Conflict" }, "500": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } - }, - "503": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } + "$ref": "#/components/responses/InternalServerError" } } } @@ -219,7 +154,7 @@ "deployment" ], "summary": "Get deployment", - "description": "Get deployment metadata", + "description": "Returns detailed information about a registered deployment, including deployment metadata and the services it exposes.", "operationId": "get_deployment", "parameters": [ { @@ -234,7 +169,7 @@ ], "responses": { "200": { - "description": "", + "description": "Deployment details including services and configuration", "content": { "application/json": { "schema": { @@ -244,64 +179,19 @@ } }, "400": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } - }, - "403": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } + "$ref": "#/components/responses/BadRequest" }, "404": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } + "$ref": "#/components/responses/NotFound" + }, + "405": { + "$ref": "#/components/responses/MethodNotAllowed" }, "409": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } + "$ref": "#/components/responses/Conflict" }, "500": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } - }, - "503": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } + "$ref": "#/components/responses/InternalServerError" } } }, @@ -310,7 +200,7 @@ "deployment" ], "summary": "Delete deployment", - "description": "Delete deployment. Currently it's supported to remove a deployment only using the force flag", + "description": "Delete a deployment. Currently, only forced deletions are supported.\n**Use with caution**: forcing a deployment deletion can break in-flight invocations.", "operationId": "delete_deployment", "parameters": [ { @@ -326,71 +216,36 @@ "name": "force", "in": "query", "description": "If true, the deployment will be forcefully deleted. This might break in-flight invocations, use with caution.", - "style": "simple", + "required": false, "schema": { - "type": "boolean" + "type": [ + "boolean", + "null" + ] } } ], "responses": { "202": { - "description": "Accepted" - }, - "501": { - "description": "Not implemented. Only using the force flag is supported at the moment." + "description": "Deployment deletion accepted and will be processed asynchronously" }, "400": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } - }, - "403": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } + "$ref": "#/components/responses/BadRequest" }, "404": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } + "$ref": "#/components/responses/NotFound" + }, + "405": { + "$ref": "#/components/responses/MethodNotAllowed" }, "409": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } + "$ref": "#/components/responses/Conflict" }, "500": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } + "$ref": "#/components/responses/InternalServerError" }, - "503": { - "description": "", + "501": { + "description": "Not implemented. Graceful deployment deletion (force=false) is not yet supported.", "content": { "application/json": { "schema": { @@ -401,15 +256,12 @@ } } }, - "put": { + "patch": { "tags": [ "deployment" ], "summary": "Update deployment", - "description": "Update an already existing deployment. This lets you update the address and options when invoking the deployment, such as the additional headers for HTTP or the assume role for Lambda. The registered services and handlers won't be overwritten, unless `overwrite: true`.", - "externalDocs": { - "url": "https://docs.restate.dev/operate/versioning" - }, + "description": "Updates an existing deployment configuration, such as the endpoint address or invocation headers.\nBy default, service schemas are not re-discovered. Set `overwrite: true` to trigger re-discovery.", "operationId": "update_deployment", "parameters": [ { @@ -434,7 +286,7 @@ }, "responses": { "200": { - "description": "", + "description": "Deployment updated successfully. Address and invocation options are updated. Service schemas are only updated if overwrite was set to true.", "content": { "application/json": { "schema": { @@ -444,64 +296,19 @@ } }, "400": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } - }, - "403": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } + "$ref": "#/components/responses/BadRequest" }, "404": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } + "$ref": "#/components/responses/NotFound" + }, + "405": { + "$ref": "#/components/responses/MethodNotAllowed" }, "409": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } + "$ref": "#/components/responses/Conflict" }, "500": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } - }, - "503": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } + "$ref": "#/components/responses/InternalServerError" } } } @@ -511,24 +318,23 @@ "tags": [ "health" ], - "summary": "Health check", - "description": "Check REST API Health.", + "summary": "Health check endpoint", "operationId": "health", "responses": { "200": { - "description": "OK" + "description": "The Admin API is ready to accept requests." } } } }, - "/invocations/{invocation_id}": { - "delete": { + "/invocations/{invocation_id}/cancel": { + "patch": { "tags": [ "invocation" ], - "summary": "Delete an invocation", - "description": "Use kill_invocation/cancel_invocation/purge_invocation instead.", - "operationId": "delete_invocation", + "summary": "Cancel an invocation", + "description": "Gracefully cancels an invocation. The invocation is terminated, but its progress is persisted, allowing consistency guarantees to be maintained.\nFor more information, see the [cancellation documentation](https://docs.restate.dev/services/invocation/managing-invocations#cancel).", + "operationId": "cancel_invocation", "parameters": [ { "name": "invocation_id", @@ -538,37 +344,37 @@ "schema": { "type": "string" } - }, - { - "name": "mode", - "in": "query", - "description": "If cancel, it will gracefully terminate the invocation. If kill, it will terminate the invocation with a hard stop. If purge, it will only cleanup the response for completed invocations, and leave unaffected an in-flight invocation.", - "style": "simple", - "schema": { - "$ref": "#/components/schemas/DeletionMode" - } } ], "responses": { + "200": { + "description": "Invocation cancelled successfully" + }, "202": { - "description": "Accepted" + "description": "Cancellation request accepted and will be processed asynchronously" }, "400": { "description": "", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } - }, - "403": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" + "type": "object", + "description": "# Error description response\n\nError details of the response", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + }, + "restate_code": { + "type": [ + "string", + "null" + ], + "description": "# Restate code\n\nRestate error code describing this error" + } + } } } } @@ -578,56 +384,90 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" + "type": "object", + "description": "# Error description response\n\nError details of the response", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + }, + "restate_code": { + "type": [ + "string", + "null" + ], + "description": "# Restate code\n\nRestate error code describing this error" + } + } } } } }, "409": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } - }, - "500": { - "description": "", + "description": "The invocation was already completed, so it cannot be cancelled nor killed. You can instead purge the invocation, in order for restate to forget it.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" + "type": "object", + "description": "# Error description response\n\nError details of the response", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + }, + "restate_code": { + "type": [ + "string", + "null" + ], + "description": "# Restate code\n\nRestate error code describing this error" + } + } } } } }, "503": { - "description": "", + "description": "Error when routing the request within restate.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" + "type": "object", + "description": "# Error description response\n\nError details of the response", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + }, + "restate_code": { + "type": [ + "string", + "null" + ], + "description": "# Restate code\n\nRestate error code describing this error" + } + } } } } } - }, - "deprecated": true + } } }, - "/invocations/{invocation_id}/cancel": { + "/invocations/{invocation_id}/kill": { "patch": { "tags": [ "invocation" ], - "summary": "Cancel an invocation", - "description": "Cancel the given invocation. Canceling an invocation allows it to free any resources it is holding and roll back any changes it has made so far, running compensation code. For more details, checkout https://docs.restate.dev/guides/sagas", - "externalDocs": { - "url": "https://docs.restate.dev/guides/sagas" - }, - "operationId": "cancel_invocation", + "summary": "Kill an invocation", + "description": "Forcefully terminates an invocation. **Warning**: This operation does not guarantee consistency for virtual object instance state,\nin-flight invocations to other services, or other side effects. Use with caution.\nFor more information, see the [cancellation documentation](https://docs.restate.dev/services/invocation/managing-invocations#kill).", + "operationId": "kill_invocation", "parameters": [ { "name": "invocation_id", @@ -641,47 +481,108 @@ ], "responses": { "200": { - "description": "The invocation has been cancelled." + "description": "Invocation killed successfully" }, - "202": { - "description": "The cancellation signal was appended to the journal and will be processed by the SDK." - }, - "404 Not Found": { + "400": { "description": "", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" + "type": "object", + "description": "# Error description response\n\nError details of the response", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + }, + "restate_code": { + "type": [ + "string", + "null" + ], + "description": "# Restate code\n\nRestate error code describing this error" + } + } } } } }, - "503 Service Unavailable": { - "description": "Error when routing the request within restate.", + "404": { + "description": "", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" + "type": "object", + "description": "# Error description response\n\nError details of the response", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + }, + "restate_code": { + "type": [ + "string", + "null" + ], + "description": "# Restate code\n\nRestate error code describing this error" + } + } } } } }, - "400 Bad Request": { - "description": "", + "409": { + "description": "The invocation was already completed, so it cannot be cancelled nor killed. You can instead purge the invocation, in order for restate to forget it.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" + "type": "object", + "description": "# Error description response\n\nError details of the response", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + }, + "restate_code": { + "type": [ + "string", + "null" + ], + "description": "# Restate code\n\nRestate error code describing this error" + } + } } } } }, - "409 Conflict": { - "description": "The invocation was already completed, so it cannot be cancelled nor killed. You can instead purge the invocation, in order for restate to forget it.", + "503": { + "description": "Error when routing the request within restate.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" + "type": "object", + "description": "# Error description response\n\nError details of the response", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + }, + "restate_code": { + "type": [ + "string", + "null" + ], + "description": "# Restate code\n\nRestate error code describing this error" + } + } } } } @@ -689,14 +590,13 @@ } } }, - "/invocations/{invocation_id}/kill": { + "/invocations/{invocation_id}/pause": { "patch": { "tags": [ "invocation" ], - "summary": "Kill an invocation", - "description": "Kill the given invocation. This does not guarantee consistency for virtual object instance state, in-flight invocations to other services, etc.", - "operationId": "kill_invocation", + "summary": "Pause an invocation", + "operationId": "pause_invocation", "parameters": [ { "name": "invocation_id", @@ -710,44 +610,111 @@ ], "responses": { "200": { - "description": "" + "description": "Invocation is already paused" + }, + "202": { + "description": "Pausing invocation" }, - "404 Not Found": { + "400": { "description": "", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" + "type": "object", + "description": "# Error description response\n\nError details of the response", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + }, + "restate_code": { + "type": [ + "string", + "null" + ], + "description": "# Restate code\n\nRestate error code describing this error" + } + } } } } }, - "503 Service Unavailable": { - "description": "Error when routing the request within restate.", + "404": { + "description": "", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" + "type": "object", + "description": "# Error description response\n\nError details of the response", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + }, + "restate_code": { + "type": [ + "string", + "null" + ], + "description": "# Restate code\n\nRestate error code describing this error" + } + } } } } }, - "400 Bad Request": { - "description": "", + "409": { + "description": "The invocation is not running. An invocation can be paused only when running.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" + "type": "object", + "description": "# Error description response\n\nError details of the response", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + }, + "restate_code": { + "type": [ + "string", + "null" + ], + "description": "# Restate code\n\nRestate error code describing this error" + } + } } } } }, - "409 Conflict": { - "description": "The invocation was already completed, so it cannot be cancelled nor killed. You can instead purge the invocation, in order for restate to forget it.", + "503": { + "description": "Error when routing the request within restate.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" + "type": "object", + "description": "# Error description response\n\nError details of the response", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + }, + "restate_code": { + "type": [ + "string", + "null" + ], + "description": "# Restate code\n\nRestate error code describing this error" + } + } } } } @@ -760,8 +727,8 @@ "tags": [ "invocation" ], - "summary": "Purge an invocation", - "description": "Purge the given invocation. This cleanups all the state for the given invocation. This command applies only to completed invocations.", + "summary": "Purge a completed invocation", + "description": "Deletes all state associated with a completed invocation, including its journal and metadata.\nThis operation only applies to invocations that have already completed. For more information,\nsee the [purging documentation](https://docs.restate.dev/services/invocation/managing-invocations#purge).", "operationId": "purge_invocation", "parameters": [ { @@ -776,44 +743,108 @@ ], "responses": { "200": { - "description": "" + "description": "Invocation purged successfully" }, - "404 Not Found": { + "400": { "description": "", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" + "type": "object", + "description": "# Error description response\n\nError details of the response", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + }, + "restate_code": { + "type": [ + "string", + "null" + ], + "description": "# Restate code\n\nRestate error code describing this error" + } + } } } } }, - "503 Service Unavailable": { - "description": "Error when routing the request within restate.", + "404": { + "description": "", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" + "type": "object", + "description": "# Error description response\n\nError details of the response", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + }, + "restate_code": { + "type": [ + "string", + "null" + ], + "description": "# Restate code\n\nRestate error code describing this error" + } + } } } } }, - "400 Bad Request": { - "description": "", + "409": { + "description": "The invocation is not yet completed. An invocation can be purged only when completed.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" + "type": "object", + "description": "# Error description response\n\nError details of the response", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + }, + "restate_code": { + "type": [ + "string", + "null" + ], + "description": "# Restate code\n\nRestate error code describing this error" + } + } } } } }, - "409 Conflict": { - "description": "The invocation is not yet completed. An invocation can be purged only when completed.", + "503": { + "description": "Error when routing the request within restate.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" + "type": "object", + "description": "# Error description response\n\nError details of the response", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + }, + "restate_code": { + "type": [ + "string", + "null" + ], + "description": "# Restate code\n\nRestate error code describing this error" + } + } } } } @@ -826,8 +857,8 @@ "tags": [ "invocation" ], - "summary": "Purge an invocation journal", - "description": "Purge the given invocation journal. This cleanups only the journal for the given invocation, retaining the metadata. This command applies only to completed invocations.", + "summary": "Purge invocation journal", + "description": "Deletes only the journal entries for a completed invocation, while retaining its metadata.\nThis operation only applies to invocations that have already completed.", "operationId": "purge_journal", "parameters": [ { @@ -842,44 +873,108 @@ ], "responses": { "200": { - "description": "" + "description": "Invocation journal purged successfully, metadata retained" }, - "404 Not Found": { + "400": { "description": "", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" + "type": "object", + "description": "# Error description response\n\nError details of the response", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + }, + "restate_code": { + "type": [ + "string", + "null" + ], + "description": "# Restate code\n\nRestate error code describing this error" + } + } } } } }, - "503 Service Unavailable": { - "description": "Error when routing the request within restate.", + "404": { + "description": "", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" + "type": "object", + "description": "# Error description response\n\nError details of the response", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + }, + "restate_code": { + "type": [ + "string", + "null" + ], + "description": "# Restate code\n\nRestate error code describing this error" + } + } } } } }, - "400 Bad Request": { - "description": "", + "409": { + "description": "The invocation is not yet completed. An invocation can be purged only when completed.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" + "type": "object", + "description": "# Error description response\n\nError details of the response", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + }, + "restate_code": { + "type": [ + "string", + "null" + ], + "description": "# Restate code\n\nRestate error code describing this error" + } + } } } } }, - "409 Conflict": { - "description": "The invocation is not yet completed. An invocation can be purged only when completed.", + "503": { + "description": "Error when routing the request within restate.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" + "type": "object", + "description": "# Error description response\n\nError details of the response", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + }, + "restate_code": { + "type": [ + "string", + "null" + ], + "description": "# Restate code\n\nRestate error code describing this error" + } + } } } } @@ -892,8 +987,8 @@ "tags": [ "invocation" ], - "summary": "Restart as new invocation", - "description": "Restart the given invocation as new. This will restart the invocation as a new invocation with a different invocation id. By using the 'from' query parameter, some of the partial progress can be copied over to the new invocation.", + "summary": "Restart invocation as new", + "description": "Creates a new invocation from a completed invocation, optionally copying partial progress from the original invocation's journal.\nThe new invocation will have a different invocation ID. Use the `from` parameter to specify how much of the original journal to preserve.", "operationId": "restart_as_new_invocation", "parameters": [ { @@ -908,27 +1003,68 @@ { "name": "from", "in": "query", - "description": "From which entry index the invocation should restart from. By default the invocation restarts from the beginning (equivalent to 'from = 0'), retaining only the input of the original invocation. When greater than 0, the new invocation will copy the old journal prefix up to 'from' included, plus eventual completions for commands in the given prefix. If the journal prefix contains commands that have not been completed, this operation will fail.", - "style": "simple", + "description": "From which entry index the invocation should restart from.\nBy default the invocation restarts from the beginning (equivalent to 'from = 0'), retaining only the input of the original invocation.\nWhen greater than 0, the new invocation will copy the old journal prefix up to 'from' included, plus eventual completions for commands in the given prefix.\nIf the journal prefix contains commands that have not been completed, this operation will fail.", + "required": false, "schema": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/u32" + } + ] } }, { "name": "deployment", "in": "query", - "description": "When restarting from journal prefix, provide a deployment id to use to replace the currently pinned deployment id. If 'latest', use the latest deployment id. If 'keep', keeps the pinned deployment id. When not provided, the invocation will resume on latest. Note: this parameter can be used only in combination with 'from'.", - "style": "simple", + "description": "When restarting from journal prefix, provide a deployment id to use to replace the currently pinned deployment id.\nIf 'latest', use the latest deployment id. If 'keep', keeps the pinned deployment id.\nWhen not provided, the invocation will resume on latest.\nNote: this parameter can be used only in combination with 'from'.", + "required": false, "schema": { - "type": "string" + "oneOf": [ + { + "type": "null" + }, + { + "oneOf": [ + { + "type": "string", + "description": "Keep the currently pinned deployment", + "enum": [ + "Keep" + ] + }, + { + "type": "string", + "description": "Use the latest deployment", + "enum": [ + "Latest" + ] + }, + { + "type": "object", + "description": "Use a specific deployment ID", + "required": [ + "Id" + ], + "properties": { + "Id": { + "type": "string", + "description": "Use a specific deployment ID" + } + } + } + ], + "description": "Specifies which deployment to use when resuming or restarting an invocation." + } + ] } } ], "responses": { "200": { - "description": "", + "description": "Invocation restarted successfully with a new invocation ID", "content": { "application/json": { "schema": { @@ -937,72 +1073,184 @@ } } }, - "404 Not Found": { - "description": "", + "400": { + "description": "The selected deployment id to restart as new the invocation doesn't support the currently pinned service protocol version.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" + "type": "object", + "description": "# Error description response\n\nError details of the response", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + }, + "restate_code": { + "type": [ + "string", + "null" + ], + "description": "# Restate code\n\nRestate error code describing this error" + } + } } } } }, - "503 Service Unavailable": { - "description": "Error when routing the request within restate.", + "404": { + "description": "", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" + "type": "object", + "description": "# Error description response\n\nError details of the response", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + }, + "restate_code": { + "type": [ + "string", + "null" + ], + "description": "# Restate code\n\nRestate error code describing this error" + } + } } } } }, - "400 Bad Request": { - "description": "\nThe given journal index is out of range.\nThe given journal prefix contains some Commands without respective Completions.\nThe given deployment was not found.\nThe selected deployment id to restart as new the invocation doesn't support the currently pinned service protocol version.", + "409": { + "description": "The invocation is still running or the deployment id is not pinned yet, deployment id cannot be changed. The deployment id can be changed only if the invocation is paused or suspended, and a deployment id is already pinned.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" + "type": "object", + "description": "# Error description response\n\nError details of the response", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + }, + "restate_code": { + "type": [ + "string", + "null" + ], + "description": "# Restate code\n\nRestate error code describing this error" + } + } } } } }, - "409 Conflict": { - "description": "The invocation is still running. An invocation can be restarted only when completed.\nThe invocation is still running or the deployment id is not pinned yet, deployment id cannot be changed. The deployment id can be changed only if the invocation is paused or suspended, and a deployment id is already pinned.", + "410": { + "description": "The invocation cannot be restarted because the input is not available. In order to restart an invocation, the journal must be available in order to read the input again. Journal can be retained after completion by enabling journal retention.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" + "type": "object", + "description": "# Error description response\n\nError details of the response", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + }, + "restate_code": { + "type": [ + "string", + "null" + ], + "description": "# Restate code\n\nRestate error code describing this error" + } + } } } } }, - "422 Unprocessable Entity": { + "422": { "description": "Restarting the invocation is not supported. Restarting workflows is not supported, and restarting invocations created using the old service protocol.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" + "type": "object", + "description": "# Error description response\n\nError details of the response", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + }, + "restate_code": { + "type": [ + "string", + "null" + ], + "description": "# Restate code\n\nRestate error code describing this error" + } + } } } } }, - "410 Gone": { - "description": "The invocation cannot be restarted because the input is not available. In order to restart an invocation, the journal must be available in order to read the input again. Journal can be retained after completion by enabling journal retention.", + "425": { + "description": "The invocation cannot be restarted because it's not running yet, meaning it might have been scheduled or inboxed.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" + "type": "object", + "description": "# Error description response\n\nError details of the response", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + }, + "restate_code": { + "type": [ + "string", + "null" + ], + "description": "# Restate code\n\nRestate error code describing this error" + } + } } } } }, - "425 Too Early": { - "description": "The invocation cannot be restarted because it's not running yet, meaning it might have been scheduled or inboxed.", + "503": { + "description": "Error when routing the request within restate.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" + "type": "object", + "description": "# Error description response\n\nError details of the response", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + }, + "restate_code": { + "type": [ + "string", + "null" + ], + "description": "# Restate code\n\nRestate error code describing this error" + } + } } } } @@ -1016,7 +1264,7 @@ "invocation" ], "summary": "Resume an invocation", - "description": "Resume the given invocation. In case the invocation is backing-off, this will immediately trigger the retry timer. If the invocation is suspended or paused, this will resume it.", + "description": "Resumes a paused or suspended invocation. If the invocation is backing off due to a retry, this will immediately trigger the retry.\nOptionally, you can change the deployment ID that will be used when the invocation resumes. For more information see [resume documentation](https://docs.restate.dev/services/invocation/managing-invocations#resume)", "operationId": "resume_invocation", "parameters": [ { @@ -1031,63 +1279,179 @@ { "name": "deployment", "in": "query", - "description": "When resuming from paused/suspended, provide a deployment id to use to replace the currently pinned deployment id. If 'latest', use the latest deployment id. If 'keep', keeps the pinned deployment id. When not provided, the invocation will resume on the pinned deployment id. When provided and the invocation is either running, or no deployment is pinned, this operation will fail.", - "style": "simple", + "description": "When resuming from paused/suspended, provide a deployment id to use to replace the currently pinned deployment id.\nIf 'latest', use the latest deployment id. If 'keep', keeps the pinned deployment id.\nWhen not provided, the invocation will resume on the pinned deployment id.\nWhen provided and the invocation is either running, or no deployment is pinned, this operation will fail.", + "required": false, "schema": { - "type": "string" + "oneOf": [ + { + "type": "null" + }, + { + "oneOf": [ + { + "type": "string", + "description": "Keep the currently pinned deployment", + "enum": [ + "Keep" + ] + }, + { + "type": "string", + "description": "Use the latest deployment", + "enum": [ + "Latest" + ] + }, + { + "type": "object", + "description": "Use a specific deployment ID", + "required": [ + "Id" + ], + "properties": { + "Id": { + "type": "string", + "description": "Use a specific deployment ID" + } + } + } + ], + "description": "Specifies which deployment to use when resuming or restarting an invocation." + } + ] } } ], "responses": { "200": { - "description": "" + "description": "Invocation resumed successfully" }, - "404 Not Found": { - "description": "", + "400": { + "description": "The selected deployment id to resume the invocation doesn't support the currently pinned service protocol version.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" + "type": "object", + "description": "# Error description response\n\nError details of the response", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + }, + "restate_code": { + "type": [ + "string", + "null" + ], + "description": "# Restate code\n\nRestate error code describing this error" + } + } } } } }, - "503 Service Unavailable": { - "description": "Error when routing the request within restate.", + "404": { + "description": "", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" + "type": "object", + "description": "# Error description response\n\nError details of the response", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + }, + "restate_code": { + "type": [ + "string", + "null" + ], + "description": "# Restate code\n\nRestate error code describing this error" + } + } } } } }, - "400 Bad Request": { - "description": "\nThe given deployment was not found.\nThe selected deployment id to resume the invocation doesn't support the currently pinned service protocol version.", + "409": { + "description": "The invocation is still running or the deployment id is not pinned yet, deployment id cannot be changed. The deployment id can be changed only if the invocation is paused or suspended, and a deployment id is already pinned.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" + "type": "object", + "description": "# Error description response\n\nError details of the response", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + }, + "restate_code": { + "type": [ + "string", + "null" + ], + "description": "# Restate code\n\nRestate error code describing this error" + } + } } } } }, - "425 Too Early": { + "425": { "description": "The invocation is either inboxed or scheduled. An invocation can be resumed only when running, paused or suspended.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" + "type": "object", + "description": "# Error description response\n\nError details of the response", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + }, + "restate_code": { + "type": [ + "string", + "null" + ], + "description": "# Restate code\n\nRestate error code describing this error" + } + } } } } }, - "409 Conflict": { - "description": "The invocation is completed. An invocation can be resumed only when running, paused or suspended.\nThe invocation is still running or the deployment id is not pinned yet, deployment id cannot be changed. The deployment id can be changed only if the invocation is paused or suspended, and a deployment id is already pinned.", + "503": { + "description": "Error when routing the request within restate.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" + "type": "object", + "description": "# Error description response\n\nError details of the response", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + }, + "restate_code": { + "type": [ + "string", + "null" + ], + "description": "# Restate code\n\nRestate error code describing this error" + } + } } } } @@ -1095,219 +1459,200 @@ } } }, - "/openapi": { + "/kafka-clusters": { "get": { "tags": [ - "openapi" + "kafka_cluster" ], - "summary": "OpenAPI specification", - "externalDocs": { - "url": "https://swagger.io/specification/" - }, - "operationId": "openapi_spec", + "summary": "List Kafka clusters", + "description": "Returns a list of all registered Kafka clusters.", + "operationId": "list_kafka_clusters", "responses": { "200": { - "description": "", + "description": "List of all Kafka clusters", "content": { "application/json": { "schema": { - "type": "object", - "additionalProperties": { - "type": "string" - } + "$ref": "#/components/schemas/ListKafkaClustersResponse" } } } } } - } - }, - "/services": { - "get": { + }, + "post": { "tags": [ - "service" + "kafka_cluster" ], - "summary": "List services", - "description": "List all registered services.", - "operationId": "list_services", + "summary": "Create Kafka cluster", + "description": "Registers a new Kafka cluster configuration that can be referenced by subscriptions.\nThe cluster configuration is validated to ensure required broker properties are present.", + "operationId": "create_kafka_cluster", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateKafkaClusterRequest" + } + } + }, + "required": true + }, "responses": { - "200": { - "description": "", + "201": { + "description": "Kafka cluster created successfully", + "headers": { + "Location": { + "schema": { + "type": "string" + }, + "description": "URI of the created Kafka cluster" + } + }, "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ListServicesResponse" + "$ref": "#/components/schemas/SimpleKafkaClusterResponse" } } } }, "400": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } - }, - "403": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } + "$ref": "#/components/responses/BadRequest" }, "404": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } + "$ref": "#/components/responses/NotFound" + }, + "405": { + "$ref": "#/components/responses/MethodNotAllowed" }, "409": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } + "$ref": "#/components/responses/Conflict" }, "500": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } - }, - "503": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } + "$ref": "#/components/responses/InternalServerError" } } } }, - "/services/{service}": { + "/kafka-clusters/{cluster_name}": { "get": { "tags": [ - "service" + "kafka_cluster" ], - "summary": "Get service", - "description": "Get a registered service.", - "operationId": "get_service", + "summary": "Get Kafka cluster", + "description": "Returns the details of a specific Kafka cluster, including its configuration properties.\nSensitive properties (passwords, secrets, etc.) are automatically redacted in the response.", + "operationId": "get_kafka_cluster", "parameters": [ { - "name": "service", + "name": "cluster_name", "in": "path", - "description": "Fully qualified service name.", + "description": "Kafka cluster name", "required": true, "schema": { "type": "string" } + }, + { + "name": "include_subscriptions", + "in": "query", + "description": "If true, includes the list of subscriptions using this cluster.", + "required": false, + "schema": { + "type": "boolean" + } } ], "responses": { "200": { - "description": "", + "description": "Kafka cluster details", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ServiceMetadata" + "$ref": "#/components/schemas/KafkaClusterResponse" } } } }, "400": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } - }, - "403": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } + "$ref": "#/components/responses/BadRequest" }, "404": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } + "$ref": "#/components/responses/NotFound" + }, + "405": { + "$ref": "#/components/responses/MethodNotAllowed" }, "409": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } + "$ref": "#/components/responses/Conflict" }, "500": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } + "$ref": "#/components/responses/InternalServerError" + } + } + }, + "delete": { + "tags": [ + "kafka_cluster" + ], + "summary": "Delete Kafka cluster", + "description": "Deletes a Kafka cluster. By default, deletion is prevented if subscriptions reference the cluster.\nUse the force parameter to allow deletion with orphaned subscriptions.", + "operationId": "delete_kafka_cluster", + "parameters": [ + { + "name": "cluster_name", + "in": "path", + "description": "Kafka cluster name", + "required": true, + "schema": { + "type": "string" } }, - "503": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } + { + "name": "force", + "in": "query", + "description": "If true, allows deletion of the cluster even if it would orphan subscriptions.", + "required": false, + "schema": { + "type": [ + "boolean", + "null" + ] } } + ], + "responses": { + "202": { + "description": "Kafka cluster deletion accepted and will be processed asynchronously" + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "405": { + "$ref": "#/components/responses/MethodNotAllowed" + }, + "409": { + "$ref": "#/components/responses/Conflict" + }, + "500": { + "$ref": "#/components/responses/InternalServerError" + } } }, "patch": { "tags": [ - "service" + "kafka_cluster" ], - "summary": "Modify a service", - "description": "Modify a registered service configuration. NOTE: Service re-discovery will update the settings based on the service endpoint configuration.", - "operationId": "modify_service", + "summary": "Update Kafka cluster", + "description": "Updates the configuration properties of an existing Kafka cluster.\nSensitive properties (passwords, secrets, etc.) are automatically redacted in the response.", + "operationId": "update_kafka_cluster", "parameters": [ { - "name": "service", + "name": "cluster_name", "in": "path", - "description": "Fully qualified service name.", + "description": "Kafka cluster name", "required": true, "schema": { "type": "string" @@ -1318,7 +1663,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ModifyServiceRequest" + "$ref": "#/components/schemas/UpdateKafkaClusterRequest" } } }, @@ -1326,86 +1671,116 @@ }, "responses": { "200": { - "description": "", + "description": "Kafka cluster updated successfully", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ServiceMetadata" + "$ref": "#/components/schemas/SimpleKafkaClusterResponse" } } } }, "400": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } - }, - "403": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } + "$ref": "#/components/responses/BadRequest" }, "404": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } + "$ref": "#/components/responses/NotFound" + }, + "405": { + "$ref": "#/components/responses/MethodNotAllowed" }, "409": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } + "$ref": "#/components/responses/Conflict" + }, + "500": { + "$ref": "#/components/responses/InternalServerError" + } + } + } + }, + "/query": { + "post": { + "tags": [ + "introspection" + ], + "summary": "Query the system and service state by using SQL.", + "operationId": "query", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/QueryRequest" } } }, - "500": { - "description": "", + "required": true + }, + "responses": { + "200": { + "description": "Query results", "content": { + "application/vnd.apache.arrow.stream": {}, "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" + "example": { + "rows": [] } } } }, + "500": { + "description": "Internal Datafusion error" + }, "503": { - "description": "", + "description": "Query service not available" + } + } + } + }, + "/services": { + "get": { + "tags": [ + "service" + ], + "summary": "List services", + "description": "Returns a list of all registered services, including their metadata and configuration.", + "operationId": "list_services", + "responses": { + "200": { + "description": "List of all registered services with their metadata", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" + "$ref": "#/components/schemas/ListServicesResponse" } } } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "405": { + "$ref": "#/components/responses/MethodNotAllowed" + }, + "409": { + "$ref": "#/components/responses/Conflict" + }, + "500": { + "$ref": "#/components/responses/InternalServerError" } } } }, - "/services/{service}/handlers": { + "/services/{service}": { "get": { "tags": [ - "service_handler" + "service" ], - "summary": "List service handlers", - "description": "List all the handlers of the given service.", - "operationId": "list_service_handlers", + "summary": "Get service", + "description": "Returns detailed metadata about a specific service, including its type, handlers, and configuration settings.", + "operationId": "get_service", "parameters": [ { "name": "service", @@ -1419,74 +1794,133 @@ ], "responses": { "200": { - "description": "", + "description": "Service metadata including type, revision, handlers, and configuration", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ListServiceHandlersResponse" + "$ref": "#/components/schemas/ServiceMetadata" } } } }, "400": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } + "$ref": "#/components/responses/BadRequest" }, - "403": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } + "404": { + "$ref": "#/components/responses/NotFound" + }, + "405": { + "$ref": "#/components/responses/MethodNotAllowed" + }, + "409": { + "$ref": "#/components/responses/Conflict" + }, + "500": { + "$ref": "#/components/responses/InternalServerError" + } + } + }, + "patch": { + "tags": [ + "service" + ], + "summary": "Modify service configuration", + "description": "Updates the configuration of a registered service, such as public visibility, retention policies, and timeout settings.\nNote: Service re-discovery will update these settings based on the service endpoint configuration.", + "operationId": "modify_service", + "parameters": [ + { + "name": "service", + "in": "path", + "description": "Fully qualified service name.", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ModifyServiceRequest" } } }, - "404": { - "description": "", + "required": true + }, + "responses": { + "200": { + "description": "Service configuration updated successfully", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" + "$ref": "#/components/schemas/ServiceMetadata" } } } }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "405": { + "$ref": "#/components/responses/MethodNotAllowed" + }, "409": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } + "$ref": "#/components/responses/Conflict" }, "500": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } + "$ref": "#/components/responses/InternalServerError" + } + } + } + }, + "/services/{service}/handlers": { + "get": { + "tags": [ + "service_handler" + ], + "summary": "List service handlers", + "description": "Returns a list of all handlers (methods) available in the specified service.", + "operationId": "list_service_handlers", + "parameters": [ + { + "name": "service", + "in": "path", + "description": "Fully qualified service name.", + "required": true, + "schema": { + "type": "string" } - }, - "503": { - "description": "", + } + ], + "responses": { + "200": { + "description": "List of handlers available in the service", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" + "$ref": "#/components/schemas/ListServiceHandlersResponse" } } } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "405": { + "$ref": "#/components/responses/MethodNotAllowed" + }, + "409": { + "$ref": "#/components/responses/Conflict" + }, + "500": { + "$ref": "#/components/responses/InternalServerError" } } } @@ -1497,7 +1931,7 @@ "service_handler" ], "summary": "Get service handler", - "description": "Get the handler of a service", + "description": "Returns detailed metadata about a specific handler within a service, including its input/output types and handler type.", "operationId": "get_service_handler", "parameters": [ { @@ -1521,7 +1955,7 @@ ], "responses": { "200": { - "description": "", + "description": "Handler metadata including input/output types and configuration", "content": { "application/json": { "schema": { @@ -1531,64 +1965,19 @@ } }, "400": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } - }, - "403": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } + "$ref": "#/components/responses/BadRequest" }, "404": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } + "$ref": "#/components/responses/NotFound" + }, + "405": { + "$ref": "#/components/responses/MethodNotAllowed" }, "409": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } + "$ref": "#/components/responses/Conflict" }, "500": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } - }, - "503": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } + "$ref": "#/components/responses/InternalServerError" } } } @@ -1598,8 +1987,8 @@ "tags": [ "service" ], - "summary": "Get service OpenAPI", - "description": "Get the service OpenAPI 3.1 contract.", + "summary": "Get service OpenAPI definition", + "description": "Returns the OpenAPI 3.1 specification for the service, describing all handlers and their request/response schemas.", "operationId": "get_service_openapi", "parameters": [ { @@ -1614,7 +2003,7 @@ ], "responses": { "200": { - "description": "OpenAPI 3.1 of the service", + "description": "OpenAPI 3.1 specification document describing the service's API", "content": { "application/json": { "schema": {} @@ -1622,64 +2011,19 @@ } }, "400": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } - }, - "403": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } + "$ref": "#/components/responses/BadRequest" }, "404": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } + "$ref": "#/components/responses/NotFound" + }, + "405": { + "$ref": "#/components/responses/MethodNotAllowed" }, "409": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } + "$ref": "#/components/responses/Conflict" }, "500": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } - }, - "503": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } + "$ref": "#/components/responses/InternalServerError" } } } @@ -1689,8 +2033,8 @@ "tags": [ "service" ], - "summary": "Modify a service state", - "description": "Modify service state", + "summary": "Modify service state", + "description": "Modifies the K/V state of a Virtual Object. For a detailed description of this API and how to use it, see the [state documentation](https://docs.restate.dev/operate/invocation#modifying-service-state).", "operationId": "modify_service_state", "parameters": [ { @@ -1715,67 +2059,22 @@ }, "responses": { "202": { - "description": "Accepted" + "description": "State modification request accepted and will be applied asynchronously" }, "400": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } - }, - "403": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } + "$ref": "#/components/responses/BadRequest" }, "404": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } + "$ref": "#/components/responses/NotFound" + }, + "405": { + "$ref": "#/components/responses/MethodNotAllowed" }, "409": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } + "$ref": "#/components/responses/Conflict" }, "500": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } - }, - "503": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } + "$ref": "#/components/responses/InternalServerError" } } } @@ -1786,31 +2085,37 @@ "subscription" ], "summary": "List subscriptions", - "description": "List all subscriptions.", + "description": "Returns a list of all registered subscriptions, optionally filtered by source or sink.", "operationId": "list_subscriptions", "parameters": [ { "name": "sink", "in": "query", "description": "Filter by the exact specified sink.", - "style": "simple", + "required": false, "schema": { - "type": "string" + "type": [ + "string", + "null" + ] } }, { "name": "source", "in": "query", "description": "Filter by the exact specified source.", - "style": "simple", + "required": false, "schema": { - "type": "string" + "type": [ + "string", + "null" + ] } } ], "responses": { "200": { - "description": "", + "description": "List of subscriptions matching the filter criteria", "content": { "application/json": { "schema": { @@ -1826,10 +2131,7 @@ "subscription" ], "summary": "Create subscription", - "description": "Create subscription.", - "externalDocs": { - "url": "https://docs.restate.dev/operate/invocation#managing-kafka-subscriptions" - }, + "description": "Creates a new subscription that connects an event source (e.g., a Kafka topic) to a Restate service handler.\nFor more information, see the [subscription documentation](https://docs.restate.dev/operate/invocation#managing-kafka-subscriptions).", "operationId": "create_subscription", "requestBody": { "content": { @@ -1843,74 +2145,37 @@ }, "responses": { "201": { - "description": "Created", - "content": { - "application/json": { + "description": "Subscription created successfully", + "headers": { + "Location": { "schema": { - "$ref": "#/components/schemas/SubscriptionResponse" - } + "type": "string" + }, + "description": "URI of the created subscription" } - } - }, - "400": { - "description": "", + }, "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" + "$ref": "#/components/schemas/SubscriptionResponse" } } } }, - "403": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } + "400": { + "$ref": "#/components/responses/BadRequest" }, "404": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } + "$ref": "#/components/responses/NotFound" + }, + "405": { + "$ref": "#/components/responses/MethodNotAllowed" }, "409": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } + "$ref": "#/components/responses/Conflict" }, "500": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } - }, - "503": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } + "$ref": "#/components/responses/InternalServerError" } } } @@ -1921,7 +2186,7 @@ "subscription" ], "summary": "Get subscription", - "description": "Get subscription", + "description": "Returns the details of a specific subscription, including its source, sink, and configuration options.", "operationId": "get_subscription", "parameters": [ { @@ -1936,7 +2201,7 @@ ], "responses": { "200": { - "description": "", + "description": "Subscription details including source, sink, and options", "content": { "application/json": { "schema": { @@ -1946,64 +2211,19 @@ } }, "400": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } - }, - "403": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } + "$ref": "#/components/responses/BadRequest" }, "404": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } + "$ref": "#/components/responses/NotFound" + }, + "405": { + "$ref": "#/components/responses/MethodNotAllowed" }, "409": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } + "$ref": "#/components/responses/Conflict" }, "500": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } - }, - "503": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } + "$ref": "#/components/responses/InternalServerError" } } }, @@ -2012,7 +2232,7 @@ "subscription" ], "summary": "Delete subscription", - "description": "Delete subscription.", + "description": "Deletes a subscription. This will stop events from the source from being forwarded to the sink.", "operationId": "delete_subscription", "parameters": [ { @@ -2027,67 +2247,22 @@ ], "responses": { "202": { - "description": "Accepted" + "description": "Subscription deletion accepted and will be processed asynchronously" }, "400": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } - }, - "403": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } + "$ref": "#/components/responses/BadRequest" }, "404": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } + "$ref": "#/components/responses/NotFound" + }, + "405": { + "$ref": "#/components/responses/MethodNotAllowed" }, "409": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } + "$ref": "#/components/responses/Conflict" }, "500": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } - }, - "503": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorDescriptionResponse" - } - } - } + "$ref": "#/components/responses/InternalServerError" } } } @@ -2097,12 +2272,12 @@ "tags": [ "version" ], - "summary": "Admin version information", - "description": "Obtain admin version information.", + "summary": "Get version information", + "description": "Returns the server version, supported Admin API versions, and the advertised ingress endpoint.", "operationId": "version", "responses": { "200": { - "description": "", + "description": "Server version information including supported API versions and ingress endpoint.", "content": { "application/json": { "schema": { @@ -2117,743 +2292,869 @@ }, "components": { "schemas": { + "AdvertisedAddress-http-ingress-server_HttpIngressPort": { + "type": "string", + "title": "advertised address", + "description": "An externally accessible URI address for http-ingress-server. This can be set to unix:restate-data/ingress.sock to advertise the automatically created unix-socket instead of using tcp if needed", + "examples": [ + "http//127.0.0.1:8080/", + "https://my-host/", + "unix:/data/restate-data/ingress.sock" + ] + }, "ClusterHealthResponse": { "type": "object", + "description": "Cluster health information", "required": [ "cluster_name" ], "properties": { "cluster_name": { - "description": "Cluster name", - "type": "string" + "type": "string", + "description": "Cluster name" }, "metadata_cluster_health": { - "description": "Embedded metadata cluster health if it was enabled", - "allOf": [ + "oneOf": [ { - "$ref": "#/components/schemas/EmbeddedMetadataClusterHealth" + "type": "null" + }, + { + "$ref": "#/components/schemas/EmbeddedMetadataClusterHealth", + "description": "Embedded metadata cluster health if it was enabled" } - ], - "nullable": true + ] } } }, - "EmbeddedMetadataClusterHealth": { + "CreateKafkaClusterRequest": { "type": "object", + "description": "Create Kafka cluster request", "required": [ - "members" + "name", + "properties" ], "properties": { - "members": { - "description": "Current members of the embedded metadata cluster", - "type": "array", - "items": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 + "name": { + "$ref": "#/components/schemas/KafkaClusterName", + "description": "# Cluster Name\n\nName for the Kafka cluster, used to identify this Kafka cluster configuration in subscriptions. Must be a valid hostname format." + }, + "properties": { + "type": "object", + "description": "# Properties\n\nKafka cluster configuration properties. Must contain either\n'bootstrap.servers' or 'metadata.broker.list'.\n\nFor a full list of configuration properties, check the [librdkafka documentation](https://github.com/confluentinc/librdkafka/blob/master/CONFIGURATION.md).", + "additionalProperties": { + "type": "string" + }, + "propertyNames": { + "type": "string" } } } }, - "ErrorDescriptionResponse": { - "title": "Error description response", - "description": "Error details of the response", + "CreateSubscriptionRequest": { "type": "object", "required": [ - "message" + "source", + "sink" ], "properties": { - "message": { - "type": "string" + "options": { + "type": [ + "object", + "null" + ], + "description": "# Options\n\nAdditional options to apply to the subscription.", + "additionalProperties": { + "type": "string" + }, + "propertyNames": { + "type": "string" + } }, - "restate_code": { - "title": "Restate code", - "description": "Restate error code describing this error", + "sink": { + "type": "string", + "format": "uri", + "description": "# Sink\n\nSink uri. Accepted forms:\n\n* `service:///`, e.g. `service://Counter/count`" + }, + "source": { "type": "string", - "nullable": true + "format": "uri", + "description": "# Source\n\nSource uri. Accepted forms:\n\n* `kafka:///`, e.g. `kafka://my-cluster/my-topic`" } } }, - "ListDeploymentsResponse": { - "type": "object", - "required": [ - "deployments" - ], - "properties": { - "deployments": { - "type": "array", - "items": { - "$ref": "#/components/schemas/DeploymentResponse" - } - } - } + "DeploymentId": { + "type": "string" }, "DeploymentResponse": { - "anyOf": [ + "oneOf": [ { + "type": "object", "title": "HttpDeploymentResponse", "description": "Deployment response for HTTP deployments", - "type": "object", "required": [ - "created_at", - "http_version", "id", - "max_protocol_version", - "min_protocol_version", + "uri", "protocol_type", - "services", - "uri" + "http_version", + "created_at", + "min_protocol_version", + "max_protocol_version", + "services" ], "properties": { - "id": { - "title": "Deployment ID", - "allOf": [ - { - "$ref": "#/components/schemas/String" - } - ] + "additional_headers": { + "$ref": "#/components/schemas/SerdeableHeaderHashMap", + "description": "# Additional headers\n\nAdditional headers used to invoke this service deployment." }, - "uri": { - "title": "Deployment URI", - "description": "URI used to invoke this service deployment.", + "created_at": { "type": "string" }, - "protocol_type": { - "title": "Protocol Type", - "description": "Protocol type used to invoke this service deployment.", - "allOf": [ - { - "$ref": "#/components/schemas/ProtocolType" - } - ] - }, "http_version": { - "title": "HTTP Version", - "description": "HTTP Version used to invoke this service deployment.", - "type": "string" + "type": "string", + "description": "# HTTP Version\n\nHTTP Version used to invoke this service deployment." }, - "additional_headers": { - "title": "Additional headers", - "description": "Additional headers used to invoke this service deployment.", - "type": "object", - "additionalProperties": { - "type": "string" - } + "id": { + "$ref": "#/components/schemas/DeploymentId", + "description": "# Deployment ID" + }, + "info": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Info" + }, + "description": "# Info\n\nList of configuration/deprecation information related to this deployment." + }, + "max_protocol_version": { + "type": "integer", + "format": "int32", + "description": "# Maximum Service Protocol version\n\nDuring registration, the SDKs declare a range from minimum (included) to maximum (included) Service Protocol supported version." }, "metadata": { - "title": "Metadata", - "description": "Deployment metadata.", "type": "object", + "description": "# Metadata\n\nDeployment metadata.", "additionalProperties": { "type": "string" - } - }, - "created_at": { - "type": "string" + }, + "propertyNames": { + "type": "string" + } }, "min_protocol_version": { - "title": "Minimum Service Protocol version", - "description": "During registration, the SDKs declare a range from minimum (included) to maximum (included) Service Protocol supported version.", "type": "integer", - "format": "int32" + "format": "int32", + "description": "# Minimum Service Protocol version\n\nDuring registration, the SDKs declare a range from minimum (included) to maximum (included) Service Protocol supported version." }, - "max_protocol_version": { - "title": "Maximum Service Protocol version", - "description": "During registration, the SDKs declare a range from minimum (included) to maximum (included) Service Protocol supported version.", - "type": "integer", - "format": "int32" + "protocol_type": { + "$ref": "#/components/schemas/ProtocolType", + "description": "# Protocol Type\n\nProtocol type used to invoke this service deployment." }, "sdk_version": { - "title": "SDK version", - "description": "SDK library and version declared during registration.", - "type": "string", - "nullable": true + "type": [ + "string", + "null" + ], + "description": "# SDK version\n\nSDK library and version declared during registration." }, "services": { - "title": "Services", - "description": "List of services exposed by this deployment.", "type": "array", "items": { "$ref": "#/components/schemas/ServiceNameRevPair" - } + }, + "description": "# Services\n\nList of services exposed by this deployment." + }, + "uri": { + "type": "string", + "format": "uri", + "description": "# Deployment URI\n\nURI used to invoke this service deployment." } } }, { + "type": "object", "title": "LambdaDeploymentResponse", "description": "Deployment response for Lambda deployments", - "type": "object", "required": [ + "id", "arn", "created_at", - "id", - "max_protocol_version", "min_protocol_version", + "max_protocol_version", "services" ], "properties": { - "id": { - "title": "Deployment ID", - "allOf": [ - { - "$ref": "#/components/schemas/String" - } - ] + "additional_headers": { + "$ref": "#/components/schemas/SerdeableHeaderHashMap", + "description": "# Additional headers\n\nAdditional headers used to invoke this service deployment." }, "arn": { - "title": "Lambda ARN", - "description": "Lambda ARN used to invoke this service deployment.", - "allOf": [ - { - "$ref": "#/components/schemas/LambdaARN" - } - ] + "$ref": "#/components/schemas/LambdaARN", + "description": "# Lambda ARN\n\nLambda ARN used to invoke this service deployment." }, "assume_role_arn": { - "title": "Assume role ARN", - "description": "Assume role ARN used to invoke this deployment. Check https://docs.restate.dev/category/aws-lambda for more details.", - "type": "string", - "nullable": true + "type": [ + "string", + "null" + ], + "description": "# Assume role ARN\n\nAssume role ARN used to invoke this deployment. Check https://docs.restate.dev/category/aws-lambda for more details." }, "compression": { - "title": "Compression", - "description": "Compression algorithm used for invoking Lambda.", - "allOf": [ + "oneOf": [ { - "$ref": "#/components/schemas/EndpointLambdaCompression" + "type": "null" + }, + { + "$ref": "#/components/schemas/EndpointLambdaCompression", + "description": "# Compression\n\nCompression algorithm used for invoking Lambda." } - ], - "nullable": true + ] }, - "additional_headers": { - "title": "Additional headers", - "description": "Additional headers used to invoke this service deployment.", - "type": "object", - "additionalProperties": { - "type": "string" - } + "created_at": { + "type": "string" + }, + "id": { + "$ref": "#/components/schemas/DeploymentId", + "description": "# Deployment ID" + }, + "info": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Info" + }, + "description": "# Info\n\nList of configuration/deprecation information related to this deployment." + }, + "max_protocol_version": { + "type": "integer", + "format": "int32", + "description": "# Maximum Service Protocol version\n\nDuring registration, the SDKs declare a range from minimum (included) to maximum (included) Service Protocol supported version." }, "metadata": { - "title": "Metadata", - "description": "Deployment metadata.", "type": "object", + "description": "# Metadata\n\nDeployment metadata.", "additionalProperties": { "type": "string" + }, + "propertyNames": { + "type": "string" } }, - "created_at": { - "type": "string" - }, "min_protocol_version": { - "title": "Minimum Service Protocol version", - "description": "During registration, the SDKs declare a range from minimum (included) to maximum (included) Service Protocol supported version.", "type": "integer", - "format": "int32" - }, - "max_protocol_version": { - "title": "Maximum Service Protocol version", - "description": "During registration, the SDKs declare a range from minimum (included) to maximum (included) Service Protocol supported version.", - "type": "integer", - "format": "int32" + "format": "int32", + "description": "# Minimum Service Protocol version\n\nDuring registration, the SDKs declare a range from minimum (included) to maximum (included) Service Protocol supported version." }, "sdk_version": { - "title": "SDK version", - "description": "SDK library and version declared during registration.", - "type": "string", - "nullable": true + "type": [ + "string", + "null" + ], + "description": "# SDK version\n\nSDK library and version declared during registration." }, "services": { - "title": "Services", - "description": "List of services exposed by this deployment.", "type": "array", "items": { "$ref": "#/components/schemas/ServiceNameRevPair" - } + }, + "description": "# Services\n\nList of services exposed by this deployment." } } } ] }, - "String": { - "type": "string" - }, - "ProtocolType": { - "type": "string", - "enum": [ - "RequestResponse", - "BidiStream" - ] - }, - "ServiceNameRevPair": { - "type": "object", - "required": [ - "name", - "revision" - ], - "properties": { - "name": { - "type": "string" - }, - "revision": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - } - }, - "LambdaARN": { - "type": "string", - "format": "arn" - }, - "EndpointLambdaCompression": { - "description": "Lambda compression", - "type": "string", - "enum": [ - "Zstd" - ] - }, - "RegisterDeploymentRequest": { - "anyOf": [ + "DetailedDeploymentResponse": { + "oneOf": [ { - "title": "RegisterHttpDeploymentRequest", - "description": "Register HTTP deployment request", "type": "object", + "title": "HttpDetailedDeploymentResponse", + "description": "Detailed deployment response for HTTP deployments", "required": [ - "uri" + "id", + "uri", + "protocol_type", + "http_version", + "created_at", + "min_protocol_version", + "max_protocol_version", + "services" ], "properties": { - "uri": { - "title": "Uri", - "description": "Uri to use to discover/invoke the http deployment.", + "additional_headers": { + "$ref": "#/components/schemas/SerdeableHeaderHashMap", + "description": "# Additional headers\n\nAdditional headers used to invoke this service deployment." + }, + "created_at": { "type": "string" }, - "additional_headers": { - "title": "Additional headers", - "description": "Additional headers added to every discover/invoke request to the deployment.\n\nFill this field with API Tokens and other authorization headers needed to send requests to the deployment.", - "type": "object", - "additionalProperties": { - "type": "string" + "http_version": { + "type": "string", + "description": "# HTTP Version\n\nHTTP Version used to invoke this service deployment." + }, + "id": { + "$ref": "#/components/schemas/DeploymentId", + "description": "# Deployment ID" + }, + "info": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Info" }, - "nullable": true + "description": "# Info\n\nList of configuration/deprecation information related to this deployment." + }, + "max_protocol_version": { + "type": "integer", + "format": "int32", + "description": "# Maximum Service Protocol version\n\nDuring registration, the SDKs declare a range from minimum (included) to maximum (included) Service Protocol supported version." }, "metadata": { - "title": "Metadata", - "description": "Deployment metadata.", "type": "object", + "description": "# Metadata\n\nDeployment metadata.", "additionalProperties": { "type": "string" + }, + "propertyNames": { + "type": "string" } }, - "use_http_11": { - "title": "Use http1.1", - "description": "If `true`, discovery will be attempted using a client that defaults to HTTP1.1 instead of a prior-knowledge HTTP2 client. HTTP2 may still be used for TLS servers that advertise HTTP2 support via ALPN. HTTP1.1 deployments will only work in request-response mode.", - "default": false, - "type": "boolean" + "min_protocol_version": { + "type": "integer", + "format": "int32", + "description": "# Minimum Service Protocol version\n\nDuring registration, the SDKs declare a range from minimum (included) to maximum (included) Service Protocol supported version." }, - "breaking": { - "title": "Breaking", - "description": "If `true`, it allows registering new service revisions with schemas incompatible with previous service revisions, such as changing service type, removing a handler, etc.\n\nSee the [versioning documentation](https://docs.restate.dev/operate/versioning) for more information.", - "default": false, - "type": "boolean" + "protocol_type": { + "$ref": "#/components/schemas/ProtocolType", + "description": "# Protocol Type\n\nProtocol type used to invoke this service deployment." }, - "force": { - "title": "Force", - "description": "If `true`, it overrides, if existing, any deployment using the same `uri`. Beware that this can lead inflight invocations to an unrecoverable error state.\n\nWhen set to `true`, it implies `breaking = true`.\n\nSee the [versioning documentation](https://docs.restate.dev/operate/versioning) for more information.", - "default": true, - "type": "boolean", - "nullable": true + "sdk_version": { + "type": [ + "string", + "null" + ], + "description": "# SDK version\n\nSDK library and version declared during registration." }, - "dry_run": { - "title": "Dry-run mode", - "description": "If `true`, discovery will run but the deployment will not be registered. This is useful to see the impact of a new deployment before registering it. `force` and `breaking` will be respected.", - "default": false, - "type": "boolean" + "services": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ServiceMetadata" + }, + "description": "# Services\n\nList of services exposed by this deployment." + }, + "uri": { + "type": "string", + "format": "uri", + "description": "# Deployment URI\n\nURI used to invoke this service deployment." } } }, { - "title": "RegisterLambdaDeploymentRequest", - "description": "Register Lambda deployment request", "type": "object", + "title": "LambdaDetailedDeploymentResponse", + "description": "Detailed deployment response for Lambda deployments", "required": [ - "arn" + "id", + "arn", + "created_at", + "min_protocol_version", + "max_protocol_version", + "services" ], "properties": { + "additional_headers": { + "$ref": "#/components/schemas/SerdeableHeaderHashMap", + "description": "# Additional headers\n\nAdditional headers used to invoke this service deployment." + }, "arn": { - "title": "ARN", - "description": "ARN to use to discover/invoke the lambda deployment.", - "type": "string" + "$ref": "#/components/schemas/LambdaARN", + "description": "# Lambda ARN\n\nLambda ARN used to invoke this service deployment." }, "assume_role_arn": { - "title": "Assume role ARN", - "description": "Optional ARN of a role to assume when invoking the addressed Lambda, to support role chaining", - "type": "string", - "nullable": true + "type": [ + "string", + "null" + ], + "description": "# Assume role ARN\n\nAssume role ARN used to invoke this deployment. Check https://docs.restate.dev/category/aws-lambda for more details." }, - "additional_headers": { - "title": "Additional headers", - "description": "Additional headers added to every discover/invoke request to the deployment.", - "type": "object", - "additionalProperties": { - "type": "string" + "compression": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/EndpointLambdaCompression", + "description": "# Compression\n\nCompression algorithm used for invoking Lambda." + } + ] + }, + "created_at": { + "type": "string" + }, + "id": { + "$ref": "#/components/schemas/DeploymentId", + "description": "# Deployment ID" + }, + "info": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Info" }, - "nullable": true + "description": "# Info\n\nList of configuration/deprecation information related to this deployment." + }, + "max_protocol_version": { + "type": "integer", + "format": "int32", + "description": "# Maximum Service Protocol version\n\nDuring registration, the SDKs declare a range from minimum (included) to maximum (included) Service Protocol supported version." }, "metadata": { - "title": "Metadata", - "description": "Deployment metadata.", "type": "object", + "description": "# Metadata\n\nDeployment metadata.", "additionalProperties": { "type": "string" + }, + "propertyNames": { + "type": "string" } }, - "breaking": { - "title": "Breaking", - "description": "If `true`, it allows registering new service revisions with schemas incompatible with previous service revisions, such as changing service type, removing a handler, etc.\n\nSee the [versioning documentation](https://docs.restate.dev/operate/versioning) for more information.", - "default": false, - "type": "boolean" + "min_protocol_version": { + "type": "integer", + "format": "int32", + "description": "# Minimum Service Protocol version\n\nDuring registration, the SDKs declare a range from minimum (included) to maximum (included) Service Protocol supported version." }, - "force": { - "title": "Force", - "description": "If `true`, it overrides, if existing, any deployment using the same `uri`. Beware that this can lead inflight invocations to an unrecoverable error state.\n\nThis implies `breaking = true`.\n\nSee the [versioning documentation](https://docs.restate.dev/operate/versioning) for more information.", - "default": true, - "type": "boolean", - "nullable": true + "sdk_version": { + "type": [ + "string", + "null" + ], + "description": "# SDK version\n\nSDK library and version declared during registration." }, - "dry_run": { - "title": "Dry-run mode", - "description": "If `true`, discovery will run but the deployment will not be registered. This is useful to see the impact of a new deployment before registering it. `force` and `breaking` will be respected.", - "default": false, - "type": "boolean" + "services": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ServiceMetadata" + }, + "description": "# Services\n\nList of services exposed by this deployment." } } } - ] + ], + "description": "Detailed information about Restate deployments" }, - "RegisterDeploymentResponse": { + "EmbeddedMetadataClusterHealth": { "type": "object", "required": [ - "id", - "services" + "members" ], "properties": { - "id": { - "$ref": "#/components/schemas/String" - }, - "services": { + "members": { "type": "array", "items": { - "$ref": "#/components/schemas/ServiceMetadata" - } - }, - "min_protocol_version": { - "title": "Minimum Service Protocol version", - "description": "During registration, the SDKs declare a range from minimum (included) to maximum (included) Service Protocol supported version.", - "default": 0, - "type": "integer", - "format": "int32" - }, - "max_protocol_version": { - "title": "Maximum Service Protocol version", - "description": "During registration, the SDKs declare a range from minimum (included) to maximum (included) Service Protocol supported version.", - "default": 0, - "type": "integer", - "format": "int32" + "$ref": "#/components/schemas/PlainNodeId" + }, + "description": "Current members of the embedded metadata cluster" + } + } + }, + "EndpointLambdaCompression": { + "type": "string", + "description": "Lambda compression", + "enum": [ + "Zstd" + ] + }, + "ErrorDescriptionResponse": { + "type": "object", + "description": "# Error description response\n\nError details of the response", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" }, - "sdk_version": { - "title": "SDK version", - "description": "SDK library and version declared during registration.", - "type": "string", - "nullable": true + "restate_code": { + "type": [ + "string", + "null" + ], + "description": "# Restate code\n\nRestate error code describing this error" } } }, - "ServiceMetadata": { + "HandlerMetadata": { "type": "object", + "description": "Handler metadata", "required": [ - "deployment_id", - "handlers", "name", - "revision", - "ty" + "input_description", + "output_description" ], "properties": { - "name": { - "title": "Name", - "description": "Fully qualified name of the service", - "type": "string" + "abort_timeout": { + "type": [ + "string", + "null" + ], + "description": "# Abort timeout\n\nThis timer guards against stalled service/handler invocations that are supposed to\nterminate. The abort timeout is started after the 'inactivity timeout' has expired\nand the service/handler invocation has been asked to gracefully terminate. Once the\ntimer expires, it will abort the service/handler invocation.\n\nThis timer potentially **interrupts** user code. If the user code needs longer to\ngracefully terminate, then this value needs to be set accordingly.\n\nCan be configured using the [`jiff::fmt::friendly`](https://docs.rs/jiff/latest/jiff/fmt/friendly/index.html) format or ISO8601, for example `5 hours`.\n\nIf set, it overrides the value set in the service." }, - "ty": { - "title": "Type", - "description": "Service type", - "allOf": [ - { - "$ref": "#/components/schemas/ServiceType" - } - ] + "documentation": { + "type": [ + "string", + "null" + ], + "description": "# Documentation\n\nDocumentation of the handler, as propagated by the SDKs." }, - "handlers": { - "title": "Handlers", - "description": "Handlers for this service.", + "enable_lazy_state": { + "type": [ + "boolean", + "null" + ], + "description": "# Enable lazy state\n\nIf true, lazy state will be enabled for all invocations to this service.\nThis is relevant only for Workflows and Virtual Objects.\n\nIf set, it overrides the value set in the service." + }, + "idempotency_retention": { + "type": [ + "string", + "null" + ], + "description": "# Idempotency retention\n\nThe retention duration of idempotent requests for this handler. If set, it overrides the value set in the service.\n\nCan be configured using the [`jiff::fmt::friendly`](https://docs.rs/jiff/latest/jiff/fmt/friendly/index.html) format or ISO8601, for example `5 hours`." + }, + "inactivity_timeout": { + "type": [ + "string", + "null" + ], + "description": "# Inactivity timeout\n\nThis timer guards against stalled service/handler invocations. Once it expires,\nRestate triggers a graceful termination by asking the service invocation to\nsuspend (which preserves intermediate progress).\n\nThe 'abort timeout' is used to abort the invocation, in case it doesn't react to\nthe request to suspend.\n\nCan be configured using the [`jiff::fmt::friendly`](https://docs.rs/jiff/latest/jiff/fmt/friendly/index.html) format or ISO8601, for example `5 hours`.\n\nIf set, it overrides the value set in the service." + }, + "info": { "type": "array", "items": { - "$ref": "#/components/schemas/HandlerMetadata" - } + "$ref": "#/components/schemas/Info" + }, + "description": "# Info\n\nList of configuration/deprecation information related to this handler." }, - "documentation": { - "title": "Documentation", - "description": "Documentation of the service, as propagated by the SDKs.", + "input_description": { "type": "string", - "nullable": true + "description": "# Human readable input description\n\nIf empty, no schema was provided by the user at discovery time." + }, + "input_json_schema": { + "description": "# Input JSON Schema\n\nJSON Schema of the handler input" + }, + "journal_retention": { + "type": [ + "string", + "null" + ], + "description": "# Journal retention\n\nThe journal retention. When set, this applies to all requests to this handler.\n\nIn case the invocation has an idempotency key, the `idempotency_retention` caps the maximum `journal_retention` time.\nIn case this handler is a workflow handler, the `workflow_completion_retention` caps the maximum `journal_retention` time.\n\nCan be configured using the [`jiff::fmt::friendly`](https://docs.rs/jiff/latest/jiff/fmt/friendly/index.html) format or ISO8601, for example `5 hours`.\n\nIf set, it overrides the value set in the service." }, "metadata": { - "title": "Metadata", - "description": "Additional service metadata, as propagated by the SDKs.", "type": "object", + "description": "# Metadata\n\nAdditional handler metadata, as propagated by the SDKs.", "additionalProperties": { "type": "string" + }, + "propertyNames": { + "type": "string" } }, - "deployment_id": { - "title": "Deployment Id", - "description": "Deployment exposing the latest revision of the service.", - "allOf": [ - { - "$ref": "#/components/schemas/String" - } - ] - }, - "revision": { - "title": "Revision", - "description": "Latest revision of the service.", - "type": "integer", - "format": "uint32", - "minimum": 0.0 - }, - "public": { - "title": "Public", - "description": "If true, the service can be invoked through the ingress. If false, the service can be invoked only from another Restate service.", - "default": true, - "type": "boolean" - }, - "idempotency_retention": { - "title": "Idempotency retention", - "description": "The retention duration of idempotent requests for this service.\n\nIf not configured, this returns the default idempotency retention.\n\nCan be configured using the [`jiff::fmt::friendly`](https://docs.rs/jiff/latest/jiff/fmt/friendly/index.html) format or ISO8601, for example `5 hours`.", - "default": "1d", - "type": "string" - }, - "workflow_completion_retention": { - "title": "Workflow completion retention", - "description": "The retention duration of workflows. Only available on workflow services.\n\nCan be configured using the [`jiff::fmt::friendly`](https://docs.rs/jiff/latest/jiff/fmt/friendly/index.html) format or ISO8601, for example `5 hours`.", + "name": { "type": "string", - "nullable": true + "description": "# Name\n\nThe handler name." }, - "journal_retention": { - "title": "Journal retention", - "description": "The journal retention. When set, this applies to all requests to all handlers of this service.\n\nIn case the invocation has an idempotency key, the `idempotency_retention` caps the maximum `journal_retention` time. In case the invocation targets a workflow handler, the `workflow_completion_retention` caps the maximum `journal_retention` time.\n\nCan be configured using the [`jiff::fmt::friendly`](https://docs.rs/jiff/latest/jiff/fmt/friendly/index.html) format or ISO8601, for example `5 hours`.", + "output_description": { "type": "string", - "nullable": true - }, - "inactivity_timeout": { - "title": "Inactivity timeout", - "description": "This timer guards against stalled service/handler invocations. Once it expires, Restate triggers a graceful termination by asking the service invocation to suspend (which preserves intermediate progress).\n\nThe 'abort timeout' is used to abort the invocation, in case it doesn't react to the request to suspend.\n\nCan be configured using the [`jiff::fmt::friendly`](https://docs.rs/jiff/latest/jiff/fmt/friendly/index.html) format or ISO8601, for example `5 hours`.\n\nIf unset, this returns the default inactivity timeout configured in invoker options.", - "default": "1m", - "type": "string" + "description": "# Human readable output description\n\nIf empty, no schema was provided by the user at discovery time." }, - "abort_timeout": { - "title": "Abort timeout", - "description": "This timer guards against stalled service/handler invocations that are supposed to terminate. The abort timeout is started after the 'inactivity timeout' has expired and the service/handler invocation has been asked to gracefully terminate. Once the timer expires, it will abort the service/handler invocation.\n\nThis timer potentially **interrupts** user code. If the user code needs longer to gracefully terminate, then this value needs to be set accordingly.\n\nCan be configured using the [`jiff::fmt::friendly`](https://docs.rs/jiff/latest/jiff/fmt/friendly/index.html) format or ISO8601, for example `5 hours`.\n\nIf unset, this returns the default abort timeout configured in invoker options.", - "default": "1m", - "type": "string" + "output_json_schema": { + "description": "# Output JSON Schema\n\nJSON Schema of the handler output" }, - "enable_lazy_state": { - "title": "Enable lazy state", - "description": "If true, lazy state will be enabled for all invocations to this service. This is relevant only for Workflows and Virtual Objects.", - "default": false, - "type": "boolean" + "public": { + "type": "boolean", + "description": "# Public\n\nIf true, this handler can be invoked through the ingress.\nIf false, this handler can be invoked only from another Restate service." }, "retry_policy": { - "allOf": [ + "$ref": "#/components/schemas/HandlerRetryPolicyMetadata", + "description": "# Retry policy\n\nRetry policy overrides applied for this handler." + }, + "ty": { + "oneOf": [ { - "$ref": "#/components/schemas/ServiceRetryPolicyMetadata" + "type": "null" }, - { "title": "Retry policy", - "description": "Retry policy applied to invocations of this service.\n\nIf unset, it returns the default values configured in the Restate configuration.", - "default": { - "exponentiation_factor": 2.0, - "initial_interval": "100ms", - "max_attempts": null, - "max_interval": null, - "on_max_attempts": "Pause" - } + { + "$ref": "#/components/schemas/HandlerMetadataType", + "description": "# Type\n\nThe handler type." } ] } } }, - "ServiceType": { + "HandlerMetadataType": { "type": "string", "enum": [ - "Service", - "VirtualObject", + "Exclusive", + "Shared", "Workflow" ] }, - "HandlerMetadata": { + "HandlerRetryPolicyMetadata": { "type": "object", - "required": [ - "input_description", - "name", - "output_description" - ], + "description": "# Handler retry policy overrides", "properties": { - "name": { - "title": "Name", - "description": "The handler name.", - "type": "string" + "exponentiation_factor": { + "type": [ + "number", + "null" + ], + "format": "float", + "description": "# Factor\n\nThe factor to use to compute the next retry attempt." }, - "ty": { - "title": "Type", - "description": "The handler type.", - "allOf": [ + "initial_interval": { + "type": [ + "string", + "null" + ], + "description": "# Initial Interval\n\nInitial interval for the first retry attempt.\n\nCan be configured using the [`jiff::fmt::friendly`](https://docs.rs/jiff/latest/jiff/fmt/friendly/index.html) format or ISO8601, for example `5 hours`." + }, + "max_attempts": { + "type": [ + "integer", + "null" + ], + "description": "# Max attempts\n\nNumber of maximum attempts (including the initial) before giving up. Infinite retries if unset. No retries if set to 1.", + "minimum": 1 + }, + "max_interval": { + "type": [ + "string", + "null" + ], + "description": "# Max interval\n\nMaximum interval between retries.\n\nCan be configured using the [`jiff::fmt::friendly`](https://docs.rs/jiff/latest/jiff/fmt/friendly/index.html) format or ISO8601, for example `5 hours`." + }, + "on_max_attempts": { + "oneOf": [ + { + "type": "null" + }, { - "$ref": "#/components/schemas/HandlerMetadataType" + "$ref": "#/components/schemas/OnMaxAttempts", + "description": "# On max attempts\n\nBehavior when max attempts are reached." } - ], - "nullable": true + ] + } + } + }, + "Info": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "code": { + "type": [ + "string", + "null" + ] }, - "documentation": { - "title": "Documentation", - "description": "Documentation of the handler, as propagated by the SDKs.", + "message": { + "type": "string" + } + } + }, + "KafkaClusterName": { + "type": "string", + "format": "hostname", + "description": "# Kafka cluster name\n\nValid name to use as a kafka cluster identifier. MUST conform a valid hostname format." + }, + "KafkaClusterResponse": { + "type": "object", + "description": "Kafka cluster details with subscriptions.", + "required": [ + "name", + "properties", + "created_at", + "subscriptions" + ], + "properties": { + "created_at": { "type": "string", - "nullable": true + "description": "# Created at\n\nWhen the Kafka cluster configuration was created." }, - "metadata": { - "title": "Metadata", - "description": "Additional handler metadata, as propagated by the SDKs.", + "name": { + "type": "string", + "description": "# Cluster Name\n\nName for the Kafka cluster, used to identify this Kafka cluster configuration in subscriptions. Must be a valid hostname format." + }, + "properties": { "type": "object", + "description": "# Properties\n\nProperties for connecting to the kafka cluster.\n\nFor a full list of configuration properties, check the [librdkafka documentation](https://github.com/confluentinc/librdkafka/blob/master/CONFIGURATION.md).", "additionalProperties": { "type": "string" + }, + "propertyNames": { + "type": "string" } }, - "idempotency_retention": { - "title": "Idempotency retention", - "description": "The retention duration of idempotent requests for this handler. If set, it overrides the value set in the service.\n\nCan be configured using the [`jiff::fmt::friendly`](https://docs.rs/jiff/latest/jiff/fmt/friendly/index.html) format or ISO8601, for example `5 hours`.", - "type": "string", - "nullable": true + "subscriptions": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SubscriptionResponse" + }, + "description": "# Subscriptions\n\nSubscriptions to this Kafka cluster, returned only when `include_subscriptions` is enabled." + } + } + }, + "LambdaARN": { + "type": "string" + }, + "ListDeploymentsResponse": { + "type": "object", + "description": "List of all registered deployments", + "required": [ + "deployments" + ], + "properties": { + "deployments": { + "type": "array", + "items": { + "$ref": "#/components/schemas/DeploymentResponse" + } + } + } + }, + "ListKafkaClustersResponse": { + "type": "object", + "description": "List of all Kafka clusters.", + "required": [ + "clusters" + ], + "properties": { + "clusters": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SimpleKafkaClusterResponse" + } + } + } + }, + "ListServiceHandlersResponse": { + "type": "object", + "description": "List of all the handlers of a service", + "required": [ + "handlers" + ], + "properties": { + "handlers": { + "type": "array", + "items": { + "$ref": "#/components/schemas/HandlerMetadata" + } + } + } + }, + "ListServicesResponse": { + "type": "object", + "description": "List of all registered services.", + "required": [ + "services" + ], + "properties": { + "services": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ServiceMetadata" + } + } + } + }, + "ListSubscriptionsResponse": { + "type": "object", + "description": "List of all subscriptions.", + "required": [ + "subscriptions" + ], + "properties": { + "subscriptions": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SubscriptionResponse" + } + } + } + }, + "ModifyServiceRequest": { + "type": "object", + "properties": { + "abort_timeout": { + "type": [ + "string", + "null" + ], + "description": "# Abort timeout\n\nThis timer guards against stalled service/handler invocations that are supposed to\nterminate. The abort timeout is started after the 'inactivity timeout' has expired\nand the service/handler invocation has been asked to gracefully terminate. Once the\ntimer expires, it will abort the service/handler invocation.\n\nThis timer potentially **interrupts** user code. If the user code needs longer to\ngracefully terminate, then this value needs to be set accordingly.\n\nCan be configured using the [`jiff::fmt::friendly`](https://docs.rs/jiff/latest/jiff/fmt/friendly/index.html) format or ISO8601, for example `5 hours`.\n\nThis overrides the default abort timeout set in invoker options." }, - "journal_retention": { - "title": "Journal retention", - "description": "The journal retention. When set, this applies to all requests to this handler.\n\nIn case the invocation has an idempotency key, the `idempotency_retention` caps the maximum `journal_retention` time. In case this handler is a workflow handler, the `workflow_completion_retention` caps the maximum `journal_retention` time.\n\nCan be configured using the [`jiff::fmt::friendly`](https://docs.rs/jiff/latest/jiff/fmt/friendly/index.html) format or ISO8601, for example `5 hours`.\n\nIf set, it overrides the value set in the service.", - "type": "string", - "nullable": true + "idempotency_retention": { + "type": [ + "string", + "null" + ], + "description": "# Idempotency retention\n\nModify the retention of idempotent requests for this service.\n\nCan be configured using the [`jiff::fmt::friendly`](https://docs.rs/jiff/latest/jiff/fmt/friendly/index.html) format or ISO8601, for example `5 hours`." }, "inactivity_timeout": { - "title": "Inactivity timeout", - "description": "This timer guards against stalled service/handler invocations. Once it expires, Restate triggers a graceful termination by asking the service invocation to suspend (which preserves intermediate progress).\n\nThe 'abort timeout' is used to abort the invocation, in case it doesn't react to the request to suspend.\n\nCan be configured using the [`jiff::fmt::friendly`](https://docs.rs/jiff/latest/jiff/fmt/friendly/index.html) format or ISO8601, for example `5 hours`.\n\nIf set, it overrides the value set in the service.", - "type": "string", - "nullable": true - }, - "abort_timeout": { - "title": "Abort timeout", - "description": "This timer guards against stalled service/handler invocations that are supposed to terminate. The abort timeout is started after the 'inactivity timeout' has expired and the service/handler invocation has been asked to gracefully terminate. Once the timer expires, it will abort the service/handler invocation.\n\nThis timer potentially **interrupts** user code. If the user code needs longer to gracefully terminate, then this value needs to be set accordingly.\n\nCan be configured using the [`jiff::fmt::friendly`](https://docs.rs/jiff/latest/jiff/fmt/friendly/index.html) format or ISO8601, for example `5 hours`.\n\nIf set, it overrides the value set in the service.", - "type": "string", - "nullable": true + "type": [ + "string", + "null" + ], + "description": "# Inactivity timeout\n\nThis timer guards against stalled service/handler invocations. Once it expires,\nRestate triggers a graceful termination by asking the service invocation to\nsuspend (which preserves intermediate progress).\n\nThe 'abort timeout' is used to abort the invocation, in case it doesn't react to\nthe request to suspend.\n\nCan be configured using the [`jiff::fmt::friendly`](https://docs.rs/jiff/latest/jiff/fmt/friendly/index.html) format or ISO8601, for example `5 hours`.\n\nThis overrides the default inactivity timeout set in invoker options." }, - "enable_lazy_state": { - "title": "Enable lazy state", - "description": "If true, lazy state will be enabled for all invocations to this service. This is relevant only for Workflows and Virtual Objects.\n\nIf set, it overrides the value set in the service.", - "type": "boolean", - "nullable": true + "journal_retention": { + "type": [ + "string", + "null" + ], + "description": "# Journal retention\n\nModify the journal retention for this service. When set, this applies to all requests to all handlers of this service.\n\nIn case the invocation has an idempotency key, the `idempotency_retention` caps the maximum `journal_retention` time.\nIn case the invocation targets a workflow handler, the `workflow_completion_retention` caps the maximum `journal_retention` time.\n\nCan be configured using the [`jiff::fmt::friendly`](https://docs.rs/jiff/latest/jiff/fmt/friendly/index.html) format or ISO8601, for example `5 hours`." }, "public": { - "title": "Public", - "description": "If true, this handler can be invoked through the ingress. If false, this handler can be invoked only from another Restate service.", - "default": true, - "type": "boolean" - }, - "input_description": { - "title": "Human readable input description", - "description": "If empty, no schema was provided by the user at discovery time.", - "type": "string" - }, - "output_description": { - "title": "Human readable output description", - "description": "If empty, no schema was provided by the user at discovery time.", - "type": "string" - }, - "input_json_schema": { - "title": "Input JSON Schema", - "description": "JSON Schema of the handler input", - "nullable": true - }, - "output_json_schema": { - "title": "Output JSON Schema", - "description": "JSON Schema of the handler output", - "nullable": true + "type": [ + "boolean", + "null" + ], + "description": "# Public\n\nIf true, the service can be invoked through the ingress.\nIf false, the service can be invoked only from another Restate service." }, - "retry_policy": { - "allOf": [ - { - "$ref": "#/components/schemas/HandlerRetryPolicyMetadata" - }, - { - "title": "Retry policy", - "description": "Retry policy overrides applied for this handler." - } - ] + "workflow_completion_retention": { + "type": [ + "string", + "null" + ], + "description": "# Workflow completion retention\n\nModify the retention of the workflow completion. This can be modified only for workflow services!\n\nCan be configured using the [`jiff::fmt::friendly`](https://docs.rs/jiff/latest/jiff/fmt/friendly/index.html) format or ISO8601, for example `5 hours`." } } }, - "HandlerMetadataType": { - "type": "string", - "enum": [ - "Exclusive", - "Shared", - "Workflow" - ] - }, - "HandlerRetryPolicyMetadata": { - "title": "Handler retry policy overrides", + "ModifyServiceStateRequest": { "type": "object", + "required": [ + "object_key", + "new_state" + ], "properties": { - "initial_interval": { - "title": "Initial Interval", - "description": "Initial interval for the first retry attempt.\n\nCan be configured using the [`jiff::fmt::friendly`](https://docs.rs/jiff/latest/jiff/fmt/friendly/index.html) format or ISO8601, for example `5 hours`.", - "type": "string" - }, - "exponentiation_factor": { - "title": "Factor", - "description": "The factor to use to compute the next retry attempt.", - "type": "number", - "format": "float", - "nullable": true - }, - "max_attempts": { - "title": "Max attempts", - "description": "Number of maximum attempts before giving up. Infinite retries if unset.", - "type": "integer", - "format": "uint", - "minimum": 0.0, - "nullable": true + "new_state": { + "type": "object", + "description": "# New State\n\nThe new state to replace the previous state with", + "additionalProperties": { + "type": "array", + "items": { + "type": "integer", + "format": "int32", + "minimum": 0 + } + }, + "propertyNames": { + "type": "string" + } }, - "max_interval": { - "title": "Max interval", - "description": "Maximum interval between retries.\n\nCan be configured using the [`jiff::fmt::friendly`](https://docs.rs/jiff/latest/jiff/fmt/friendly/index.html) format or ISO8601, for example `5 hours`.", + "object_key": { "type": "string", - "nullable": true + "description": "# Service key\n\nTo what virtual object key to apply this change" }, - "on_max_attempts": { - "allOf": [ - { - "$ref": "#/components/schemas/OnMaxAttempts" - }, - { - "title": "On max attempts", - "description": "Behavior when max attempts are reached.", - "nullable": true - } - ] + "version": { + "type": [ + "string", + "null" + ], + "description": "# Version\n\nIf set, the latest version of the state is compared with this value and the operation will fail\nwhen the versions differ." } } }, @@ -2864,353 +3165,182 @@ "Kill" ] }, - "ServiceRetryPolicyMetadata": { - "title": "Service retry policy", + "PlainNodeId": { + "type": "integer", + "format": "int32", + "minimum": 0 + }, + "ProtocolType": { + "type": "string", + "enum": [ + "RequestResponse", + "BidiStream" + ] + }, + "QueryRequest": { "type": "object", + "required": [ + "query" + ], "properties": { - "initial_interval": { - "title": "Initial Interval", - "description": "Initial interval for the first retry attempt.\n\nCan be configured using the [`jiff::fmt::friendly`](https://docs.rs/jiff/latest/jiff/fmt/friendly/index.html) format or ISO8601, for example `5 hours`.", - "default": "100ms", - "type": "string" - }, - "exponentiation_factor": { - "title": "Factor", - "description": "The factor to use to compute the next retry attempt. Default: `2.0`.", - "default": 2.0, - "type": "number", - "format": "float" - }, - "max_attempts": { - "title": "Max attempts", - "description": "Number of maximum attempts (including the initial) before giving up. Infinite retries if unset. No retries if set to 1.", - "default": null, - "type": "integer", - "format": "uint", - "minimum": 1.0, - "nullable": true - }, - "max_interval": { - "title": "Max interval", - "description": "Maximum interval between retries.\n\nCan be configured using the [`jiff::fmt::friendly`](https://docs.rs/jiff/latest/jiff/fmt/friendly/index.html) format or ISO8601, for example `5 hours`.", - "default": null, + "query": { "type": "string", - "nullable": true - }, - "on_max_attempts": { - "allOf": [ - { - "$ref": "#/components/schemas/OnMaxAttempts" - }, - { - "title": "On max attempts", - "description": "Behavior when max attempts are reached.", - "default": "Pause" - } - ] + "description": "SQL query to run against the storage" } } }, - "DetailedDeploymentResponse": { - "anyOf": [ + "RegisterDeploymentRequest": { + "oneOf": [ { - "title": "HttpDetailedDeploymentResponse", - "description": "Detailed deployment response for HTTP deployments", "type": "object", + "title": "RegisterHttpDeploymentRequest", + "description": "Register HTTP deployment request", "required": [ - "created_at", - "http_version", - "id", - "max_protocol_version", - "min_protocol_version", - "protocol_type", - "services", "uri" ], "properties": { - "id": { - "title": "Deployment ID", - "allOf": [ + "additional_headers": { + "oneOf": [ { - "$ref": "#/components/schemas/String" - } - ] - }, - "uri": { - "title": "Deployment URI", - "description": "URI used to invoke this service deployment.", - "type": "string" - }, - "protocol_type": { - "title": "Protocol Type", - "description": "Protocol type used to invoke this service deployment.", - "allOf": [ + "type": "null" + }, { - "$ref": "#/components/schemas/ProtocolType" + "$ref": "#/components/schemas/SerdeableHeaderHashMap", + "description": "# Additional headers\n\nAdditional headers added to every discover/invoke request to the deployment.\n\nYou typically want to include here API keys and other tokens required to send requests to deployments." } ] }, - "http_version": { - "title": "HTTP Version", - "description": "HTTP Version used to invoke this service deployment.", - "type": "string" + "breaking": { + "type": "boolean", + "description": "# Breaking\n\nIf `true`, it allows registering new service revisions with\nschemas incompatible with previous service revisions, such as changing service type, removing a handler, etc.\n\nSee the [versioning documentation](https://docs.restate.dev/operate/versioning) for more information." }, - "additional_headers": { - "title": "Additional headers", - "description": "Additional headers used to invoke this service deployment.", - "type": "object", - "additionalProperties": { - "type": "string" - } + "dry_run": { + "type": "boolean", + "description": "# Dry-run mode\n\nIf `true`, discovery will run but the deployment will not be registered.\nThis is useful to see the impact of a new deployment before registering it.\n`force` and `breaking` will be respected." + }, + "force": { + "type": [ + "boolean", + "null" + ], + "description": "# Force\n\nIf `true`, it overrides, if existing, any deployment using the same `uri`.\nBeware that this can lead inflight invocations to an unrecoverable error state.\n\nWhen set to `true`, it implies `breaking = true`.\n\nSee the [versioning documentation](https://docs.restate.dev/operate/versioning) for more information.", + "default": true }, "metadata": { - "title": "Metadata", - "description": "Deployment metadata.", "type": "object", + "description": "# Metadata\n\nDeployment metadata.", "additionalProperties": { "type": "string" + }, + "propertyNames": { + "type": "string" } }, - "created_at": { - "type": "string" - }, - "min_protocol_version": { - "title": "Minimum Service Protocol version", - "description": "During registration, the SDKs declare a range from minimum (included) to maximum (included) Service Protocol supported version.", - "type": "integer", - "format": "int32" - }, - "max_protocol_version": { - "title": "Maximum Service Protocol version", - "description": "During registration, the SDKs declare a range from minimum (included) to maximum (included) Service Protocol supported version.", - "type": "integer", - "format": "int32" - }, - "sdk_version": { - "title": "SDK version", - "description": "SDK library and version declared during registration.", + "uri": { "type": "string", - "nullable": true + "format": "uri", + "description": "# Uri\n\nUri to use to discover/invoke the http deployment." }, - "services": { - "title": "Services", - "description": "List of services exposed by this deployment.", - "type": "array", - "items": { - "$ref": "#/components/schemas/ServiceMetadata" - } + "use_http_11": { + "type": "boolean", + "description": "# Use http1.1\n\nIf `true`, discovery will be attempted using a client that defaults to HTTP1.1\ninstead of a prior-knowledge HTTP2 client. HTTP2 may still be used for TLS servers\nthat advertise HTTP2 support via ALPN. HTTP1.1 deployments will only work in\nrequest-response mode.\n" } } }, { - "title": "LambdaDetailedDeploymentResponse", - "description": "Detailed deployment response for Lambda deployments", "type": "object", + "title": "RegisterLambdaDeploymentRequest", + "description": "Register Lambda deployment request", "required": [ - "arn", - "created_at", - "id", - "max_protocol_version", - "min_protocol_version", - "services" + "arn" ], "properties": { - "id": { - "title": "Deployment ID", - "allOf": [ + "additional_headers": { + "oneOf": [ { - "$ref": "#/components/schemas/String" - } - ] - }, - "arn": { - "title": "Lambda ARN", - "description": "Lambda ARN used to invoke this service deployment.", - "allOf": [ + "type": "null" + }, { - "$ref": "#/components/schemas/LambdaARN" + "$ref": "#/components/schemas/SerdeableHeaderHashMap", + "description": "# Additional headers\n\nAdditional headers added to every discover/invoke request to the deployment." } ] }, - "assume_role_arn": { - "title": "Assume role ARN", - "description": "Assume role ARN used to invoke this deployment. Check https://docs.restate.dev/category/aws-lambda for more details.", + "arn": { "type": "string", - "nullable": true + "description": "# ARN\n\nARN to use to discover/invoke the lambda deployment." }, - "compression": { - "title": "Compression", - "description": "Compression algorithm used for invoking Lambda.", - "allOf": [ - { - "$ref": "#/components/schemas/EndpointLambdaCompression" - } + "assume_role_arn": { + "type": [ + "string", + "null" ], - "nullable": true - }, - "additional_headers": { - "title": "Additional headers", - "description": "Additional headers used to invoke this service deployment.", - "type": "object", - "additionalProperties": { - "type": "string" - } - }, - "metadata": { - "title": "Metadata", - "description": "Deployment metadata.", - "type": "object", - "additionalProperties": { - "type": "string" - } - }, - "created_at": { - "type": "string" - }, - "min_protocol_version": { - "title": "Minimum Service Protocol version", - "description": "During registration, the SDKs declare a range from minimum (included) to maximum (included) Service Protocol supported version.", - "type": "integer", - "format": "int32" - }, - "max_protocol_version": { - "title": "Maximum Service Protocol version", - "description": "During registration, the SDKs declare a range from minimum (included) to maximum (included) Service Protocol supported version.", - "type": "integer", - "format": "int32" - }, - "sdk_version": { - "title": "SDK version", - "description": "SDK library and version declared during registration.", - "type": "string", - "nullable": true - }, - "services": { - "title": "Services", - "description": "List of services exposed by this deployment.", - "type": "array", - "items": { - "$ref": "#/components/schemas/ServiceMetadata" - } - } - } - } - ] - }, - "UpdateDeploymentRequest": { - "anyOf": [ - { - "title": "UpdateHttpDeploymentRequest", - "description": "Update HTTP deployment request", - "type": "object", - "properties": { - "uri": { - "title": "Uri", - "description": "Uri to use to discover/invoke the http deployment.", - "type": "string", - "nullable": true - }, - "additional_headers": { - "title": "Additional headers", - "description": "Additional headers added to the discover/invoke requests to the deployment. When provided, this will overwrite all the headers previously configured for this deployment.", - "type": "object", - "additionalProperties": { - "type": "string" - }, - "nullable": true + "description": "# Assume role ARN\n\nOptional ARN of a role to assume when invoking the addressed Lambda, to support role chaining" }, - "use_http_11": { - "title": "Use http1.1", - "description": "If `true`, discovery will be attempted using a client that defaults to HTTP1.1 instead of a prior-knowledge HTTP2 client. HTTP2 may still be used for TLS servers that advertise HTTP2 support via ALPN. HTTP1.1 deployments will only work in request-response mode.", + "breaking": { "type": "boolean", - "nullable": true - }, - "overwrite": { - "title": "Overwrite", - "description": "If `true`, the update will overwrite the schema information, including the exposed service and handlers and service configuration, allowing **breaking changes** too. Use with caution.", - "default": false, - "type": "boolean" + "description": "# Breaking\n\nIf `true`, it allows registering new service revisions with\nschemas incompatible with previous service revisions, such as changing service type, removing a handler, etc.\n\nSee the [versioning documentation](https://docs.restate.dev/operate/versioning) for more information." }, "dry_run": { - "title": "Dry-run mode", - "description": "If `true`, discovery will run but the deployment will not be registered. This is useful to see the impact of a new deployment before registering it.", - "default": false, - "type": "boolean" - } - } - }, - { - "title": "UpdateLambdaDeploymentRequest", - "description": "Update Lambda deployment request", - "type": "object", - "properties": { - "arn": { - "title": "ARN", - "description": "ARN to use to discover/invoke the lambda deployment.", - "type": "string", - "nullable": true + "type": "boolean", + "description": "# Dry-run mode\n\nIf `true`, discovery will run but the deployment will not be registered.\nThis is useful to see the impact of a new deployment before registering it.\n`force` and `breaking` will be respected." }, - "assume_role_arn": { - "title": "Assume role ARN", - "description": "Optional ARN of a role to assume when invoking the addressed Lambda, to support role chaining.", - "type": "string", - "nullable": true + "force": { + "type": [ + "boolean", + "null" + ], + "description": "# Force\n\nIf `true`, it overrides, if existing, any deployment using the same `uri`.\nBeware that this can lead inflight invocations to an unrecoverable error state.\n\nThis implies `breaking = true`.\n\nSee the [versioning documentation](https://docs.restate.dev/operate/versioning) for more information.", + "default": true }, - "additional_headers": { - "title": "Additional headers", - "description": "Additional headers added to the discover/invoke requests to the deployment. When provided, this will overwrite all the headers previously configured for this deployment.", + "metadata": { "type": "object", + "description": "# Metadata\n\nDeployment metadata.", "additionalProperties": { "type": "string" }, - "nullable": true - }, - "overwrite": { - "title": "Overwrite", - "description": "If `true`, the update will overwrite the schema information, including the exposed service and handlers and service configuration, allowing **breaking changes** too. Use with caution.", - "default": false, - "type": "boolean" - }, - "dry_run": { - "title": "Dry-run mode", - "description": "If `true`, discovery will run but the deployment will not be registered. This is useful to see the impact of a new deployment before registering it.", - "default": false, - "type": "boolean" + "propertyNames": { + "type": "string" + } } } } ] }, - "DeletionMode": { - "type": "string", - "enum": [ - "Cancel", - "Kill", - "Purge" - ] - }, - "RestartAsNewInvocationResponse": { - "type": "object", - "required": [ - "new_invocation_id" - ], - "properties": { - "new_invocation_id": { - "description": "The invocation id of the new invocation.", - "allOf": [ - { - "$ref": "#/components/schemas/String" - } - ] - } - } - }, - "ListServicesResponse": { + "RegisterDeploymentResponse": { "type": "object", "required": [ + "id", "services" ], "properties": { + "id": { + "$ref": "#/components/schemas/DeploymentId" + }, + "info": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Info" + }, + "description": "# Info\n\nList of configuration/deprecation information related to this deployment." + }, + "max_protocol_version": { + "type": "integer", + "format": "int32", + "description": "# Maximum Service Protocol version\n\nDuring registration, the SDKs declare a range from minimum (included) to maximum (included) Service Protocol supported version." + }, + "min_protocol_version": { + "type": "integer", + "format": "int32", + "description": "# Minimum Service Protocol version\n\nDuring registration, the SDKs declare a range from minimum (included) to maximum (included) Service Protocol supported version." + }, + "sdk_version": { + "type": [ + "string", + "null" + ], + "description": "# SDK version\n\nSDK library and version declared during registration." + }, "services": { "type": "array", "items": { @@ -3219,201 +3349,445 @@ } } }, - "ModifyServiceRequest": { + "RestartAsNewInvocationResponse": { + "type": "object", + "description": "The invocation was restarted as new.", + "required": [ + "new_invocation_id" + ], + "properties": { + "new_invocation_id": { + "$ref": "#/components/schemas/String", + "description": "The invocation id of the new invocation." + } + } + }, + "SerdeableHeaderHashMap": { + "type": "object", + "description": "Proxy type to implement HashMap ser/de\nUse it directly or with `#[serde(with = \"serde_with::As::>\")]`.", + "additionalProperties": { + "type": "string" + }, + "propertyNames": { + "type": "string" + } + }, + "ServiceMetadata": { "type": "object", + "description": "Metadata of a registered service.", + "required": [ + "name", + "ty", + "handlers", + "deployment_id", + "revision" + ], "properties": { - "public": { - "title": "Public", - "description": "If true, the service can be invoked through the ingress. If false, the service can be invoked only from another Restate service.", - "default": null, + "abort_timeout": { + "type": "string", + "description": "# Abort timeout\n\nThis timer guards against stalled service/handler invocations that are supposed to\nterminate. The abort timeout is started after the 'inactivity timeout' has expired\nand the service/handler invocation has been asked to gracefully terminate. Once the\ntimer expires, it will abort the service/handler invocation.\n\nThis timer potentially **interrupts** user code. If the user code needs longer to\ngracefully terminate, then this value needs to be set accordingly.\n\nCan be configured using the [`jiff::fmt::friendly`](https://docs.rs/jiff/latest/jiff/fmt/friendly/index.html) format or ISO8601, for example `5 hours`.\n\nIf unset, this returns the default abort timeout configured in invoker options." + }, + "deployment_id": { + "$ref": "#/components/schemas/DeploymentId", + "description": "# Deployment Id\n\nDeployment exposing the latest revision of the service." + }, + "documentation": { + "type": [ + "string", + "null" + ], + "description": "# Documentation\n\nDocumentation of the service, as propagated by the SDKs." + }, + "enable_lazy_state": { "type": "boolean", - "nullable": true + "description": "# Enable lazy state\n\nIf true, lazy state will be enabled for all invocations to this service.\nThis is relevant only for Workflows and Virtual Objects." + }, + "handlers": { + "type": "array", + "items": { + "$ref": "#/components/schemas/HandlerMetadata" + }, + "description": "# Handlers\n\nHandlers for this service." }, "idempotency_retention": { - "title": "Idempotency retention", - "description": "Modify the retention of idempotent requests for this service.\n\nCan be configured using the [`jiff::fmt::friendly`](https://docs.rs/jiff/latest/jiff/fmt/friendly/index.html) format or ISO8601, for example `5 hours`.", - "default": null, "type": "string", - "nullable": true + "description": "# Idempotency retention\n\nThe retention duration of idempotent requests for this service.\n\nIf not configured, this returns the default idempotency retention.\n\nCan be configured using the [`jiff::fmt::friendly`](https://docs.rs/jiff/latest/jiff/fmt/friendly/index.html) format or ISO8601, for example `5 hours`." }, - "workflow_completion_retention": { - "title": "Workflow completion retention", - "description": "Modify the retention of the workflow completion. This can be modified only for workflow services!\n\nCan be configured using the [`jiff::fmt::friendly`](https://docs.rs/jiff/latest/jiff/fmt/friendly/index.html) format or ISO8601, for example `5 hours`.", - "default": null, + "inactivity_timeout": { "type": "string", - "nullable": true + "description": "# Inactivity timeout\n\nThis timer guards against stalled service/handler invocations. Once it expires,\nRestate triggers a graceful termination by asking the service invocation to\nsuspend (which preserves intermediate progress).\n\nThe 'abort timeout' is used to abort the invocation, in case it doesn't react to\nthe request to suspend.\n\nCan be configured using the [`jiff::fmt::friendly`](https://docs.rs/jiff/latest/jiff/fmt/friendly/index.html) format or ISO8601, for example `5 hours`.\n\nIf unset, this returns the default inactivity timeout configured in invoker options." + }, + "info": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Info" + }, + "description": "# Info\n\nList of configuration/deprecation information related to this service." }, "journal_retention": { - "title": "Journal retention", - "description": "Modify the journal retention for this service. When set, this applies to all requests to all handlers of this service.\n\nIn case the invocation has an idempotency key, the `idempotency_retention` caps the maximum `journal_retention` time. In case the invocation targets a workflow handler, the `workflow_completion_retention` caps the maximum `journal_retention` time.\n\nCan be configured using the [`jiff::fmt::friendly`](https://docs.rs/jiff/latest/jiff/fmt/friendly/index.html) format or ISO8601, for example `5 hours`.", - "default": null, - "type": "string", - "nullable": true + "type": [ + "string", + "null" + ], + "description": "# Journal retention\n\nThe journal retention. When set, this applies to all requests to all handlers of this service.\n\nIn case the invocation has an idempotency key, the `idempotency_retention` caps the maximum `journal_retention` time.\nIn case the invocation targets a workflow handler, the `workflow_completion_retention` caps the maximum `journal_retention` time.\n\nCan be configured using the [`jiff::fmt::friendly`](https://docs.rs/jiff/latest/jiff/fmt/friendly/index.html) format or ISO8601, for example `5 hours`." }, - "inactivity_timeout": { - "title": "Inactivity timeout", - "description": "This timer guards against stalled service/handler invocations. Once it expires, Restate triggers a graceful termination by asking the service invocation to suspend (which preserves intermediate progress).\n\nThe 'abort timeout' is used to abort the invocation, in case it doesn't react to the request to suspend.\n\nCan be configured using the [`jiff::fmt::friendly`](https://docs.rs/jiff/latest/jiff/fmt/friendly/index.html) format or ISO8601, for example `5 hours`.\n\nThis overrides the default inactivity timeout set in invoker options.", - "default": null, - "type": "string", - "nullable": true + "metadata": { + "type": "object", + "description": "# Metadata\n\nAdditional service metadata, as propagated by the SDKs.", + "additionalProperties": { + "type": "string" + }, + "propertyNames": { + "type": "string" + } }, - "abort_timeout": { - "title": "Abort timeout", - "description": "This timer guards against stalled service/handler invocations that are supposed to terminate. The abort timeout is started after the 'inactivity timeout' has expired and the service/handler invocation has been asked to gracefully terminate. Once the timer expires, it will abort the service/handler invocation.\n\nThis timer potentially **interrupts** user code. If the user code needs longer to gracefully terminate, then this value needs to be set accordingly.\n\nCan be configured using the [`jiff::fmt::friendly`](https://docs.rs/jiff/latest/jiff/fmt/friendly/index.html) format or ISO8601, for example `5 hours`.\n\nThis overrides the default abort timeout set in invoker options.", - "default": null, + "name": { "type": "string", - "nullable": true + "description": "# Name\n\nFully qualified name of the service" + }, + "public": { + "type": "boolean", + "description": "# Public\n\nIf true, the service can be invoked through the ingress.\nIf false, the service can be invoked only from another Restate service." + }, + "retry_policy": { + "$ref": "#/components/schemas/ServiceRetryPolicyMetadata", + "description": "# Retry policy\n\nRetry policy applied to invocations of this service.\n\nIf unset, it returns the default values configured in the Restate configuration." + }, + "revision": { + "$ref": "#/components/schemas/u32", + "description": "# Revision\n\nLatest revision of the service." + }, + "ty": { + "$ref": "#/components/schemas/ServiceType", + "description": "# Type\n\nService type" + }, + "workflow_completion_retention": { + "type": [ + "string", + "null" + ], + "description": "# Workflow completion retention\n\nThe retention duration of workflows. Only available on workflow services.\n\nCan be configured using the [`jiff::fmt::friendly`](https://docs.rs/jiff/latest/jiff/fmt/friendly/index.html) format or ISO8601, for example `5 hours`." } } }, - "ListServiceHandlersResponse": { + "ServiceNameRevPair": { "type": "object", "required": [ - "handlers" + "name", + "revision" ], "properties": { - "handlers": { - "type": "array", - "items": { - "$ref": "#/components/schemas/HandlerMetadata" - } + "name": { + "type": "string" + }, + "revision": { + "$ref": "#/components/schemas/u32" } } }, - "ModifyServiceStateRequest": { + "ServiceRetryPolicyMetadata": { "type": "object", - "required": [ - "new_state", - "object_key" - ], + "description": "# Service retry policy", "properties": { - "version": { - "title": "Version", - "description": "If set, the latest version of the state is compared with this value and the operation will fail when the versions differ.", + "exponentiation_factor": { + "type": "number", + "format": "float", + "description": "# Factor\n\nThe factor to use to compute the next retry attempt. Default: `2.0`." + }, + "initial_interval": { "type": "string", - "nullable": true + "description": "# Initial Interval\n\nInitial interval for the first retry attempt.\n\nCan be configured using the [`jiff::fmt::friendly`](https://docs.rs/jiff/latest/jiff/fmt/friendly/index.html) format or ISO8601, for example `5 hours`." }, - "object_key": { - "title": "Service key", - "description": "To what virtual object key to apply this change", - "type": "string" + "max_attempts": { + "type": [ + "integer", + "null" + ], + "description": "# Max attempts\n\nNumber of maximum attempts (including the initial) before giving up. Infinite retries if unset. No retries if set to 1.", + "minimum": 1 }, - "new_state": { - "title": "New State", - "description": "The new state to replace the previous state with", - "type": "object", - "additionalProperties": { - "type": "array", - "items": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - } - } + "max_interval": { + "type": [ + "string", + "null" + ], + "description": "# Max interval\n\nMaximum interval between retries.\n\nCan be configured using the [`jiff::fmt::friendly`](https://docs.rs/jiff/latest/jiff/fmt/friendly/index.html) format or ISO8601, for example `5 hours`." + }, + "on_max_attempts": { + "$ref": "#/components/schemas/OnMaxAttempts", + "description": "# On max attempts\n\nBehavior when max attempts are reached." } } }, - "ListSubscriptionsResponse": { + "ServiceType": { + "type": "string", + "enum": [ + "Service", + "VirtualObject", + "Workflow" + ] + }, + "SimpleKafkaClusterResponse": { "type": "object", + "description": "Kafka cluster simple response.", "required": [ - "subscriptions" + "name", + "properties", + "created_at" ], "properties": { - "subscriptions": { - "type": "array", - "items": { - "$ref": "#/components/schemas/SubscriptionResponse" + "created_at": { + "type": "string", + "description": "# Created at\n\nWhen the Kafka cluster configuration was created." + }, + "name": { + "type": "string", + "description": "# Cluster Name\n\nName for the Kafka cluster, used to identify this Kafka cluster configuration in subscriptions. Must be a valid hostname format." + }, + "properties": { + "type": "object", + "description": "# Properties\n\nProperties for connecting to the kafka cluster.\n\nFor a full list of configuration properties, check the [librdkafka documentation](https://github.com/confluentinc/librdkafka/blob/master/CONFIGURATION.md).", + "additionalProperties": { + "type": "string" + }, + "propertyNames": { + "type": "string" } } } }, + "String": { + "type": "string" + }, + "SubscriptionId": { + "type": "string" + }, "SubscriptionResponse": { "type": "object", + "description": "Subscription details.", "required": [ "id", - "options", + "source", "sink", - "source" + "options" ], "properties": { "id": { - "$ref": "#/components/schemas/String" - }, - "source": { - "type": "string" - }, - "sink": { - "type": "string" + "$ref": "#/components/schemas/SubscriptionId" }, "options": { "type": "object", "additionalProperties": { "type": "string" + }, + "propertyNames": { + "type": "string" } + }, + "sink": { + "type": "string" + }, + "source": { + "type": "string" } } }, - "CreateSubscriptionRequest": { + "UpdateDeploymentRequest": { + "oneOf": [ + { + "type": "object", + "title": "UpdateHttpDeploymentRequest", + "description": "Update HTTP deployment request", + "properties": { + "additional_headers": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/SerdeableHeaderHashMap", + "description": "# Additional headers\n\nAdditional headers added to the discover/invoke requests to the deployment.\nWhen provided, this will overwrite all the headers previously configured for this deployment." + } + ] + }, + "dry_run": { + "type": "boolean", + "description": "# Dry-run mode\n\nIf `true`, discovery will run but the deployment will not be registered.\nThis is useful to see the impact of a new deployment before registering it." + }, + "overwrite": { + "type": "boolean", + "description": "# Overwrite\n\nIf `true`, the update will overwrite the schema information, including the exposed service and handlers and service configuration, allowing **breaking changes** too. Use with caution." + }, + "uri": { + "type": [ + "string", + "null" + ], + "format": "uri", + "description": "# Uri\n\nUri to use to discover/invoke the http deployment." + }, + "use_http_11": { + "type": [ + "boolean", + "null" + ], + "description": "# Use http1.1\n\nIf `true`, discovery will be attempted using a client that defaults to HTTP1.1\ninstead of a prior-knowledge HTTP2 client. HTTP2 may still be used for TLS servers\nthat advertise HTTP2 support via ALPN. HTTP1.1 deployments will only work in\nrequest-response mode." + } + } + }, + { + "type": "object", + "title": "UpdateLambdaDeploymentRequest", + "description": "Update Lambda deployment request", + "properties": { + "additional_headers": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/SerdeableHeaderHashMap", + "description": "# Additional headers\n\nAdditional headers added to the discover/invoke requests to the deployment.\nWhen provided, this will overwrite all the headers previously configured for this deployment." + } + ] + }, + "arn": { + "type": [ + "string", + "null" + ], + "description": "# ARN\n\nARN to use to discover/invoke the lambda deployment." + }, + "assume_role_arn": { + "type": [ + "string", + "null" + ], + "description": "# Assume role ARN\n\nOptional ARN of a role to assume when invoking the addressed Lambda, to support role chaining." + }, + "dry_run": { + "type": "boolean", + "description": "# Dry-run mode\n\nIf `true`, discovery will run but the deployment will not be registered.\nThis is useful to see the impact of a new deployment before registering it." + }, + "overwrite": { + "type": "boolean", + "description": "# Overwrite\n\nIf `true`, the update will overwrite the schema information, including the exposed service and handlers and service configuration, allowing **breaking changes** too. Use with caution." + } + } + } + ] + }, + "UpdateKafkaClusterRequest": { "type": "object", + "description": "Update Kafka cluster request", "required": [ - "sink", - "source" + "properties" ], "properties": { - "source": { - "title": "Source", - "description": "Source uri. Accepted forms:\n\n* `kafka:///`, e.g. `kafka://my-cluster/my-topic`", - "type": "string" - }, - "sink": { - "title": "Sink", - "description": "Sink uri. Accepted forms:\n\n* `service:///`, e.g. `service://Counter/count`", - "type": "string" - }, - "options": { - "title": "Options", - "description": "Additional options to apply to the subscription.", + "properties": { "type": "object", + "description": "# Properties\n\nUpdated Kafka cluster configuration properties. Must contain either\n'bootstrap.servers' or 'metadata.broker.list'.\n\nFor a full list of configuration properties, check the [librdkafka documentation](https://github.com/confluentinc/librdkafka/blob/master/CONFIGURATION.md).", "additionalProperties": { "type": "string" }, - "nullable": true + "propertyNames": { + "type": "string" + } } } }, "VersionInformation": { "type": "object", + "description": "Admin API version information", "required": [ - "ingress_endpoint", - "max_admin_api_version", + "version", "min_admin_api_version", - "version" + "max_admin_api_version" ], "properties": { - "version": { - "title": "Admin server version", - "description": "Version of the admin server", - "type": "string" + "ingress_endpoint": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/AdvertisedAddress-http-ingress-server_HttpIngressPort", + "description": "# Ingress endpoint\n\nIngress endpoint that the Web UI should use to interact with." + } + ] }, - "min_admin_api_version": { - "title": "Min admin API version", - "description": "Minimum supported admin API version by the admin server", + "max_admin_api_version": { "type": "integer", - "format": "uint16", - "minimum": 0.0 + "format": "int32", + "description": "# Max admin API version\n\nMaximum supported admin API version by the admin server", + "minimum": 0 }, - "max_admin_api_version": { - "title": "Max admin API version", - "description": "Maximum supported admin API version by the admin server", + "min_admin_api_version": { "type": "integer", - "format": "uint16", - "minimum": 0.0 + "format": "int32", + "description": "# Min admin API version\n\nMinimum supported admin API version by the admin server", + "minimum": 0 }, - "ingress_endpoint": { - "title": "Ingress endpoint", - "description": "Ingress endpoint that the Web UI should use to interact with.", + "version": { "type": "string", - "format": "uri" + "description": "# Admin server version\n\nVersion of the admin server" + } + } + }, + "u32": { + "type": "integer", + "format": "int32", + "minimum": 0 + } + }, + "responses": { + "BadRequest": { + "description": "Bad request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorDescriptionResponse" + } + } + } + }, + "Conflict": { + "description": "Conflict", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorDescriptionResponse" + } + } + } + }, + "InternalServerError": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorDescriptionResponse" + } + } + } + }, + "MethodNotAllowed": { + "description": "Method not allowed", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorDescriptionResponse" + } + } + } + }, + "NotFound": { + "description": "Not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorDescriptionResponse" + } } } } @@ -3428,16 +3802,22 @@ "name": "invocation", "description": "Invocation management", "externalDocs": { - "url": "https://docs.restate.dev/operate/invocation" + "url": "https://docs.restate.dev/operate/invocation", + "description": "Invocations documentation" } }, { "name": "subscription", "description": "Subscription management", "externalDocs": { - "url": "https://docs.restate.dev/operate/invocation#managing-kafka-subscriptions" + "url": "https://docs.restate.dev/operate/invocation#managing-kafka-subscriptions", + "description": "Kafka subscriptions documentation" } }, + { + "name": "kafka_cluster", + "description": "Kafka cluster management" + }, { "name": "service", "description": "Service management" @@ -3457,9 +3837,14 @@ { "name": "version", "description": "API Version" + }, + { + "name": "introspection", + "description": "System introspection" } ], "externalDocs": { - "url": "https://docs.restate.dev/operate/" + "url": "https://docs.restate.dev/operate/", + "description": "Restate operations documentation" } }