0

I am currently developing an API which needs to "extend" its own data (my database) with the data I receive from another API. I have an inventory class/aggregate in the domain layer with a repository interface which is implemented in the infrastructure layer.

Now I have injected via Dependency Injection both the Entity Manager for my own database as well as the RestClient for the external API.

public class RestInventoryRepository implements InventoryRepository {

    @RestClient
    @Inject
    InventoryRestClient inventoryRestClient;
    
    @Inject
    EntityManager eM;

In the repository method implementation I first call the rest client and receive its representation of the requested inventory. I then map it to my inventory class with an Object Mapper. After that I try to get the additional information from my boxInventory by the same inventory id and then append it to the earlier received inventory.

The result is a rather big method which only gets bigger with other additions. My question now is if there is a good practise to handle situations like that? I found the API Composition pattern but I am not sure if I can handle mixing a database with a API the same way as if mixing different APIs.

public Optional<Inventory> findInventoryById(String inventoryId) {
        JSONObject inventoryJSON = inventoryRestClient.getInventoryById(inventoryId);
        if (inventoryJSON == null) {
            return Optional.empty();
        }

        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.registerModule(new JavaTimeModule());
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        Inventory inventory = objectMapper.convertValue(inventoryJSON, Inventory.class);

        //extracts boxTagInventory
        TypedQuery<BoxInventory> typedQuery =
                eM.createQuery("FROM BoxInventory WHERE INVENTORY_ID = :inventoryId",
                        BoxInventory.class);
        typedQuery.setParameter("inventoryId", inventory.inventoryId());
        List<BoxInventory> resultSet = typedQuery.getResultList();

        if(resultSet.isEmpty()){
            return Optional.empty();
        }
        inventory.addBoxInventory(resultSet.get(0));
        return Optional.of(inventory);

}
    
  • 1
    First of all, you don't need the object mapper, the Rest Client can return DTOs perfectly fine and you can configure the jackson mapper elsewhere. Second, I would have one method or dedicated class to access each set of data and another from merging the informacion, this should be cleaner. You can use the Service pattern or just DAO, with both the Rest Client and database Query. With the rest client if you return just a dto, i wouldn't bother to use a class to hide this complexity, if not, then yes – Javier Toja Jul 07 '21 at 11:10
  • I know services as a connection between my controller and domain layer. In this case I am already in the infrastructure layer. How would a service there look like? About the DAO Pattern: I just read about it and if I understand it correctly I also could just inject a BoxInventoryRepository with the same request? Can you inject another repository in a repository? – hikari_temp Jul 07 '21 at 13:26

0 Answers0