1

I am new on DDD and hexagonal architecture and I am stuck in deciding where to place a very simple piece of code.

To code is a simple JWT decode. For SRP reasons, I want to isolate this action into an specific class like the next one, but the question is where...

class JWTDecoder
  def initialize(id_token, signing_key)
    @id_token = id_token
    @signing_key = signing_key
  end

  def decode
    JWT.decode(@id_token, @signing_key, ...)
  end
end

IMHO it's not Domain (because has nothing to do with my domain), it's not Infra (because it does not depend on any external service), it's neither application.

  • Maybe an application service?
  • Is the authentication flow a bounded context of the domain?

2 Answers 2

2

In terms of hexagonal architecture, if it's working on something coming from the outside than it's associated with an adapter (think of an adapter as of a class that reaches out or accepts outside requests + any data structures and helper classes associated with it).

Now, since the need to decode a token is not adapter-specific, and in fact can be called (shared) by several different adapters, it's an implementation detail of those adapters.

"it's not Infra (because it does not depend on any external service)"

In terms of DDD, the Infrastructure layer is not a layer that calls some external web service API, it's a layer that provides generic technical capabilities to other layers. Decoding a string is a generic technical capability. Also, your implementation does depend on external code: JWT.decode is external code that provides a decoding service (the word "service" is used here in the usual conversational English sense).

Is the authentication flow a bounded context of the domain?

You'd first have to define what you mean by bounded context, because many people use the term in a way that's not equivalent to how it was defined in Eric Evans' book. If that meaning is meant, it wouldn't make sense to call the authentication flow a bounded context, because a bounded context is about you (and your team) deciding not to have a single unified, sprawling model of the domain, but splitting it into two or more models with explicit applicability boundaries (as in, when dealing with this part of the business, this model / way of thinking applies, when dealing with this other part of business, this other model / way of thinking applies). This is done in order to make things simpler for you - to get simpler, cleaner models that have small overlap that you can manage, rather than having to reconcile a bunch of contradictions and edge cases arising from the complexities of real business.

You and your team are the ones doing the modeling: you decide what a bounded context is, based on your understanding of the specific problem domain you're working on (that is, you are the ones who are in the best position to come up with bounded contexts, and it is your prerogative to decide how to conceptualize the system; this is not some generic concern where there's a prescribed solution).

But many people use "bounded context" to denote either the parts of the system that all share the same subset of the overall model, or even more wrongly, to denote some sort of self-contained component or a (micro)service, or some such thing. Of course there will be boundaries within the system implementing a domain model, but all that is just your usual decomposition within the domain, so when used like this, the term is in some sense wasted.

Authentication is about determining the identity of the user. You can separate out the authentication flow (either manually, or with a help of some library/framework) - doing so allows your application code (that's meant to orchestrate requests to the domain) to not be intermixed with authentication concerns.

Note, though, that your JWTDecoder class doesn't really contain any logic at the abstraction level of the authentication flow itself, it's just a helper decoder used within it (again, a technical capability).

Be careful, though, as authentication is distinct from authorization (who can do what, when and why) - while, perhaps, not the core business logic, authorization is business logic, or is closely associated to it, and is much more of a cross cutting concern, and a whole other topic.

1

Evans, in Chapter 4, details four distinct layers

  • Presentation
  • Application
  • Domain
  • Infrastructure

His description of the infrastructure layer:

Provides generic technical capabilities that support the higher layers: message sending for the application, persistence for the domain, drawing widgets for the UI, and so on.

Notice: nothing in that definition assumes that there must be an external service.

So dropping it into the infrastructure layer should be "fine", in the sense of being consistent with the constraints of this layered architecture.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.