How-To: Invoke services using HTTP

    This article demonstrates how to deploy services each with an unique application ID for other services to discover and call endpoints on them using service invocation over HTTP.

    For a complete sample demonstrating service invocation, walk through the service invocation quickstart.

    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.

    If your app uses an SSL connection, you can tell Dapr to invoke your app over an insecure SSL connection:

    1. dapr run --app-id checkout --app-port 6002 --dapr-http-port 3602 --dapr-grpc-port 60002 --app-ssl dotnet run
    2. dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-grpc-port 60001 --app-ssl dotnet run
    1. dapr run --app-id checkout --app-port 6002 --dapr-http-port 3602 --dapr-grpc-port 60002 mvn spring-boot:run
    2. 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:

    1. dapr run --app-id checkout --app-port 6002 --dapr-http-port 3602 --dapr-grpc-port 60002 --app-ssl mvn spring-boot:run
    2. dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-grpc-port 60001 --app-ssl mvn spring-boot:run
    1. dapr run --app-id checkout --app-port 6002 --dapr-http-port 3602 --dapr-grpc-port 60002 -- python3 CheckoutService.py
    2. 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:

    1. dapr run --app-id checkout --app-port 6002 --dapr-http-port 3602 --dapr-grpc-port 60002 --app-ssl -- python3 CheckoutService.py
    2. dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-grpc-port 60001 --app-ssl -- python3 OrderProcessingService.py
    1. dapr run --app-id checkout --app-port 6002 --dapr-http-port 3602 --dapr-grpc-port 60002 go run CheckoutService.go
    2. dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-grpc-port 60001 go run OrderProcessingService.go
    1. dapr run --app-id checkout --app-port 6002 --dapr-http-port 3602 --dapr-grpc-port 60002 npm start
    2. 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:

    1. dapr run --app-id checkout --app-port 6002 --dapr-http-port 3602 --dapr-grpc-port 60002 --app-ssl npm start
    2. dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-grpc-port 60001 --app-ssl npm start

    In Kubernetes, set the dapr.io/app-id annotation on your pod:

    1. apiVersion: apps/v1
    2. kind: Deployment
    3. metadata:
    4. name: <language>-app
    5. namespace: default
    6. labels:
    7. app: <language>-app
    8. spec:
    9. replicas: 1
    10. selector:
    11. matchLabels:
    12. app: <language>-app
    13. template:
    14. metadata:
    15. labels:
    16. app: <language>-app
    17. annotations:
    18. dapr.io/enabled: "true"
    19. dapr.io/app-id: "orderprocessingservice"
    20. dapr.io/app-port: "6001"
    21. ...

    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 )

    To invoke an application using Dapr, you can use the invoke API on any Dapr instance. The sidecar programming model encourages each application to interact with its own instance of Dapr. The Dapr sidecars discover and communicate with one another.

    Below are code examples that leverage Dapr SDKs for service invocation.

    1. //dependencies
    2. using System;
    3. using System.Collections.Generic;
    4. using System.Net.Http;
    5. using System.Net.Http.Headers;
    6. using Dapr.Client;
    7. using Microsoft.AspNetCore.Mvc;
    8. using System.Threading;
    9. //code
    10. namespace EventService
    11. {
    12. class Program
    13. {
    14. static async Task Main(string[] args)
    15. {
    16. while(true) {
    17. System.Threading.Thread.Sleep(5000);
    18. Random random = new Random();
    19. int orderId = random.Next(1,1000);
    20. CancellationTokenSource source = new CancellationTokenSource();
    21. CancellationToken cancellationToken = source.Token;
    22. using var client = new DaprClientBuilder().Build();
    23. //Using Dapr SDK to invoke a method
    24. var result = client.CreateInvokeMethodRequest(HttpMethod.Get, "checkout", "checkout/" + orderId, cancellationToken);
    25. await client.InvokeMethodAsync(result);
    26. Console.WriteLine("Order requested: " + orderId);
    27. Console.WriteLine("Result: " + result);
    28. }
    29. }
    30. }
    31. }
    1. //dependencies
    2. import io.dapr.client.DaprClient;
    3. import io.dapr.client.DaprClientBuilder;
    4. import io.dapr.client.domain.HttpExtension;
    5. import org.springframework.boot.autoconfigure.SpringBootApplication;
    6. import org.slf4j.Logger;
    7. import org.slf4j.LoggerFactory;
    8. import java.util.Random;
    9. import java.util.concurrent.TimeUnit;
    10. //code
    11. @SpringBootApplication
    12. public class OrderProcessingServiceApplication {
    13. private static final Logger log = LoggerFactory.getLogger(OrderProcessingServiceApplication.class);
    14. public static void main(String[] args) throws InterruptedException{
    15. while(true) {
    16. TimeUnit.MILLISECONDS.sleep(5000);
    17. Random random = new Random();
    18. int orderId = random.nextInt(1000-1) + 1;
    19. DaprClient daprClient = new DaprClientBuilder().build();
    20. //Using Dapr SDK to invoke a method
    21. var result = daprClient.invokeMethod(
    22. "checkout",
    23. "checkout/" + orderId,
    24. null,
    25. HttpExtension.GET,
    26. String.class
    27. );
    28. log.info("Order requested: " + orderId);
    29. }
    30. }
    1. #dependencies
    2. import random
    3. from time import sleep
    4. import logging
    5. from dapr.clients import DaprClient
    6. #code
    7. logging.basicConfig(level = logging.INFO)
    8. while True:
    9. sleep(random.randrange(50, 5000) / 1000)
    10. orderId = random.randint(1, 1000)
    11. with DaprClient() as daprClient:
    12. #Using Dapr SDK to invoke a method
    13. result = daprClient.invoke_method(
    14. "checkout",
    15. f"checkout/{orderId}",
    16. data=b'',
    17. http_verb="GET"
    18. )
    19. logging.basicConfig(level = logging.INFO)
    20. logging.info('Order requested: ' + str(orderId))
    21. logging.info('Result: ' + str(result))
    1. //dependencies
    2. import { DaprClient, HttpMethod, CommunicationProtocolEnum } from 'dapr-client';
    3. //code
    4. const daprHost = "127.0.0.1";
    5. var main = function() {
    6. for(var i=0;i<10;i++) {
    7. sleep(5000);
    8. var orderId = Math.floor(Math.random() * (1000 - 1) + 1);
    9. start(orderId).catch((e) => {
    10. console.error(e);
    11. process.exit(1);
    12. });
    13. }
    14. }
    15. async function start(orderId) {
    16. const client = new DaprClient(daprHost, process.env.DAPR_HTTP_PORT, CommunicationProtocolEnum.HTTP);
    17. //Using Dapr SDK to invoke a method
    18. const result = await client.invoker.invoke('checkoutservice' , "checkout/" + orderId , HttpMethod.GET);
    19. console.log("Order requested: " + orderId);
    20. console.log("Result: " + result);
    21. }
    22. function sleep(ms) {
    23. return new Promise(resolve => setTimeout(resolve, ms));
    24. }
    25. main();

    To invoke a ‘GET’ endpoint:

    1. curl http://localhost:3602/v1.0/invoke/checkout/method/checkout/100

    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.
    1. curl http://localhost:3602/v1.0/invoke/checkout/method/checkout/100

    is equivalent to:

    1. curl -H 'dapr-app-id: checkout' 'http://localhost:3602/checkout/100' -X POST

    or:

    1. curl 'http://dapr-app-id:checkout@localhost:3602/checkout/100' -X POST

    Using CLI:

    When running on 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 look like:

    See the for more information on namespaces.

    Our example above showed you how to directly invoke a different service running locally or in Kubernetes. Dapr:

    • Outputs metrics, tracing, and logging information,
    • Allows you to visualize a call graph between services and log errors, and
    • Optionally, log the payload body.