Help implementing call to external API and store summary in my database in hexagonal architecture with DDD

0

Good afternoon.

My situation is this:
I have to call an external API to create some data and store it there, but I want to have a summary of that data in my own database. I have my use case that creates the AggregateRoot and my port interface that the implementation calls the external API. Where should I put the database store code? I have thought these options:

  1. Encapsulate the database repository port in the external API adapter implementation and call
  2. Call the database port in my use case so after the external API call succeed, I can call that port and store the information.
  3. In the external API adapter, when the external call is succeed, send a event with the information created and create another use case to store the information in my database.

Number 1 and 3 seems quite strange to me because I will be manipulating domain objects in the infrastructure layer.
I think number 2 is the way to go, but I am not sure.
Thank you!

2

Encapsulating data replication in the API adapter would be nice, because your use case does not need to remember to do this. Error handling and order of operations (call API first, then insert into DB) get pushed into the abstraction provided by the adapter. Replicating this data is easy and hidden from the perspective of the caller, but this might be a little surprising. Sometimes “hidden” operations are not desirable for the simple fact they are hidden.

Replicating this data explicitly in the use case is nice, because that logic is right in front of your face. It becomes very easy to understand that we duplicate some data, but it becomes possible for a careless programmer to flip the order of operations in the future. Without understanding the system properly, someone could save data to the database first, and then call the API, only to have the API call fail. Now you have data in your database, but not in the external API.

I would lean towards choosing the solution that guards against accidental bugs in the future caused by changing the order methods are called. These can be excruciating to debug in production, because the failure isn’t obvious. Based on this, I would go for solution #2, because it solves “order of operations” issues. You do have a couple of options that might make the code easier to understand:

  1. Use one class that makes explicit calls to the API and then database.

    The benefit of this approach is seeing both calls right in front of your face.

    The drawback is you are coupling both operations together in the same class.

  2. Create two classes that implement the same interface, making the database class a proxy for the API class:

    Plain text
    Copy to clipboard
    Open code in new window
    EnlighterJS 3 Syntax Highlighter
    <code>IExternalApi api = new DatabaseExternalApiProxy(new ExternalApi(), repository);
    api.SomeOperation(data);
    </code>
    <code>IExternalApi api = new DatabaseExternalApiProxy(new ExternalApi(), repository); api.SomeOperation(data); </code>
    IExternalApi api = new DatabaseExternalApiProxy(new ExternalApi(), repository);
    
    api.SomeOperation(data);
    

    The proxy class can juggle the order of operations, and you get loose coupling to the external API:

    Plain text
    Copy to clipboard
    Open code in new window
    EnlighterJS 3 Syntax Highlighter
    <code>public class DatabaseExternalApiProxy : IExternalApi
    {
    private IExternalApi api;
    private ISomeRepository repository;
    public DatabaseExternalApiProxy(IExternalApi api, ISomeRepository repository)
    {
    this.api = api;
    this.repository = repository;
    }
    public void SomeOperation(data)
    {
    api.SomeOperation(data);
    repository.ReplicateData(data);
    }
    }
    </code>
    <code>public class DatabaseExternalApiProxy : IExternalApi { private IExternalApi api; private ISomeRepository repository; public DatabaseExternalApiProxy(IExternalApi api, ISomeRepository repository) { this.api = api; this.repository = repository; } public void SomeOperation(data) { api.SomeOperation(data); repository.ReplicateData(data); } } </code>
    public class DatabaseExternalApiProxy : IExternalApi
    {
        private IExternalApi api;
        private ISomeRepository repository;
    
        public DatabaseExternalApiProxy(IExternalApi api, ISomeRepository repository)
        {
            this.api = api;
            this.repository = repository;
        }
    
        public void SomeOperation(data)
        {
            api.SomeOperation(data);
            repository.ReplicateData(data);
        }
    }
    

4

0

If I understood your use case right I see some advantages in option 1.

In my understanding you want to mirror the API’s data as a sort of cache. (If this is not the case you can stop reading here and go with @greg-burghardt)

In this is the case I would indeed save this replication in your repository implementation – before your use case even is in contact with the data (option 1).
The question here is what kind of requirement is the replication of the API’s data? A) Is it a infrastructural (speed, availability,…) requirement or B) is it one of your domain? As of your description I guess it is more of an infrastructural requirement.

From an implementation pov I see these options:

  • Option 1A: Hide the cache completely from your use case and implement it in the repository
  • Option 1B: if your use case has knowledge about the consistency of this data then define the repository port accordingly. prepare different methods for the different situations your use case has to handle. this could be getDataConsistent() and getDataCached() and use the right one for the right situation.

All in all I think this is highly dependent on your domain requirements. I could completely confirm with gregs answer here but wanted to share a second point of view on that. Maybe it helps.

1

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật