Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Why domain model know about json? #50

Open
Bogdaan opened this issue May 30, 2020 · 5 comments
Open

Why domain model know about json? #50

Bogdaan opened this issue May 30, 2020 · 5 comments

Comments

@Bogdaan
Copy link
Contributor

Bogdaan commented May 30, 2020

  1. Why domain model know about json (presentation level)?
  2. Why domain model know about input validation?
type Article struct {
	ID        int64     `json:"id"`
	Title     string    `json:"title" validate:"required"`
	Content   string    `json:"content" validate:"required"`
	Author    Author    `json:"author"`
	UpdatedAt time.Time `json:"updated_at"`
	CreatedAt time.Time `json:"created_at"`
}

Maybe better to separate this concerns.

@aeharvlee
Copy link

aeharvlee commented Jun 2, 2020

I think it is not strange. It is really helpful using Tags in structure.
Domain in the clean architecture means "What kind of data structure will you use in the project?".

With tags, we can interpret that file like "Oh, the project of Bogdaan will use a Article data structure. There is fields which describe details of Article and I can see json tags which will be used when binding request or response. Title and Content of Article must be used when request Article in the project. I see how this domain(=Article) works."

So in my opinion, tags should be in the domain file.
Separating files would increase more complex.

@devarsh
Copy link

devarsh commented Jun 3, 2020

@Bogdaan something I read which cleared my doubts about handling validation, you might want check it out: https://medium.com/@apzuk3/input-validation-in-golang-bc24cdec1835

@stackus
Copy link

stackus commented Jun 18, 2020

My take is the json and validation tags, and tags in general do not belong in the domain.

I don't accept or return my domain entities in my delivery layer. Instead delivery specific input and output structs are used and on those I'll use json tags. Using additional structs does add complexity and I am comfortable with that because to me using them has benefits. I'm protected from additions or other changes to my entities being accidentally exposed as a value that can be submitted or displayed. I also may not marshal the entity the same way everywhere.

I would also make the case that the validation struct tags do not belong because they don't describe the business rules they are meant to enforce. Are these used during the article draft creation? Are they used when the article is promoted and published? A NewArticle(title, content string) Article constructor in the domain would be the route I'd take.

Validation would be handled in a couple places and for different concerns. Delivery would validate structures, and garbage input checks but nothing business related. Service/Usecases would validate business rules like uniqueness, ownership, relationships, aggregate stuff. Domain entities would have methods to modify internal state and would also do validation.

The AWS DynamoDB SDK uses dynamodbav:"title" tags for marshalling and to me it is an easy argument that they shouldn't exist within the domain. I choose to apply this to all tags vs making exceptions.

I do have an open mind and a good counter opinion would be considered.

@bxcodec
Copy link
Owner

bxcodec commented Jun 19, 2020

Hi everyone, thanks for your opinions and recommendations.
I'll answer from my side as the one who made this repository.

I agree with @Bogdaan and @stackus to be honest. I've been thinking about this quite a long time ago. I agree to have a separate data structure in Controller and in Repository.

But IRL, I never met projects that have a complex marshall method. So, to increase the pace for development, I put the struct tag (JSON and validate) in the domain.

But there's a case I forgot which project it is, I have 3 databases, MongoDB, MySQL, AeroSpike. MongoDB has the bson tag. For this case, I made my own struct for the repository layer (MongoDB part). And Aerospike, since the data structure is different, I also define my own struct in the repository. So I will map the domain struct to the repository's struct in the repository layer. So it's the same as @stackus said. But it's only happened once so far since my project is only around REST and Postgres in the past year.

About this current project in this Github repo, yes, I only put the tag in the domain for the sake of its simplicity LOL. I mean, this is only a simple CRUD.

But yeah, I agree with putting the specific tag to its respective layer. JSON and Validate in the controller, BSON, and Dynamodeb tag in the repository.

@AlexanderMatveev
Copy link

AlexanderMatveev commented Mar 15, 2021

I want to add one case that forces me to stop using tags in the domain entity. This is a simple differentiation of access: one user can see specific fields of the domain entity, the second cannot.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants