mirror of https://github.com/dapr/docs.git
Merge pull request #1965 from amulyavarote/feature/service_invocation
Provide consistent examples of service invocation for all SDKs
This commit is contained in:
commit
59fc6f8068
|
@ -8,29 +8,136 @@ weight: 2000
|
|||
|
||||
This article describe how to deploy services each with an unique application ID, so that other services can discover and call endpoints on them using service invocation API.
|
||||
|
||||
## Example:
|
||||
|
||||
The below code examples loosely describe an application that processes orders. In the examples, there are two services - an order processing service and a checkout service. Both services have Dapr sidecars and the order processing service uses Dapr to invoke the checkout method in the checkout service.
|
||||
|
||||
<img src="/images/service_invocation_eg.png" width=1000 height=500 alt="Diagram showing service invocation of example service">
|
||||
|
||||
## Step 1: Choose an ID for your service
|
||||
|
||||
Dapr allows you to assign a global, unique ID for your app. This ID encapsulates the state for your application, regardless of the number of instances it may have.
|
||||
|
||||
{{< tabs "Self-Hosted (CLI)" Kubernetes >}}
|
||||
|
||||
{{< tabs Dotnet Java Python Go Javascript Kubernetes>}}
|
||||
|
||||
|
||||
{{% codetab %}}
|
||||
In self hosted mode, set the `--app-id` flag:
|
||||
|
||||
```bash
|
||||
dapr run --app-id cart --dapr-http-port 3500 --app-port 5000 python app.py
|
||||
|
||||
dapr run --app-id checkout --app-port 6002 --dapr-http-port 3602 --dapr-grpc-port 60002 dotnet run
|
||||
|
||||
dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-grpc-port 60001 dotnet run
|
||||
|
||||
```
|
||||
|
||||
If your app uses an SSL connection, you can tell Dapr to invoke your app over an insecure SSL connection:
|
||||
|
||||
```bash
|
||||
dapr run --app-id cart --dapr-http-port 3500 --app-port 5000 --app-ssl python app.py
|
||||
|
||||
dapr run --app-id checkout --app-port 6002 --dapr-http-port 3602 --dapr-grpc-port 60002 --app-ssl dotnet run
|
||||
|
||||
dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-grpc-port 60001 --app-ssl dotnet run
|
||||
|
||||
```
|
||||
|
||||
{{% /codetab %}}
|
||||
|
||||
{{% codetab %}}
|
||||
|
||||
### Setup an ID using Kubernetes
|
||||
```bash
|
||||
|
||||
dapr run --app-id checkout --app-port 6002 --dapr-http-port 3602 --dapr-grpc-port 60002 mvn spring-boot:run
|
||||
|
||||
dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-grpc-port 60001 mvn spring-boot:run
|
||||
|
||||
```
|
||||
|
||||
If your app uses an SSL connection, you can tell Dapr to invoke your app over an insecure SSL connection:
|
||||
|
||||
```bash
|
||||
|
||||
dapr run --app-id checkout --app-port 6002 --dapr-http-port 3602 --dapr-grpc-port 60002 --app-ssl mvn spring-boot:run
|
||||
|
||||
dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-grpc-port 60001 --app-ssl mvn spring-boot:run
|
||||
|
||||
```
|
||||
|
||||
{{% /codetab %}}
|
||||
|
||||
{{% codetab %}}
|
||||
|
||||
```bash
|
||||
|
||||
dapr run --app-id checkout --app-port 6002 --dapr-http-port 3602 --dapr-grpc-port 60002 -- python3 CheckoutService.py
|
||||
|
||||
dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-grpc-port 60001 -- python3 OrderProcessingService.py
|
||||
|
||||
```
|
||||
|
||||
If your app uses an SSL connection, you can tell Dapr to invoke your app over an insecure SSL connection:
|
||||
|
||||
```bash
|
||||
|
||||
dapr run --app-id checkout --app-port 6002 --dapr-http-port 3602 --dapr-grpc-port 60002 --app-ssl -- python3 CheckoutService.py
|
||||
|
||||
dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-grpc-port 60001 --app-ssl -- python3 OrderProcessingService.py
|
||||
|
||||
```
|
||||
|
||||
{{% /codetab %}}
|
||||
|
||||
|
||||
{{% codetab %}}
|
||||
|
||||
```bash
|
||||
|
||||
dapr run --app-id checkout --app-port 6002 --dapr-http-port 3602 --dapr-grpc-port 60002 go run CheckoutService.go
|
||||
|
||||
dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-grpc-port 60001 go run OrderProcessingService.go
|
||||
|
||||
```
|
||||
|
||||
If your app uses an SSL connection, you can tell Dapr to invoke your app over an insecure SSL connection:
|
||||
|
||||
```bash
|
||||
|
||||
dapr run --app-id checkout --app-port 6002 --dapr-http-port 3602 --dapr-grpc-port 60002 --app-ssl go run CheckoutService.go
|
||||
|
||||
dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-grpc-port 60001 --app-ssl go run OrderProcessingService.go
|
||||
|
||||
```
|
||||
|
||||
{{% /codetab %}}
|
||||
|
||||
|
||||
{{% codetab %}}
|
||||
|
||||
```bash
|
||||
|
||||
dapr run --app-id checkout --app-port 6002 --dapr-http-port 3602 --dapr-grpc-port 60002 npm start
|
||||
|
||||
dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-grpc-port 60001 npm start
|
||||
|
||||
```
|
||||
|
||||
If your app uses an SSL connection, you can tell Dapr to invoke your app over an insecure SSL connection:
|
||||
|
||||
```bash
|
||||
|
||||
dapr run --app-id checkout --app-port 6002 --dapr-http-port 3602 --dapr-grpc-port 60002 --app-ssl npm start
|
||||
|
||||
dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-grpc-port 60001 --app-ssl npm start
|
||||
|
||||
```
|
||||
|
||||
{{% /codetab %}}
|
||||
|
||||
|
||||
{{% codetab %}}
|
||||
|
||||
### Set an app-id when deploying to Kubernetes
|
||||
|
||||
In Kubernetes, set the `dapr.io/app-id` annotation on your pod:
|
||||
|
||||
|
@ -38,23 +145,23 @@ In Kubernetes, set the `dapr.io/app-id` annotation on your pod:
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: python-app
|
||||
name: <language>-app
|
||||
namespace: default
|
||||
labels:
|
||||
app: python-app
|
||||
app: <language>-app
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: python-app
|
||||
app: <language>-app
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: python-app
|
||||
app: <language>-app
|
||||
annotations:
|
||||
dapr.io/enabled: "true"
|
||||
dapr.io/app-id: "cart"
|
||||
dapr.io/app-port: "5000"
|
||||
dapr.io/app-id: "orderprocessingservice"
|
||||
dapr.io/app-port: "6001"
|
||||
...
|
||||
```
|
||||
*If your app uses an SSL connection, you can tell Dapr to invoke your app over an insecure SSL connection with the `app-ssl: "true"` annotation (full list [here]({{< ref arguments-annotations-overview.md >}}))*
|
||||
|
@ -63,103 +170,169 @@ spec:
|
|||
|
||||
{{< /tabs >}}
|
||||
|
||||
## Step 2: Invoke the service
|
||||
|
||||
## Step 2: Setup a service
|
||||
To invoke an application using Dapr, you can use the `invoke` API on any Dapr instance.
|
||||
|
||||
The following is a Python example of a cart app. It can be written in any programming language.
|
||||
The sidecar programming model encourages each application to interact with its own instance of Dapr. The Dapr sidecars discover and communicate with one another.
|
||||
|
||||
```python
|
||||
from flask import Flask
|
||||
app = Flask(__name__)
|
||||
Below are code examples that leverage Dapr SDKs for service invocation.
|
||||
|
||||
@app.route('/add', methods=['POST'])
|
||||
def add():
|
||||
return "Added!"
|
||||
{{< tabs Dotnet Java Python Go Javascript>}}
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run()
|
||||
```
|
||||
|
||||
This Python app exposes an `add()` method via the `/add` endpoint.
|
||||
|
||||
## Step 3: Invoke the service
|
||||
|
||||
Dapr uses a sidecar, decentralized architecture. To invoke an application using Dapr, you can use the `invoke` API on any Dapr instance.
|
||||
|
||||
The sidecar programming model encourages each applications to talk to its own instance of Dapr. The Dapr instances discover and communicate with one another.
|
||||
|
||||
{{< tabs curl CLI >}}
|
||||
|
||||
{{% codetab %}}
|
||||
From a terminal or command prompt run:
|
||||
```bash
|
||||
curl http://localhost:3500/v1.0/invoke/cart/method/add -X POST
|
||||
```csharp
|
||||
|
||||
//headers
|
||||
|
||||
using Dapr.Client;
|
||||
using System.Net.Http;
|
||||
|
||||
//code
|
||||
|
||||
CancellationTokenSource source = new CancellationTokenSource();
|
||||
CancellationToken cancellationToken = source.Token;
|
||||
using var client = new DaprClientBuilder().Build();
|
||||
var result = client.CreateInvokeMethodRequest(HttpMethod.Get, "checkout", "checkout/" + orderId, cancellationToken);
|
||||
await client.InvokeMethodAsync(result);
|
||||
|
||||
```
|
||||
{{% /codetab %}}
|
||||
|
||||
Since the add endpoint is a 'POST' method, we used `-X POST` in the curl command.
|
||||
|
||||
To invoke a 'GET' endpoint:
|
||||
{{% codetab %}}
|
||||
```java
|
||||
|
||||
//headers
|
||||
|
||||
import io.dapr.client.DaprClient;
|
||||
import io.dapr.client.DaprClientBuilder;
|
||||
import io.dapr.client.domain.HttpExtension;
|
||||
|
||||
//code
|
||||
|
||||
DaprClient daprClient = new DaprClientBuilder().build();
|
||||
var result = daprClient.invokeMethod(
|
||||
"checkout",
|
||||
"checkout/" + orderId,
|
||||
null,
|
||||
HttpExtension.GET,
|
||||
String.class
|
||||
);
|
||||
|
||||
```bash
|
||||
curl http://localhost:3500/v1.0/invoke/cart/method/add
|
||||
```
|
||||
|
||||
To invoke a 'DELETE' endpoint:
|
||||
|
||||
```bash
|
||||
curl http://localhost:3500/v1.0/invoke/cart/method/add -X DELETE
|
||||
```
|
||||
|
||||
Dapr puts any payload returned by the called service in the HTTP response's body.
|
||||
|
||||
### Additional URL formats
|
||||
|
||||
In order to avoid changing URL paths as much as possible, Dapr provides the following ways to call the service invocation API:
|
||||
|
||||
|
||||
1. Change the address in the URL to `localhost:<dapr-http-port>`.
|
||||
2. Add a `dapr-app-id` header to specify the ID of the target service, or alternatively pass the ID via HTTP Basic Auth: `http://dapr-app-id:<service-id>@localhost:3500/path`.
|
||||
|
||||
For example, the following command
|
||||
```bash
|
||||
curl http://localhost:3500/v1.0/invoke/cart/method/add
|
||||
```
|
||||
|
||||
is equivalent to:
|
||||
|
||||
```bash
|
||||
curl -H 'dapr-app-id: cart' 'http://localhost:3500/add' -X POST
|
||||
```
|
||||
|
||||
or:
|
||||
|
||||
```bash
|
||||
curl 'http://dapr-app-id:cart@localhost:3500/add' -X POST
|
||||
```
|
||||
|
||||
{{% /codetab %}}
|
||||
|
||||
{{% codetab %}}
|
||||
```bash
|
||||
dapr invoke --app-id cart --method add
|
||||
```python
|
||||
|
||||
//headers
|
||||
|
||||
from dapr.clients import DaprClient
|
||||
|
||||
//code
|
||||
|
||||
with DaprClient() as daprClient:
|
||||
result = daprClient.invoke_method(
|
||||
"checkout",
|
||||
f"checkout/{orderId}",
|
||||
data=b'',
|
||||
http_verb="GET"
|
||||
)
|
||||
|
||||
```
|
||||
{{% /codetab %}}
|
||||
|
||||
{{% codetab %}}
|
||||
```go
|
||||
|
||||
//headers
|
||||
import (
|
||||
dapr "github.com/dapr/go-sdk/client"
|
||||
)
|
||||
|
||||
//code
|
||||
|
||||
client, err := dapr.NewClient()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer client.Close()
|
||||
ctx := context.Background()
|
||||
|
||||
result, err := client.InvokeMethod(ctx, "checkout", "checkout/" + strconv.Itoa(orderId), "get")
|
||||
|
||||
```
|
||||
{{% /codetab %}}
|
||||
|
||||
{{% codetab %}}
|
||||
```javascript
|
||||
|
||||
//headers
|
||||
|
||||
import { DaprClient, HttpMethod, CommunicationProtocolEnum } from 'dapr-client';
|
||||
|
||||
//code
|
||||
|
||||
const daprHost = "127.0.0.1";
|
||||
const client = new DaprClient(daprHost, process.env.DAPR_HTTP_PORT, CommunicationProtocolEnum.HTTP);
|
||||
const result = await client.invoker.invoke('checkout' , "checkout/" + orderId , HttpMethod.GET);
|
||||
|
||||
```
|
||||
{{% /codetab %}}
|
||||
|
||||
{{< /tabs >}}
|
||||
|
||||
### Namespaces
|
||||
### Additional URL formats
|
||||
|
||||
When running on [namespace supported platforms]({{< ref "service_invocation_api.md#namespace-supported-platforms" >}}), you include the namespace of the target app in the app ID: `myApp.production`
|
||||
To invoke a 'GET' endpoint:
|
||||
```bash
|
||||
curl http://localhost:3602/v1.0/invoke/checkout/method/checkout/100
|
||||
```
|
||||
|
||||
For example, invoking the example python service with a namespace would be:
|
||||
In order to avoid changing URL paths as much as possible, Dapr provides the following ways to call the service invocation API:
|
||||
|
||||
|
||||
1. Change the address in the URL to `localhost:<dapr-http-port>`.
|
||||
2. Add a `dapr-app-id` header to specify the ID of the target service, or alternatively pass the ID via HTTP Basic Auth: `http://dapr-app-id:<service-id>@localhost:3602/path`.
|
||||
|
||||
For example, the following command
|
||||
```bash
|
||||
curl http://localhost:3602/v1.0/invoke/checkout/method/checkout/100
|
||||
```
|
||||
|
||||
is equivalent to:
|
||||
|
||||
```bash
|
||||
curl http://localhost:3500/v1.0/invoke/cart.production/method/add -X POST
|
||||
curl -H 'dapr-app-id: checkout' 'http://localhost:3602/checkout/100' -X POST
|
||||
```
|
||||
|
||||
or:
|
||||
|
||||
```bash
|
||||
curl 'http://dapr-app-id:checkout@localhost:3602/checkout/100' -X POST
|
||||
```
|
||||
|
||||
Using CLI:
|
||||
|
||||
```bash
|
||||
dapr invoke --app-id checkout --method checkout/100
|
||||
```
|
||||
|
||||
### Namespaces
|
||||
|
||||
When running on [namespace supported platforms]({{< ref "service_invocation_api.md#namespace-supported-platforms" >}}), you include the namespace of the target app in the app ID: `checkout.production`
|
||||
|
||||
For example, invoking the example service with a namespace would be:
|
||||
|
||||
```bash
|
||||
curl http://localhost:3602/v1.0/invoke/checkout.production/method/checkout/100 -X POST
|
||||
```
|
||||
|
||||
See the [Cross namespace API spec]({{< ref "service_invocation_api.md#cross-namespace-invocation" >}}) for more information on namespaces.
|
||||
|
||||
## Step 4: View traces and logs
|
||||
## Step 3: View traces and logs
|
||||
|
||||
The example above showed you how to directly invoke a different service running locally or in Kubernetes. Dapr outputs metrics, tracing and logging information allowing you to visualize a call graph between services, log errors and optionally log the payload body.
|
||||
|
||||
|
@ -168,4 +341,4 @@ For more information on tracing and logs see the [observability]({{< ref observa
|
|||
## Related Links
|
||||
|
||||
* [Service invocation overview]({{< ref service-invocation-overview.md >}})
|
||||
* [Service invocation API specification]({{< ref service_invocation_api.md >}})
|
||||
* [Service invocation API specification]({{< ref service_invocation_api.md >}})
|
Binary file not shown.
After Width: | Height: | Size: 181 KiB |
Loading…
Reference in New Issue