Skip to main content
Clarifying that you don't need one user class per module
Source Link
Greg Burghardt
  • 46.6k
  • 8
  • 87
  • 151

Modular monoliths, micro services, and domain-driven design have one important thing in common: clear boundaries between functionality. I'd like to borrow a bit of DDD to put this problem in perspective and suggest a solution.

Modeling Shared Entities Across Bounded Contexts in Domain-Driven Design by Lalit Kale presents a similar situation as yours. An e-commerce application has the concept of a customer in Sales and Support. At first glance, both modules need a Customer class, but each module has some unique needs of a customer:

  • The Sales team cares about a customer's lead score, purchase intent, and assigned sales rep.
  • The Support team, on the other hand, is focused on support ticket history, SLA agreements, and incident timelines.

Clearly, while the term "Customer" is shared, its meaning and usage diverge across these contexts. This is a textbook case of polysemy in DDD — the same term having multiple meanings in different bounded contexts.

Source

The concept of a User in your application might have a similar polysemous meaning; each module has it's own similar concept of a User with slight differences. The biggest difference between users is between the authentication module and all of the rest of the application. In short: let each module define it's own User class, each with their own properties and methods.

Sure, you'll have some overlap — all User classes will have a username, for example — but don't be afraid to copy data; it's behavior you want to be weary of duplicating. Properties have no behavior, so copying properties isn't really a DRY violation, in my opinion.

So, that's my recommendation: let each module declare it's own User class tailored to the needs of that particular module. In the very least, have two representations of a user: one for the authentication module encapsulating business rules for managing users, and a simpler one for the rest of the application that encapsulates the refresh token and related fields to facilitate web service calls.

This keeps the complexity of supporting multiple authentication strategies locallocal to the authentication module. Now you are free to go crazy with your authentication module database schema which will limit the pain induced by major changes in the future. Only once you change something truly common to all modules should you see widespread changes across module boundaries.

Modular monoliths, micro services, and domain-driven design have one important thing in common: clear boundaries between functionality. I'd like to borrow a bit of DDD to put this problem in perspective and suggest a solution.

Modeling Shared Entities Across Bounded Contexts in Domain-Driven Design by Lalit Kale presents a similar situation as yours. An e-commerce application has the concept of a customer in Sales and Support. At first glance, both modules need a Customer class, but each module has some unique needs of a customer:

  • The Sales team cares about a customer's lead score, purchase intent, and assigned sales rep.
  • The Support team, on the other hand, is focused on support ticket history, SLA agreements, and incident timelines.

Clearly, while the term "Customer" is shared, its meaning and usage diverge across these contexts. This is a textbook case of polysemy in DDD — the same term having multiple meanings in different bounded contexts.

Source

The concept of a User in your application might have a similar polysemous meaning; each module has it's own similar concept of a User with slight differences. The biggest difference between users is between the authentication module and all of the rest of the application. In short: let each module define it's own User class, each with their own properties and methods.

Sure, you'll have some overlap — all User classes will have a username, for example — but don't be afraid to copy data; it's behavior you want to be weary of duplicating. Properties have no behavior, so copying properties isn't really a DRY violation, in my opinion.

So, that's my recommendation: let each module declare it's own User class tailored to the needs of that particular module. This keeps the complexity of supporting multiple authentication strategies local to the authentication module. Now you are free to go crazy with your authentication module database schema which will limit the pain induced by major changes in the future. Only once you change something truly common to all modules should you see widespread changes across module boundaries.

Modular monoliths, micro services, and domain-driven design have one important thing in common: clear boundaries between functionality. I'd like to borrow a bit of DDD to put this problem in perspective and suggest a solution.

Modeling Shared Entities Across Bounded Contexts in Domain-Driven Design by Lalit Kale presents a similar situation as yours. An e-commerce application has the concept of a customer in Sales and Support. At first glance, both modules need a Customer class, but each module has some unique needs of a customer:

  • The Sales team cares about a customer's lead score, purchase intent, and assigned sales rep.
  • The Support team, on the other hand, is focused on support ticket history, SLA agreements, and incident timelines.

Clearly, while the term "Customer" is shared, its meaning and usage diverge across these contexts. This is a textbook case of polysemy in DDD — the same term having multiple meanings in different bounded contexts.

Source

The concept of a User in your application might have a similar polysemous meaning; each module has it's own similar concept of a User with slight differences. The biggest difference between users is between the authentication module and all of the rest of the application. In short: let each module define it's own User class, each with their own properties and methods.

Sure, you'll have some overlap — all User classes will have a username, for example — but don't be afraid to copy data; it's behavior you want to be weary of duplicating. Properties have no behavior, so copying properties isn't really a DRY violation, in my opinion.

So, that's my recommendation: let each module declare it's own User class tailored to the needs of that particular module. In the very least, have two representations of a user: one for the authentication module encapsulating business rules for managing users, and a simpler one for the rest of the application that encapsulates the refresh token and related fields to facilitate web service calls.

This keeps the complexity of supporting multiple authentication strategies local to the authentication module. Now you are free to go crazy with your authentication database schema which will limit the pain induced by major changes in the future. Only once you change something truly common to all modules should you see widespread changes across module boundaries.

added 103 characters in body
Source Link
Greg Burghardt
  • 46.6k
  • 8
  • 87
  • 151

Modular monoliths, micro services, and domain-driven design have one important thing in common: clear boundaries between functionality. I'd like to borrow a bit of DDD to put this problem in perspective and suggest a solution.

Modeling Shared Entities Across Bounded Contexts in Domain-Driven Design by Lalit Kale presents a similar situation as yours. An e-commerce application has the concept of a customer in Sales and Support. At first glance, both modules need a Customer class, but each module has some unique needs of a customer:

  • The Sales team cares about a customer's lead score, purchase intent, and assigned sales rep.
  • The Support team, on the other hand, is focused on support ticket history, SLA agreements, and incident timelines.

Clearly, while the term "Customer" is shared, its meaning and usage diverge across these contexts. This is a textbook case of polysemy in DDD — the same term having multiple meanings in different bounded contexts.

Source

The concept of a User in your application might have a similar polysemous meaning; each module in your modular monolith has it's own similar concept of a User with slight differences. The biggest difference between users is between the authentication module and all of the rest of the application. In short: let each module define it's own User class, each with their own attributesproperties and methods.

Sure, you'll have some overlap — all User classes will have a username, for example — but don't be afraid to copy data; it's behavior you don't want to duplicatebe weary of duplicating. Properties have no behavior, so copying properties isn't really a DRY violation, in my opinion.

So, that's my recommendation: let each module declare it's own User class tailored to the needs of that particular module. This preventskeeps the complexity of supporting multiple authentication strategies from leaking out of local to the authentication module and crossing boundaries. Now you are free to go crazy with your authentication module database schema which will limit the pain induced by major changes in the future. Only once you change something truly common to all modules should you see widespread changes across module boundaries.

Modular monoliths, micro services, and domain-driven design have one important thing in common: clear boundaries between functionality. I'd like to borrow a bit of DDD to put this problem in perspective and suggest a solution.

Modeling Shared Entities Across Bounded Contexts in Domain-Driven Design by Lalit Kale presents a similar situation as yours. An e-commerce application has the concept of a customer in Sales and Support. At first glance, both modules need a Customer class, but each module has some unique needs of a customer:

  • The Sales team cares about a customer's lead score, purchase intent, and assigned sales rep.
  • The Support team, on the other hand, is focused on support ticket history, SLA agreements, and incident timelines.

Clearly, while the term "Customer" is shared, its meaning and usage diverge across these contexts. This is a textbook case of polysemy in DDD — the same term having multiple meanings in different bounded contexts.

Source

The concept of a User in your application might have a similar polysemous meaning; each module in your modular monolith has it's own similar concept of a User with slight differences. The biggest difference between users is between the authentication module and all of the rest of the application. In short: let each module define it's own User class, each with their own attributes and methods.

Sure, you'll have some overlap — all User classes will have a username, for example — but don't be afraid to copy data; it's behavior you don't want to duplicate.

So, that's my recommendation: let each module declare it's own User class tailored to the needs of that particular module. This prevents the complexity of supporting multiple authentication strategies from leaking out of the authentication module and crossing boundaries. Now you are free to go crazy with your authentication module database schema which will limit the pain induced by major changes in the future. Only once you change something truly common to all modules should you see widespread changes across module boundaries.

Modular monoliths, micro services, and domain-driven design have one important thing in common: clear boundaries between functionality. I'd like to borrow a bit of DDD to put this problem in perspective and suggest a solution.

Modeling Shared Entities Across Bounded Contexts in Domain-Driven Design by Lalit Kale presents a similar situation as yours. An e-commerce application has the concept of a customer in Sales and Support. At first glance, both modules need a Customer class, but each module has some unique needs of a customer:

  • The Sales team cares about a customer's lead score, purchase intent, and assigned sales rep.
  • The Support team, on the other hand, is focused on support ticket history, SLA agreements, and incident timelines.

Clearly, while the term "Customer" is shared, its meaning and usage diverge across these contexts. This is a textbook case of polysemy in DDD — the same term having multiple meanings in different bounded contexts.

Source

The concept of a User in your application might have a similar polysemous meaning; each module has it's own similar concept of a User with slight differences. The biggest difference between users is between the authentication module and all of the rest of the application. In short: let each module define it's own User class, each with their own properties and methods.

Sure, you'll have some overlap — all User classes will have a username, for example — but don't be afraid to copy data; it's behavior you want to be weary of duplicating. Properties have no behavior, so copying properties isn't really a DRY violation, in my opinion.

So, that's my recommendation: let each module declare it's own User class tailored to the needs of that particular module. This keeps the complexity of supporting multiple authentication strategies local to the authentication module. Now you are free to go crazy with your authentication module database schema which will limit the pain induced by major changes in the future. Only once you change something truly common to all modules should you see widespread changes across module boundaries.

Source Link
Greg Burghardt
  • 46.6k
  • 8
  • 87
  • 151

Modular monoliths, micro services, and domain-driven design have one important thing in common: clear boundaries between functionality. I'd like to borrow a bit of DDD to put this problem in perspective and suggest a solution.

Modeling Shared Entities Across Bounded Contexts in Domain-Driven Design by Lalit Kale presents a similar situation as yours. An e-commerce application has the concept of a customer in Sales and Support. At first glance, both modules need a Customer class, but each module has some unique needs of a customer:

  • The Sales team cares about a customer's lead score, purchase intent, and assigned sales rep.
  • The Support team, on the other hand, is focused on support ticket history, SLA agreements, and incident timelines.

Clearly, while the term "Customer" is shared, its meaning and usage diverge across these contexts. This is a textbook case of polysemy in DDD — the same term having multiple meanings in different bounded contexts.

Source

The concept of a User in your application might have a similar polysemous meaning; each module in your modular monolith has it's own similar concept of a User with slight differences. The biggest difference between users is between the authentication module and all of the rest of the application. In short: let each module define it's own User class, each with their own attributes and methods.

Sure, you'll have some overlap — all User classes will have a username, for example — but don't be afraid to copy data; it's behavior you don't want to duplicate.

So, that's my recommendation: let each module declare it's own User class tailored to the needs of that particular module. This prevents the complexity of supporting multiple authentication strategies from leaking out of the authentication module and crossing boundaries. Now you are free to go crazy with your authentication module database schema which will limit the pain induced by major changes in the future. Only once you change something truly common to all modules should you see widespread changes across module boundaries.