bxcodec / go-clean-arch

Go (Golang) Clean Architecture based on Reading Uncle Bob's Clean Architecture
MIT License
9.22k stars 1.22k forks source link

If domain struct does not equal to database's schema, what should be done regarding repository's interface? #81

Open muhwyndhamhp opened 1 year ago

muhwyndhamhp commented 1 year ago

I have tried to implement the domain structure where we put our interface of Usecase and Repository in the domain module and are very close to the domain struct.

I very much so liking this approach as it solves our circular dependency, is closer to Domain-driven dev, and abstracts away our model from being too close to the DB schema.

But I have a peculiar case:

I am reimplementing this in an existing service that was up and running, meaning the DB schema is pretty much set (or very hard to migrate). Currently, my DB schema is not quite the same as the domain models, for example (this is not our real case but an example case):

// This is our DB schema
type SchemaUser struct {
    gorm.Model
    UserID               uint
    OtherRelatedID          uint
    Phone                   string
}

// This is our User domain model
type DomainUser struct {
    ID           uint             
    Name         string          
    PhoneNumber  string        
    Email        string            
    DeviceTokens map[string]string 

I found myself confused as to how should I structure the Repository interface. I tried to only put the domain model in the repository interface such as:

type DomainUserRepository interface {
    UpsertUser(ctx context.Context, value *DomainUser) error
        FetchOneByPhone(ctx context.Context, phone string) (*DomainUser, error)
}

But then not every field from SchemaUser is contained inside our DomainUser and vice versa, meaning that:

What should I do? some of the potential solutions as I understand it:

Any help will be greatly appreciated.

kordenlu commented 1 year ago

Create a converter that can convert PO to Domain Object or Domain Object to PO. The converter can be a separate class or method, or it can be a method of Domain Object or PO itself