2

I have an application with the following layers:

  • Web API - Provides an access point for external calls to enter the application.
  • Infrastructure - Provides repositories which allows access to the database.
  • Service layer - Responsible for different use cases (e.g. 'Add item to cart').
  • Domain - Contains domain objects with business logic.

You can see how they reference each other, in the drawing below.

I want to add a typed http client, to fetch certain information from an external API.

In what layer/project, should the typed client be created?

My reasoning so far:

The first thing that came to me, was the infrastructure project. But since the infrastructure points towards the service layer (which needs the data from the API), that means introducing an interface on top of the API. This also means that the response object, from the typed client, must be defined in the infrastructure layer (this is where it starts to get messy).

If that is the case, that means that one of the two following must be true:
A) The service layer gets to depend on the API response directly or
B) The typed client must map the response to an object defined in the service layer.

This means that I can either introduce a dependency, in which case I might as well put it all in the service layer. Or I make the typed client more than a typed client, which really feels like a code smell.

Architechtural diagram of the layers.

Peter Csala
  • 17,736
  • 16
  • 35
  • 75
Jakob Busk Sørensen
  • 5,599
  • 7
  • 44
  • 96
  • Could you please add some description what each layer's responsibilites are? – Peter Csala Nov 07 '22 at 12:36
  • HTTP Client must connect to a HTTP Server. Following steps are performed 1) Client Sends a Request 2) Server Receives Request 3) Server Processes the request 4) Server sends a response 5) Client receives response. HTTP request contains an URL, HTTP Headers (optional), and HTTP Body (optional). Response contains a HTTP Header with Status Code and optional additional headers, and optional Body. Server has to be able to understand any message that client sends and likewise the client has to be able to understand any response received from server. So any model has to be at both client and server. – jdweng Nov 07 '22 at 13:13
  • @PeterCsala I have tried updating the list with a brief summary. But you can also answer it, with respect to Hexagonal Architecture, if that helps. In that case I guess the question would be, if a typed client, can be considered an adapter. – Jakob Busk Sørensen Nov 07 '22 at 13:34
  • 1
    If we are talking about Hexagonal Architecture then yes Typed HttpClient is an adapter. – Peter Csala Nov 07 '22 at 13:53

1 Answers1

1

Some thoughts about your layering

Based on the your definitions:

Infrastructure - Provides repositories which allows access to the database.
Service layer - Responsible for different use cases (e.g. 'Add item to cart').

none of these have the responsibility to communicate with 1st and/or 3rd party services. It seems like your Infrastructure layer is a data access layer (in other traditional layered architecture naming), whereas the Service layer is the business logic layer.


Where to place

After this little detour let's focus on your question where to place the typed client(s). You can reason about that either of the layers can be good home of the typed clients. I would suggest to make a decision based on the followings:

  • If you have multiple independent typed clients and most of your business logic calls only one of them OR if the business logic utilizes multiple typed clients but only to aggregate their responses
    • Then place it where it feels right, It does not matter whether they are defined at the bottom layer or in the middle
  • If you have business processes / workflows which are typically utilizing multiple typed clients in a specific order OR in a pipeline fashion (one client's response is the input for the other client's request)
    • Then define them in the same layer as the process/workflow reside, because they are interconnected and most probably you want to avoid that situation that an other layer can use them in the wrong order or just partially

I hope my guidance could be applied for your particular case as well :)

Peter Csala
  • 17,736
  • 16
  • 35
  • 75
  • 1
    Thanks for the thoughts. You make some great points. I think our application is close to the latter of your examples. I’m leaning towards making an adapter for this specific case, which also aggregates and maps. But I’m glad I’m not the only one struggling to give a definitive answer :-) – Jakob Busk Sørensen Nov 09 '22 at 15:52