< Previous Challenge - Home - Next Challenge >
In this challenge, you're going to add Dapr into the mix, using the Dapr service invocation building block.
While asynchronous communication across microservices is favored, some operations require an immediate response. For such use cases, one microservice effectively queries another for a response that is needed to complete the operation. Such scenarios often implement synchronous calls between services.
Operationally, it's important to not hardcode endpoints when implementing synchronous service calls. This practice becomes especially important in orchestrated environments, such as Kubernetes, where services are continually moved across cluster nodes and replaced with newer versions. The Dapr service invocation building block addresses service-to-service communication. Here is how it works:
In Dapr, every service is started with a unique Id (the app-id) which can be used to find it. What happens if Service A needs to call Service B?
- Service A invokes the Dapr service invocation API (using HTTP or gRPC) on its Dapr sidecar and specifies the unique app-id of Service B.
- Dapr discovers Service B's current location by using the name-resolution component configured for the hosting environment in which the solution is running.
- Service A's Dapr sidecar forwards the message to Service B's Dapr sidecar.
- Service B's Dapr sidecar forwards the request to Service B. Service B executes the corresponding business logic.
- Service B returns the response for Service A to its Dapr sidecar.
- Service B's Dapr sidecar forwards the response to Service A's Dapr sidecar.
- Service A's Dapr sidecar forwards the response to Service A.
The service invocation building block offers many other features, such as security and load-balancing. Check out the Dapr documentation later to learn more.
Service Invocation is also covered in detail in the Dapr for .NET Developers guidance eBook.
For this hands-on challenge, you will decouple communication between two services.
- Start up a Dapr sidecar for both the
VehicleRegistrationService
and theFineCollectionService
. - Modify the
FineCollectionService
(VehicleRegistrationService
class) so that it uses the Dapr service invocation building block to call the/vehicleinfo/{licensenumber}
endpoint on theVehicleRegistrationService
. - Restart all services & run the Simulation application.
This challenge targets the operations labeled as number 1 in the end-state setup:
- Validate that the
VehicleRegistrationService
andFineCollectionService
each run with a Dapr sidecar. You'll see both Dapr and application logging in the output. - Validate that the
FineCollectionService
uses the Dapr service invocation building block to call the/vehicleinfo/{licensenumber}
endpoint on theVehicleRegistrationService
. The HTTP call should be to the Dapr port number, not the API port number.
So how can you check whether or not the call to the VehicleRegistrationService
is handled by Dapr? Well, Dapr has some observability built in. You can look at Dapr traffic using Zipkin:
- Open a browser and go the this URL: http://localhost:9411/zipkin.
- Click the
RUN QUERY
button in the top right of the screen to search for traces. - You should see the calls between the
FineCollectionService
and theVehicleRegistrationService
. You can expand and collapse each trace and click theSHOW
button to get more details: - If you click the dependencies button and search, you will see the services and the traffic flowing between them:
- Look in the
Resources.zip
package provided by your coach for the source code to get started. - Use the
dapr run
command to start up a Dapr sidecar & make sure and append thedotnet run
command at the end of the command to ensure that both services are started at the same time. - Refer to the Prevent port collisions section to see what ports to use.