The book "Implementing Domain Driven Design" (page 361) suggests to use special types to distinguish several kinds of IDs, e. g. using BookId(1)
instead of just 1
of type Int
or Long
. In my Clean Architecture or Onion Architecture the outermost layer is a HTTP adapter taking an id
of type Long
. Then this adapter calls an application service, which in turn calls the domain (a repository in this case). The flow is as follows:
HTTP Adapter → Application Service → Domain
The question is where to convert the Long
to BookId
. In principle there are two options:
1) Convert it in the HTTP adapter. This would have the benefit that the raw type would no longer exist and no one could ever use an AuthorId
where a BookId
should have been used. The conversation could even be performed by the framework, so that no code would ever have to convert or handle raw types. An example with Jersey (JAX/RS) could look like this:
@GET
@Path("/books/{id}")
fun findById(id: BookId): Response { ... }
A converter registered by the framework would take the Long
value from the request and convert it to a BookId
automatically.
HTTP Adapter → Application Service → Domain
Long → BookId BookID BookId
2) The Long
value could be passed to the application service. However, I don't see any benefit here.
HTTP Adapter → Application Service → Domain
Long Long → BookId BookID
Question: Where is the best place for the conversion? Do you see any good reason not to convert the value as early as possible?
long
. The interface of the adapter is defined by the Application Service, and resides in the same layer; as such it is expressed in terms of types and abstractions decided by the Application Service. Imagine now that it's notlong
, but some library-specific data structure - then it becomes more obvious; if you do (2), then App Service has a dependency on HTTP Adapter (and the lib) - which breaks the dependency rule.