Trong bài viết trước, mình đã hướng dẫn các bạn cách cài đặt Dapr. Để hình dung cách hoạt động của Dapr như thế nào, chúng ta hãy cùng nhau làm một ví dụ về Service Invocation với Dapr các bạn nhé!
Dapr hoạt động đóng vai trò là một sidecar cùng với ứng dụng, nên cho ví dụ của bài viết này, mình sẽ có 2 service cùng với dapr như sau:
Service 2 sẽ expose một RESTful API với endpoint “/hello”. Service 1 sẽ call tới endpoint “/hello” này, nhưng thay vì call trực tiếp thì nó sẽ call thông qua dapr đó các bạn!
Nội dung của HelloController trong Service 2 như sau các bạn nhé:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
package com.huongdanjava.dapr.serviceinvocation2; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; @Controller public class HelloController { @GetMapping("/hello") public String hello() { return "Hello from Huong Dan Java!"; } } |
Service 2 này sẽ chạy trên port 8081 bằng cách cấu hình property server.port như sau:
1 |
server.port=8081 |
Bây giờ mình sẽ viết code để Service 1 gọi tới Service 2 thông qua Dapr như sau:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
package com.huongdanjava.dapr.serviceinvocation1; import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; import java.time.Duration; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class DaprServiceInvocation1Application implements CommandLineRunner { @Override public void run(String... args) throws Exception { try (HttpClient httpClient = HttpClient.newBuilder() .version(HttpClient.Version.HTTP_2) .connectTimeout(Duration.ofSeconds(10)) .build()) { String daprUrl = "http://localhost:3500/hello"; HttpRequest request = HttpRequest.newBuilder() .GET() .uri(URI.create(daprUrl)) .header("Content-Type", "application/json") .header("dapr-app-id", "service2") .build(); HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); System.out.println("Response: " + response.body()); } } public static void main(String[] args) { SpringApplication.run(DaprServiceInvocation1Application.class, args); } } |
Dapr của mình sẽ chạy ở port 3500 nên như các bạn thấy, mình đang sử dụng thư viện HttpClient của Java để gọi đến endpoint “http://localhost:3500/hello”.
Một điểm mà các bạn cần lưu ý là chúng ta phải chỉ định app id của ứng dụng mà chúng ta cần gọi tới trong Dapr bằng cách truyền thông tin header “dapr-app-id”, như mình làm ở trên, khi gọi tới Dapr. Trong ví dụ của mình thì app id mà mình muốn gọi tới là “service2”, khi đó Dapr sẽ giúp Service 1 gọi đến Service 2 mà không cần biết thông tin của Service 2 như thế nào!
Bây giờ, để chạy các service này với Dapr, các bạn hãy chạy Maven command
1 |
mvn clean package -DskipTests |
để build 2 ứng dụng của chúng ta trước.
Sau đó, các bạn hãy sử dụng Dapr CLI để chạy ứng dụng của chúng ta với Dapr.
Chúng ta sẽ chạy Service 2 với Dapr trước, như sau:
1 |
dapr run --app-id service2 --app-port 8081 --app-protocol http --dapr-http-port 3501 -- java -jar target/dapr-service-invocation-2-0.0.1-SNAPSHOT.jar |
Khi chạy ứng dụng với Dapr, chúng ta sẽ định nghĩa Id cho từng service sử dụng tham số –app-id như các bạn thấy ở command trên. Chúng ta sẽ phải định nghĩa port và protocol mà chúng ta sử dụng để chạy ứng dụng. Trong ví dụ của mình thì Service 2 sẽ chạy ở port 8081 và protocol là HTTP nên như các bạn thấy, cho 2 tham số –app-port và –app-protocol mình đã khai báo các giá trị này.
Nếu các bạn chạy nhiều instance cho Service 2 thì giá trị của tham số –app-id sẽ không đổi các bạn nhé!
Trong command của mình ở trên, tham số –dapr-http-port sẽ định nghĩa port mà Dapr sẽ sử dụng để nhận request từ bên ngoài.
Các bạn hãy chạy command này trong thư mục project của Service 2 các bạn nhé!
Kết quả của mình như sau:
Cho Service 1, tương tự như Service 2, chúng ta cũng sẽ sử dụng Dapr để chạy với Service 1. Trong thư mục project của Service 1, các bạn hãy chạy command như sau các bạn nhé:
1 |
dapr run --app-id service1 --dapr-http-port 3500 -- java -jar target/dapr-service-invocation-1-0.0.1-SNAPSHOT.jar |
Các bạn sẽ thấy kết quả như sau:
Như các bạn thấy, Service 1 của mình có thể gọi đến Service 2 thông qua Dapr và nhận về response là “Hello from Huong Dan Java” đó các bạn!
Behind the sense thì Dapr sử dụng API “invoke” đó các bạn.
API invoke này sẽ cho phép các ứng dụng có thể gọi với nhau thông qua app id. Ngoài cách truyền thông tin app id trên header của request ở ví dụ trên, các bạn còn có thể gọi tới Service 2 sử dụng cú pháp:
1 |
http://<dapr_host>:<dapr_port>/v1.0/invoke/<app_id>/method/<method_name>/<parameter> |
Ví dụ của mình như sau:
1 |
http://localhost:3501/v1.0/invoke/service2/method/hello |
Kết quả:
Một cách khác, các bạn cũng có thể truyền thông tin app id trong phần Basic Authentication của request, ví dụ của mình như sau:
Hoặc sử dụng Dapr CLI cũng được: