Web API Implementation Practice in Micro-Service Architecture
In the system I work on these days, one service needs to call another service to get data and it is done through web API. If the service is used by multiple services, client portion for the service is repeated on every consumers.
This became a problem.
- Duplication of API client codes on all consumers
- The contract between service and client is URL signature: very loose
- Hard to make mock: to test consumer code, you need to make mock service using actual web server
To solve all these problems, the following practice is suggested.
Step 1. The module that provides service will also provide client interface and DTO of the client code in DLL, namely [ModuleName].Client.Core.DLL. Consuming modules’ Core may reference the Client.Core.DLL.
Step 2. The servicing module also provides client code itself in a separate .NET DLL, namely [ModuleName].Client.DLL.
Step 3. Client.Core.DLL will also contain mock class, mock base class, or mock helper class as needed.
Step 4. The servicing module’s client artifact (MyService.Client.Core.dll and MyService.Client.dll) is distributed to all the consuming services. We use in-house version of NuGet-like service for automatic deployment. You can do this in any ways you want but make sure it is auto-deployed.
Step 5. The consuming service uses the DLLs from servicing module as-is. All you do is to inject baseAddress.
The benefits of this approach are:
- No duplicate api client codes on all consumers.
- Strong-typed implementation of client code.
- Mock class base is provided by the service module, conforming to the api client interface.
- Contract is enforced by the service and respected by client apps (will raise compiler/build error if broken)