Motivation
You may be worked on projects that deal with third party APIs (APIs related to another service provider) or some libraries generated by another companies or you building new system but it deals with a legacy system, when you use or deal with these APIs you have to deal them with special handling in order to keep your code clean and maintainable.
The main problem is different languages
Mostly these APIs you deal with outside your system are built with different language from that in your system, By different language I don't mean programming language I mean Domain language, Different objects and properties from that used in your system.
If you start directly use this language (Objects and Properties) in the middle of your Domain business logic, you will find that you are make explicit conversion between your system objects and third party objects, also may handle exceptions that may occur from library or handle failure of HTTP requests in the middle of your business logic, and maybe your functionality is very small or trivial but because it uses a third party API it became more complex to read and maintain.
Meet Anti-Corruption Layer
Anti-corruption layer is one of DDD (Domain Driven Design) principles, name came from that preventing corruption of your business logic that may happen because of integration code, which tells you that if you will deal with any third party API you have to isolate integration code in different layer and any service in your system needs to use this API it should use it from Contract/Interface.
Let's take an example, If you have a Social Insurance System and want to integrate with a third party that provides Citizen information based on national id, so your system have Insurer class that belongs to your system domain like this
`Class Insurer {
private String firstName;
private String lastName;
private String nationalId;
private Integer age;
// getters and setters
}`
And third party response will be like this
`Class Citizen {
private String fullName;
private String id;
private Date dateOfBirth;
// getters and setters
}`
it's Obvious that 2 different classes and need conversion, so how our anti-corruption layer will be look like?
First we will build the contract/interface as this
`public interface CitizenSystemIntegration {
public Insurer getInsurer(String nationalId);
}`
and our contract implementation service will be like
`class CitizenSystemIntegrationImpl implements CitizenSystemIntegration {
@Override
public Insurer getInsurer(String nationalId) {
// build request object
// call third party api
// convert response to Insurer object
// return
}
}`
Now whenever you need this facility you can create object from this implementation and use it, listing below benefits of this strategy
- Isolating the integration code.
- Reducing code duplication , as we have one place to edit and maintain.
- You can build your exception handling logic in one place.
- Your main system functionality is clear, there is no different object you need to handle, no specific exceptions you have to deal with and your domain service is clear.
- You can add logging functionality
At the end , Anti-corruption layer is built based on same concept of Adapter Design Pattern
Resources
IF YOU LIKED THE POST, THEN YOU CAN SUPPPORT SUCH CONTENT WITH A CUP OF COFFEE, THANKS IN ADVANCE.