diff --git a/reference/REDAME.md b/reference/REDAME.md index b587a926a..bc08c55df 100644 --- a/reference/REDAME.md +++ b/reference/REDAME.md @@ -1,4 +1,4 @@ # Dapr References - **[Dapr CLI](https://github.com/dapr/cli)**: The Dapr CLI allows you to setup Dapr on your local dev machine or on a Kubernetes cluster, provides debugging support, launches and manages Dapr instances. -- **[Dapr Spec](https://github.com/dapr/spec)**: Provides a clear understanding of the Dapr runtime API surface and help evolve it for the benefit of developers everywhere. +- **[Dapr API](./api)**: Provides a clear understanding of the Dapr runtime HTTP API surface and help evolve it for the benefit of developers everywhere. diff --git a/reference/api/CONTRIBUTING.md b/reference/api/CONTRIBUTING.md new file mode 100644 index 000000000..fcc32a7df --- /dev/null +++ b/reference/api/CONTRIBUTING.md @@ -0,0 +1,121 @@ +# Contributing Guidelines + +The Dapr API Specification project accepts contributions via GitHub pull requests. This document outlines the process for merging contributions to the spec. + +## Issues + +Issues are used as the primary method for tracking anything to do with the Dapr API Specification project. + +### Issue Types + +There are 4 types of issues (each with their own corresponding [label](#labels)): +- Discussion: These are support or functionality inquiries that we want to have a record of for +future reference. Depending on the discussion, these can turn into "Spec Change" issues. +- Proposal: Used for items that propose a new ideas or functionality that require +a larger discussion. This allows for feedback from others teams before a +spec change is actually written. All issues that are proposals should +both have a label and an issue title of "Proposal: [the rest of the title]." A proposal can become +a "Spec Change" and does not require a milestone. +- Spec Change: These track specific spec changes and ideas until they are complete. They can evolve +from "Proposal" and "Discussion" items, or can be submitted individually depending on the size. + +### Issue Lifecycle + +The issue lifecycle is mainly driven by the core maintainers, but is good information for those +contributing to Helm. All issue types follow the same general lifecycle. Differences are noted below. +1. Issue creation +2. Triage + - The maintainer in charge of triaging will apply the proper labels for the issue. This + includes labels for priority, type, and metadata. + - (If needed) Clean up the title to succinctly and clearly state the issue. Also ensure + that proposals are prefaced with "Proposal". + - We attempt to do this process at least once per work day. +3. Discussion + - "Spec Change" issues should be connected to the PR that resolves it. + - Whoever is working on a "Spec Change" issue should either assign the issue to themself or make a comment in the issue + saying that they are taking it. + - "Proposal" and "Discussion" issues should stay open until resolved. +4. Issue closure + +## How to Contribute a Patch + +1. Fork the repo, modify the specification to address the issue. +1. Submit a pull request. + +The next section contains more information on the workflow followed for Pull Requests. + +## Pull Requests and Issues + +Like any good open source project, we use Pull Requests (PRs) to track code changes. + +### PR Lifecycle + +1. PR creation + - We more than welcome PRs that are currently in progress. They are a great way to keep track of + important work that is in-flight, but useful for others to see. If a PR is a work in progress, + it **should** be prefaced with "WIP: [title]". You should also add the `wip` **label** Once the PR is ready for review, remove "WIP" from the title and label. + - It is preferred, but not required, to have a PR tied to a specific issue. There can be + circumstances where if it is a quick fix then an issue might be overkill. The details provided + in the PR description would suffice in this case. +2. Triage + - The maintainer in charge of triaging will apply the proper labels for the issue. This should + include at least a size label, a milestone, and `awaiting review` once all labels are applied. + See the [Labels section](#labels) for full details on the definitions of labels. +3. Assigning reviews + - All PRs require at least 2 review approvals before it can be merged. +4. Reviewing/Discussion + - All reviews will be completed using Github review tool. + - A "Comment" review should be used when there are questions about the spec that should be + answered, but that don't involve spec changes. This type of review does not count as approval. + - A "Changes Requested" review indicates that changes to the spec need to be made before they will be + merged. + - Reviewers should update labels as needed (such as `needs rebase`). + - When a review is approved, the reviewer should add `LGTM` as a comment. + - Final approval is required by a designated owner (see `.github/CODEOWNERS` file). Merging is blocked without this final approval. Approvers will factor reviews from all other reviewers into their approval process. +5. PR owner should try to be responsive to comments by answering questions or changing text. Once all comments have been addressed, + the PR is ready to be merged. +6. Merge or close + - A PR should stay open until a Final Approver (see above) has marked the PR approved. + - PRs can be closed by the author without merging + - PRs may be closed by a Final Approver if the decision is made that the PR is not going to be merged + +## The Triager + +Each week, someone from the Dapr team should act as the triager. This person will be in charge triaging new PRs and issues throughout the day. + +## Labels + +The following tables define all label types used for the Dapr API Specification. It is split up by category. + +### Common + +| Label | Description | +| ----- | ----------- | +| `high priority` | Marks an issue or PR as critical. This means that addressing the PR or issue is top priority and will be handled first | +| `duplicate` | Indicates that the issue or PR is a duplicate of another | +| `spec change` | Marks the issue or a PR as an agreed upon change to the spec | +| `wip` | Identifies an issue or PR as a work in progress | + +### Issue Specific + +| Label | Description | +| ----- | ----------- | +| `proposal` | This issue is a proposal | +| `discussion` | This issue is a question or discussion point to capture feedback | + +### PR Specific + +| Label | Description | +| ----- | ----------- | +| `awaiting review` | The PR has been triaged and is ready for someone to review | +| `needs rebase` | A helper label used to indicate that the PR needs to be rebased before it can be merged. Used for easy filtering | + +#### Size labels + +Size labels are used to indicate how much change is in a given PR. This is helpful for estimating review time. + +| Label | Description | +| ----- | ----------- | +| `size/small` | Anything less than or equal to 4 files and 150 lines. | +| `size/medium` | Anything greater than `size/small` and less than or equal to 8 files and 300 lines. | +| `size/large` | Anything greater than `size/medium`. This also should be applied to anything that is a significant specification change. diff --git a/reference/api/LICENSE b/reference/api/LICENSE new file mode 100644 index 000000000..b2f52a2ba --- /dev/null +++ b/reference/api/LICENSE @@ -0,0 +1,21 @@ +Copyright (c) Microsoft Corporation. + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/reference/api/README.md b/reference/api/README.md new file mode 100644 index 000000000..7490295d7 --- /dev/null +++ b/reference/api/README.md @@ -0,0 +1,29 @@ +# Dapr API reference + +This repository holds the API reference for the Dapr runtime. + +Dapr is an open source runtime that provides a set of building blocks for building scalable distributed apps. +Building blocks include pub-sub, state management, bindings, messaging and invocation, actor runtime capabilities, and more. + +Dapr aims to provide an open, community driven approach to solving real world problems at scale. + +These building blocks are provided in a platform agnostic and language agnostic way over common protocols such as HTTP 1.1/2.0 and gRPC. + +### Goals + +The goal of the Dapr API reference is to provide a clear understanding of the Dapr runtime API surface and help evolve it for the benefit of developers everywhere. + +Any changes/proposals to the Dapr API should adhere to the following: + +* Must be platform agnostic +* Must be programming language agnostic +* Must be backward compatible + +## Table of Contents + + 1. [Messaging](service_invocation.md) + 2. [Bindings](bindings.md) + 3. [Pub Sub/Broadcast](pubsub.md) + 4. [State Management](state.md) + 5. [Actors](actors.md) + 6. [Metadata](metadata.md) diff --git a/reference/api/actors.md b/reference/api/actors.md new file mode 100644 index 000000000..d27f395ad --- /dev/null +++ b/reference/api/actors.md @@ -0,0 +1,533 @@ +# Actors + +Dapr has a native, cross platform and cross-language virtual actor capabilities. +Besides the language specific Dapr SDKs, a developer can invoke an actor using the API endpoints below. + +## Specifications for user service code calling to Dapr + +### Invoke a method on an Actor + +This endpoint lets you invoke a method on a remote Actor. + +#### HTTP Request + +`POST/GET/PUT/DELETE http://localhost:3500/v1.0/actors///method/` + +#### HTTP Response codes + +Code | Description +---- | ----------- +200 | Request successful +500 | Request failed +404 | Actor not found + +#### URL Parameters + +Parameter | Description +--------- | ----------- +actorType | the actor type +actorId | the actor id +method | the name of the method to invoke on the remote actor + +> Example of invoking a method on a remote actor: + +```shell +curl -X POST http://localhost:3500/v1.0/actors/stormtrooper/50/method/shoot \ + -H "Content-Type: application/json" +``` + +> Example of invoking a method on a remote actor with a payload: + +```shell +curl -X POST http://localhost:3500/v1.0/actors/x-wing/33/method/fly \ + -H "Content-Type: application/json" + -d '{ + "destination": "Hoth" + }' +``` + +> The response from the remote endpoint will be returned in the request body. + +### Save actor state + +This endpoint lets you save state for a given actor for a given key. + +#### HTTP Request + +`POST/PUT http://localhost:3500/v1.0/actors///state/` + +#### HTTP Response codes + +Code | Description +---- | ----------- +201 | Request successful +500 | Request failed +404 | Actor not found + +#### URL Parameters + +Parameter | Description +--------- | ----------- +actorType | the actor type +actorId | the actor id +key | key for the state value + +```shell +curl -X POST http://localhost:3500/v1.0/actors/stormtrooper/50/state/location \ + -H "Content-Type: application/json" + -d '{ + "location": "Alderaan" + }' +``` + +### Save actor state - transaction + +This endpoint lets you save an actor's state as a multi item transaction. + +***Note that this operation is dependant on a state store that supports multi item transactions.*** + +#### HTTP Request + +`POST/PUT http://localhost:3500/v1.0/actors///state` + +#### HTTP Response codes + +Code | Description +---- | ----------- +201 | Request successful +500 | Request failed +404 | Actor not found + +#### URL Parameters + +Parameter | Description +--------- | ----------- +actorType | the actor type +actorId | the actor id + +```shell +curl -X POST http://localhost:3500/v1.0/actors/stormtrooper/50/state \ + -H "Content-Type: application/json" + -d '[ + { + "operation": "upsert", + "request": { + "key": "key1", + "value": "myData" + } + }, + { + "operation": "delete", + "request": { + "key": "key2" + } + } + ]' +``` + +### Get actor state + +This endpoint lets you get the state of a given actor for a given key. + +#### HTTP Request + +`GET http://localhost:3500/v1.0/actors///state/` + +#### HTTP Response codes + +Code | Description +---- | ----------- +200 | Request successful +500 | Request failed +404 | Actor not found + +#### URL Parameters + +Parameter | Description +--------- | ----------- +actorType | the actor type +actorId | the actor id +key | key for the state value + +```shell +curl http://localhost:3500/v1.0/actors/stormtrooper/50/state/location \ + -H "Content-Type: application/json" +``` + +> The above command returns the state: + +```json +{ + "location": "Alderaan" +} +``` + +### Delete actor state + +This endpoint lets you delete the state of a given actor for a given key. + +#### HTTP Request + +`DELETE http://localhost:3500/v1.0/actors///state/` + +#### HTTP Response codes + +Code | Description +---- | ----------- +200 | Request successful +500 | Request failed +404 | Actor not found + +#### URL Parameters + +Parameter | Description +--------- | ----------- +actorType | the actor type +actorId | the actor id +key | key for the state value + +```shell +curl http://localhost:3500/v1.0/actors/stormtrooper/50/state/location \ + -X "Content-Type: application/json" +``` + +### Set actor reminder + +This endpoint lets you create a persistent reminder for an actor. + +#### HTTP Request + +`POST,PUT http://localhost:3500/v1.0/actors///reminders/` + +#### HTTP Response codes + +Code | Description +---- | ----------- +200 | Request successful +500 | Request failed +404 | Actor not found + +#### URL Parameters + +Parameter | Description +--------- | ----------- +actorType | the actor type +actorId | the actor id +name | the name of the reminder + +```shell +curl http://localhost:3500/v1.0/actors/stormtrooper/50/reminders/checkRebels \ + -H "Content-Type: application/json" +-d '{ + "data": "someData", + "dueTime": "1m", + "period": "20s" + }' +``` + +### Get actor reminder + +This endpoint lets get a reminder for an actor + +#### HTTP Request + +`GET http://localhost:3500/v1.0/actors///reminders/` + +#### HTTP Response codes + +Code | Description +---- | ----------- +200 | Request successful +500 | Request failed +404 | Actor not found + +#### URL Parameters + +Parameter | Description +--------- | ----------- +actorType | the actor type +actorId | the actor id +name | the name of the reminder to get + +```shell +curl http://localhost:3500/v1.0/actors/stormtrooper/50/reminders/checkRebels \ + "Content-Type: application/json" +``` + +> The above command returns the reminder: + +```json +{ + "dueTime": "1s", + "period": "5s", + "data": "0", +} +``` + +### Delete actor reminder + +This endpoint lets delete a reminder for an actor + +#### HTTP Request + +`DELETE http://localhost:3500/v1.0/actors///reminders/` + +#### HTTP Response codes + +Code | Description +---- | ----------- +200 | Request successful +500 | Request failed +404 | Actor not found + +#### URL Parameters + +Parameter | Description +--------- | ----------- +actorType | the actor type +actorId | the actor id +name | the name of the reminder to delete + +```shell +curl http://localhost:3500/v1.0/actors/stormtrooper/50/reminders/checkRebels \ + -X "Content-Type: application/json" +``` + +### Set actor timer + +This endpoint lets you create a timer for an actor. + +#### HTTP Request + +`POST,PUT http://localhost:3500/v1.0/actors///timers/` + +#### HTTP Response codes + +Code | Description +---- | ----------- +200 | Request successful +500 | Request failed +404 | Actor not found + +#### URL Parameters + +Parameter | Description +--------- | ----------- +actorType | the actor type +actorId | the actor id +name | the name of the timer + +```shell +curl http://localhost:3500/v1.0/actors/stormtrooper/50/timers/checkRebels \ + -H "Content-Type: application/json" +-d '{ + "data": "someData", + "dueTime": "1m", + "period": "20s", + "callback": "myEventHandler" + }' +``` + +### Delete actor timer + +This endpoint lets delete a timer for an actor + +#### HTTP Request + +`DELETE http://localhost:3500/v1.0/actors///timers/` + +#### HTTP Response codes + +Code | Description +---- | ----------- +200 | Request successful +500 | Request failed +404 | Actor not found + +#### URL Parameters + +Parameter | Description +--------- | ----------- +actorType | the actor type +actorId | the actor id +name | the name of the timer to delete + +```shell +curl http://localhost:3500/v1.0/actors/stormtrooper/50/timers/checkRebels \ + -X "Content-Type: application/json" +``` + +## Specifications for Dapr calling to user service code + +### Get Registered Actors + +This endpoint lets you get the registered actors in Dapr. + +#### HTTP Request + +`GET http://localhost:/v1.0/dapr/config` + +#### HTTP Response codes + +Code | Description +---- | ----------- +200 | Request successful +500 | Request failed + +#### URL Parameters + +Parameter | Description +--------- | ----------- +appPort | the application port + +> Example of getting the registered actors: + +```shell +curl -X GET http://localhost:5001/v1.0/dapr/config \ + -H "Content-Type: application/json" +``` + +### Activate the Actors + +This endpoint lets you activate the actor. + +#### HTTP Request + +`POST http://localhost:/v1.0/actors//` + +#### HTTP Response codes + +Code | Description +---- | ----------- +200 | Request successful +500 | Request failed +404 | Actor not found + +#### URL Parameters + +Parameter | Description +--------- | ----------- +appPort | the application port +actorType | the actor type +actorId | the actor id + +> Example of activating the actor: + +```shell +curl -X POST http://localhost:5001/v1.0/actors/stormtrooper/50 \ + -H "Content-Type: application/json" +``` + +### Deactivate the Actors + +This endpoint lets you deactivate the actor. + +#### HTTP Request + +`DELETE http://localhost:/v1.0/actors//` + +#### HTTP Response codes + +Code | Description +---- | ----------- +200 | Request successful +500 | Request failed +404 | Actor not found + +#### URL Parameters + +Parameter | Description +--------- | ----------- +appPort | the application port +actorType | the actor type +actorId | the actor id + +> Example of deactivating the actor: + +```shell +curl -X DELETE http://localhost:5001/v1.0/actors/stormtrooper/50 \ + -H "Content-Type: application/json" +``` + +### Invoke the Reminders + +This endpoint lets you invokes the actor reminders. + +#### HTTP Request + +`PUT http://localhost:/v1.0/actors///method/remind/` + +#### HTTP Response codes + +Code | Description +---- | ----------- +200 | Request successful +500 | Request failed +404 | Actor not found + +#### URL Parameters + +Parameter | Description +--------- | ----------- +appPort | the application port +actorType | the actor type +actorId | the actor id +reminderName | the name of the reminder + +> Example of invoking the actor reminder: + +```shell +curl -X POST http://localhost:5001/v1.0/actors/stormtrooper/50/method/remind/checkRebels \ + -H "Content-Type: application/json" +``` + +### Invoke the Timers + +This endpoint lets you invokes the actor timers. + +#### HTTP Request + +`PUT http://localhost:/v1.0/actors///method/timer/` + +#### HTTP Response codes + +Code | Description +---- | ----------- +200 | Request successful +500 | Request failed +404 | Actor not found + +#### URL Parameters + +Parameter | Description +--------- | ----------- +appPort | the application port +actorType | the actor type +actorId | the actor id +timerName | the name of the timer + +> Example of invoking the actor timer: + +```shell +curl -X POST http://localhost:5001/v1.0/actors/stormtrooper/50/method/timer/checkRebels \ + -H "Content-Type: application/json" +``` + +## Querying actor state externally + +In order to promote visibility into the state of an actor and allow for complex scenarios such as state aggregation, Dapr saves actor state in external databases. + +As such, it is possible to query for an actor state externally by composing the correct key or query. +The state namespace created by Dapr for actors is composed of the following items: + +* Dapr ID - represents the unique ID given to the Dapr application. +* Actor Type - represents the type of the actor +* Actor ID - represents the unique ID of the actor instance for an actor type +* Key - A key for the specific state value. An actor ID can hold multiple state keys. + +The following example shows how to construct a key for the state of an actor instance under the `myapp` Dapr ID namespace: +`` +myapp-cat-hobbit-food +`` + +In the example above, we are getting the value for the state key `food`, for the actor ID `hobbit` with an actor type of `cat`, under the Dapr ID namespace of `myapp`. diff --git a/reference/api/azure-pipelines.yml b/reference/api/azure-pipelines.yml new file mode 100644 index 000000000..c7189599e --- /dev/null +++ b/reference/api/azure-pipelines.yml @@ -0,0 +1,67 @@ +# dapr/spec + +trigger: + - master + +pr : none + +pool: + vmImage: 'ubuntu-latest' + +steps: +- task: UseNode@1 + inputs: + version: '10.16.3' +- task: Bash@3 + displayName: 'Install md-to-pdf' + inputs: + targetType: 'inline' + script: | + npm install -g md-to-pdf + workingDirectory: '$(Build.SourcesDirectory)' +- task: Bash@3 + displayName: 'Create pdf output directory' + inputs: + targetType: 'inline' + script: | + mkdir ./output_pdf + mkdir ./output_md + workingDirectory: '$(Build.SourcesDirectory)' +- task: Bash@3 + displayName: 'Generate PDF files' + inputs: + targetType: 'inline' + script: | + echo Copying *.md to ./output_md/ + cp *.md ./output_md/ + + pushd ./output_md + + rm -f README.md CONTRIBUTING.md + + echo Genereating PDFs from markdown documents + for filename in *.md; do + md-to-pdf $filename ../output_pdf/$(basename $filename .md).pdf + done + + popd + workingDirectory: '$(Build.SourcesDirectory)' +- task: ArchiveFiles@2 + inputs: + rootFolderOrFile: '$(Build.SourcesDirectory)/output_pdf/' + includeRootFolder: false + archiveType: 'zip' + archiveFile: '$(Build.ArtifactStagingDirectory)/dapr-spec-pdf.zip' + replaceExistingArchive: true +- task: ArchiveFiles@2 + inputs: + rootFolderOrFile: '$(Build.SourcesDirectory)/output_md/' + includeRootFolder: false + archiveType: 'zip' + archiveFile: '$(Build.ArtifactStagingDirectory)/dapr-spec-md.zip' + replaceExistingArchive: true +- task: PublishBuildArtifacts@1 + inputs: + PathtoPublish: '$(Build.ArtifactStagingDirectory)' + ArtifactName: 'drop' + publishLocation: 'Container' \ No newline at end of file diff --git a/reference/api/bindings.md b/reference/api/bindings.md new file mode 100644 index 000000000..5c017e201 --- /dev/null +++ b/reference/api/bindings.md @@ -0,0 +1,109 @@ +# Bindings + +Dapr provides bi-directional binding capabilities for applications and a consistent approach to interacting with different cloud/on-premise services or systems. +Developers can invoke output bindings using the Dapr API, and have the Dapr runtime trigger an application with input bindings. + +Examples for bindings include ```Kafka```, ```Rabbit MQ```, ```Azure Event Hubs```, ```AWS SQS```, ```GCP Storage``` to name a few. + +An Dapr Binding has the following structure: + +``` +apiVersion: dapr.io/v1alpha1 +kind: Component +metadata: + name: +spec: + type: bindings. + metadata: + - name: + value: +``` + +The ```metadata.name``` is the name of the binding. A developer who wants to trigger her app using an input binding can listen on a ```POST``` http endpoint with the route name being the same as ```metadata.name```. + +the ```metadata``` section is an open key/value metadata pair that allows a binding to define connection properties, as well as custom properties unique to the implementation. + +For example, here's how a Python application subscribes for events from ```Kafka``` using an Dapr API compliant platform: + +#### Kafka Component + +```yaml +apiVersion: dapr.io/v1alpha1 +kind: Component +metadata: + name: kafkaevent +spec: + type: bindings.kafka + metadata: + - name: brokers + value: "http://localhost:5050" + - name: topics + value: "someTopic" + - name: publishTopic + value: "someTopic2" + - name: consumerGroup + value: "group1" +``` + +#### Python Code + +```python +from flask import Flask +app = Flask(__name__) + +@app.route("/kafkaevent", methods=['POST']) +def incoming(): + print("Hello from Kafka!", flush=True) + + return "Kafka Event Processed!" +``` + +## Sending messages to output bindings + +This endpoint lets you invoke an Dapr output binding. + +### HTTP Request + +`POST/GET/PUT/DELETE http://localhost:3500/v1.0/bindings/` + +### HTTP Response codes + +Code | Description +---- | ----------- +200 | Request successful +500 | Request failed + +### Payload + +The bindings endpoint receives the following JSON payload: + +``` +{ + "data": "", + "metadata": [ + "": "" + ] +} +``` + +The `data` field takes any JSON serializable value and acts as the payload to be sent to the output binding. +The metadata is an array of key/value pairs and allows to set binding specific metadata for each call. + +### URL Parameters + +Parameter | Description +--------- | ----------- +name | the name of the binding to invoke + +```shell +curl -X POST http://localhost:3500/v1.0/bindings/myKafka \ + -H "Content-Type: application/json" \ + -d '{ + "data": { + "message": "Hi" + }, + "metadata": [ + "key": "redis-key-1" + ] + }' +``` diff --git a/reference/api/metadata.md b/reference/api/metadata.md new file mode 100644 index 000000000..5bc3096d4 --- /dev/null +++ b/reference/api/metadata.md @@ -0,0 +1,44 @@ +# Metadata + +## Get Dapr metadata + +This endpoint lets you inspect additional data related to the running Dapr runtime instance. + +### HTTP Request + +`GET http://localhost:3500/v1.0/metadata` + +### HTTP Response codes + +Code | Description +---- | ----------- +200 | Request successful +500 | Request failed + +```shell +curl http://localhost:3500/v1.0/metadata \ + -H "Content-Type: application/json" +``` + +> The above command returns the following JSON: + +```json +{ + "id": "myApp", + "protocol": "gRPC", + "stateStore": "redis", + "appAddress": "http://localhost:8080", + "healthy": true, + "stateItemsCount": 1000, + "actors": [ + { + "actorType": "sith", + "activatedContexts": [ + "darth-vader", + "darth-nihilus", + "darth sidious" + ] + } + ] +} +``` \ No newline at end of file diff --git a/reference/api/pubsub.md b/reference/api/pubsub.md new file mode 100644 index 000000000..236939061 --- /dev/null +++ b/reference/api/pubsub.md @@ -0,0 +1,126 @@ +# Pub Sub and Broadcast + +## Publish a message to a given topic + +This endpoint lets you publish a payload to multiple consumers who are listening on a ```topic```. +Dapr guarantees at least once semantics for this endpoint. + +### HTTP Request + +```POST http://localhost:3500/v1.0/publish/``` +### HTTP Response codes + +Code | Description +---- | ----------- +200 | Message delivered +500 | Delivery failed + +```shell +curl -X POST http://localhost:3500/v1.0/publish/deathStarStatus \ + -H "Content-Type: application/json" \ + -d '{ + "status": "completed" + }' +``` + +## Broadcast a message to a list of recipients + +This endpoint lets you publish a payload to a named list recipients who are listening on a given ```topic```. +The list of recipients may include the unique identifiers of other apps (used by Dapr for messaging) and also Dapr bindings. + +### HTTP Request + +```POST http://localhost:3500/v1.0/publish/``` + +### HTTP Response codes + +Code | Description +---- | ----------- +200 | Message delivered +500 | Delivery failed + +> Example of publishing a message to another Dapr app: + +```shell +curl -X POST http://localhost:3500/v1.0/publish \ + -H "Content-Type: application/json" \ + -d '{ + "topic": "DeathStarStatus", + "data": { + "status": "completed" + }, + "to": [ + "otherApp" + ] + }' +``` + +> Example of publishing a message to an Dapr binding: + +```shell +curl -X POST http://localhost:3500/v1.0/publish \ + -H "Content-Type: application/json" \ + -d '{ + "topic": "DeathStarStatus", + "data": { + "status": "completed" + }, + "to": [ + "azure-queues" + ] + }' +``` + +> Example of publishing a message to multiple consumers in parallel: + +```shell +curl -X POST http://localhost:3500/v1.0/publish \ + -H "Content-Type: application/json" \ + -d '{ + "eventName": "DeathStarStatus", + "data": { + "status": "completed" + }, + "to": [ + "otherApp", + "azure-queues" + ], + "concurrency": "parallel" + }' +``` + +## Handling topic subscriptions + +In order to receive topic subscriptions, Dapr will invoke the following endpoint on user code: + +### HTTP Request + +```GET http://
/dapr/subscribe``` + +### HTTP Response body + +A json encoded array of strings. + +Example: + +` +"["TopicA","TopicB"]" +` + +## Delivering events to subscribers + +In order to deliver events to a subscribed application, a `POST` call should be made to user code with the name of the topic as the URL path. + +The following example illustrates this point, considering a subscription for topic `TopicA`: + +### HTTP Request + +```POST http://
/TopicA``` + +### HTTP Response body + +A JSON encoded payload. + +## Message Envelope + +Dapr Pub-Sub adheres to version 0.3 of Cloud Events. diff --git a/reference/api/service_invocation.md b/reference/api/service_invocation.md new file mode 100644 index 000000000..9972657d3 --- /dev/null +++ b/reference/api/service_invocation.md @@ -0,0 +1,43 @@ +# Service Invocation + +Dapr provides users with the ability to call other applications that have unique ids. +This functionality allows apps to interact with one another via named identifiers and puts the burden of service discovery on the Dapr runtime. + +## Invoke a method on a remote Dapr app + +This endpoint lets you invoke a method in another Dapr enabled app. + +### HTTP Request + +`POST/GET/PUT/DELETE http://localhost:3500/v1.0/invoke//method/` + +### HTTP Response codes + +Code | Description +---- | ----------- +200 | Request successful +500 | Request failed + +### URL Parameters + +Parameter | Description +--------- | ----------- +id | the Action ID associated with the remote app +method-name | the name of the method or url to invoke on the remote app + +```shell +curl http://localhost:3500/v1.0/invoke/countService/method/sum \ + -H "Content-Type: application/json" +``` + +### Sending data + +You can send data by posting it as part of the request body. + +```shell +curl http://localhost:3500/v1.0/invoke/countService/method/calculate \ + -H "Content-Type: application/json" + -d '{ "arg1": 10, "arg2": 23, "operator": "+" }' +``` + +> The response from the remote endpoint will be returned in the request body. diff --git a/reference/api/state.md b/reference/api/state.md new file mode 100644 index 000000000..6f4cbbe2a --- /dev/null +++ b/reference/api/state.md @@ -0,0 +1,246 @@ +# State management + +Dapr offers a reliable state endpoint that allows developers to save and retrieve state via an API. +Dapr has a pluggable architecture and allows binding to a multitude of cloud/on-premises state stores. + +Examples for state stores include ```Redis```, ```Azure CosmosDB```, ```AWS DynamoDB```, ```GCP Cloud Spanner```, ```Cassandra``` to name a few. + +An Dapr State Store has the following structure: + +``` +apiVersion: dapr.io/v1alpha1 +kind: Component +metadata: + name: +spec: + type: state. + metadata: + - name: + value: + - name: + value: +``` + +The ```metadata.name``` is the name of the state store. + +the ```spec/metadata``` section is an open key value pair metadata that allows a binding to define connection properties. + +## Key scheme +Dapr state stores are key/value stores. To ensure data compatibility, Dapr requires these data stores follow a fixed key scheme. For general states, the key format is: +```bash +- +``` +For Actor states, the key format is: +```bash +--- +``` + + +## Save state + +This endpoint lets you save an array of state objects. + +### HTTP Request + +`POST http://localhost:3500/v1.0/state` + +#### Request Body +A JSON array of state objects. Each state object is comprised with the following fields: + +Field | Description +---- | ----------- +key | state key +value | state value, which can be any byte array +etag | (optional) state ETag +metadata | (optional) additional key-value pairs to be passed to the state store +options | (optional) state operation options, see [state operation options](#state-operation-options) + +> **ETag format** Dapr runtime treats ETags as opaque strings. The exact ETag format is defined by the corresponding data store. + +### HTTP Response +#### Response Codes + +Code | Description +---- | ----------- +201 | State saved +400 | State store is missing or misconfigured +500 | Failed to save state + +#### Response Body +None. + +### Example +```shell +curl -X POST http://localhost:3500/v1.0/state \ + -H "Content-Type: application/json" + -d '[ + { + "key": "weapon", + "value": "DeathStar" + }, + { + "key": "planet", + "value": { + "name": "Tatooine" + } + } + ]' +``` + +## Get state + +This endpoint lets you get the state for a specific key. + +### HTTP Request + +`GET http://localhost:3500/v1.0/state/` + +#### URL Parameters + +Parameter | Description +--------- | ----------- +key | the key of the desired state +consistency | (optional) read consistency mode, see [state operation options](#state-operation-options) + +### HTTP Response + +#### Response Codes + +Code | Description +---- | ----------- +200 | Get state successful +204 | Key is not found +400 | State store is missing or misconfigured +500 | Get state failed + +#### Response Headers + +Header | Description +--------- | ----------- +ETag | ETag of returned value + +#### Response Body +JSON-encoded value + +### Example + +```shell +curl http://localhost:3500/v1.0/state/planet \ + -H "Content-Type: application/json" +``` + +> The above command returns the state: + +```json +{ + "name": "Tatooine" +} +``` +## Delete state + +This endpoint lets you delete the state for a specific key. + +### HTTP Request + +`DELETE http://localhost:3500/v1.0/state/` + +#### URL Parameters + +Parameter | Description +--------- | ----------- +key | the key of the desired state +concurrency | (optional) either *first-write* or *last-write*, see [state operation options](#state-operation-options) +consistency | (optional) either *strong* or *eventual*, see [state operation options](#state-operation-options) +retryInterval | (optional) retry interval, in milliseconds, see [retry policy](#retry-policy) +retryPattern | (optional) retyr pattern, can be either *linear* or *exponential*, see [retry policy](#retry-policy) +retryThreshold | (optinal) number of retries, see [retry policy](#retry-policy) + +#### Request Headers + +Header | Description +--------- | ----------- +If-Match | (Optional) ETag associated with the key to be deleted + +### HTTP Response + +#### Response Codes + +Code | Description +---- | ----------- +200 | Delete state successful +400 | State store is missing or misconfigured +500 | Delete state failed + +#### Response Body +None. + +### Example + +```shell +curl -X "DELETE" http://localhost:3500/v1.0/state/planet -H "ETag: xxxxxxx" +``` + +## Expected state store behaviors + +### Key scheme + +A Dapr-compatible state store shall use the following key scheme: + +* *\-\* key format for general states +* *\-\-\-\* key format for Actor states. + +### Concurrency +Dapr uses Optimized Concurrency Control (OCC) with ETags. Dapr imposes the following requirements on state stores: +* An Dapr-compatible state store shall support optimistic concurrency control using ETags. When an ETag is associated with an *save* or *delete* request, the store shall allow the update only if the attached ETag matches with the latest ETag in the database. +* When ETag is mssing in the write requests, the state store shall handle the reuqests in a last-write-wins fashion. This is to allow optimizations for high-throughput write scenarios in which data contingency is low or has no negative effects. +* A store shall **always** return ETags when returning states to callers. + +### Consistency +Dapr allows clients to attach a consistency hint to *get*, *set* and *delete* operation. Dapr support two consistency level: **strong** and **eventual**, which are defined as the follows: + +#### Eventual Consistency + +Dapr assumes data stores are eventually consistent by default. A state should: + +* For read requests, the state store can return data from any of the replicas +* For write request, the state store should asynchronously replicate updates to configured quorum after acknowledging the update request. + +#### Strong Consistency + +When a strong consistency hint is attached, a state store should: + +* For read requests, the state store should return the most up-to-date data consistently acorss replicas. +* For write/delete requests, the state store should synchronisely replicate updated data to configured quorum before completing the write request. + +### Retry Policy +Dapr allows clients to attach retry policies to *set* and *delete* operations. A retry policy is described by three fields: + +Field | Description +---- | ----------- +retryInterval | Initial delay between retries, in milliseconds. The interval remains constant for *linear* retry pattern. The interval is doubled after each retry for *exponential* retry pattern. So, for *exponential* pattern, the delay after attempt *n* will be interval*2^(n-1). +retryPattern | Retry pattern, can be either *linear* or *exponential*. +retryThreshold | Maximum number of retries. + +### Example +The following is a sample *set* request with a complete operation option definition: + +```shell +curl -X POST http://localhost:3500/v1.0/state \ + -H "Content-Type: application/json" + -d '[ + { + "key": "weapon", + "value": "DeathStar", + "etag": "xxxxx", + "options": { + "concurrency": "first-write", + "consistency": "strong", + "retryPolicy": { + "interval": 100, + "threshold" : 3, + "pattern": "exponential" + } + } + } + ]' +``` diff --git a/reference/readme.md b/reference/readme.md deleted file mode 100644 index f14d27cab..000000000 --- a/reference/readme.md +++ /dev/null @@ -1,7 +0,0 @@ -# Reference documentation - - - - **[Dapr CLI documentation](https://github.com/dapr/cli)** - - - - **[Dapr Specification](https://github.com/dapr/spec)** \ No newline at end of file