Code structuring which approach would be better?

Hi everyone,

I’m working on a go code api where the main task of the code is to take the data from the cassandra db and do some data transformation from one form to another. But I’m confused on the fact that which approach would be better to achieve the same.

Deep diving into my code base.
I’m following 3 layer architecture store, service and http, where
store: deals with the data retrieval from the db
service: deals with the business rules that should be applied on the validation
http: that takes the data from the service and delivers it to the client.

I have a directory called models where I store all the go structs that I’m using.

my code directory structure looks something like this:

stores
  product.go
services
  product.go
http
  product.go
models
  product.go

Now explaining the problem:

The structure of the data that I get from the db looks something like this:

type ProductModel struct{
  Name string
  Code string
  Department CodeNamePair
  Fact CodeNamePair
}

type CodeNamePair struct{
  Name string
  Code string
}

The structure that I want as an output should be:

type ProductResponse struct{
  Name string
  Code string
  DepartmentCode string
  DepartmentName string
  FactCode string
  FactName string
}

So currently I have come across two approaches which is technically correct and both of them works. But there are some conflicting ideas for which I need to conclude and finalise. Going through the both:

1.Implementing the method on the ProductModel struct:
In the models Package I would write a method called transform which converts the db struct into a response.Something like this:

func (p *Product) Transform() ProductResponse {
  return ProductResponse{
    Name:p.Name
    Code:p.Code
    DepartmentCode:p.Department.Code
    DepartmentName:p.Department.Name
    FactCode:p.Fact.Code
    FactName:p.Fact.Name
  }
}

Pros:
a.The code looks more cleaner and readable because the structs and the methods are intact.

Cons:
a.The business logic that has to be implemented comes into models package which should have been on service layer.
b.This exposes the Transform method to the outside world.

2.Implementing the independent function that takes the ProductModel struct and returns the ProductResponse in the service layer. Something like this:

func transformProduct(p models.ProductModel) models.ProductResponse {
  return models.ProductResponse{
    Name:p.Name
    Code:p.Code
    DepartmentCode:p.Department.Code
    DepartmentName:p.Department.Name
    FactCode:p.Fact.Code
    FactName:p.Fact.Name
  }
}

Pros:
a.The logic of data transformation remains in the service layer
Cons:
a.The code gets messed up when more structs have to be transformed and we will have more functions coming in the service layer.

Note: The illustration given are very basic and in reality I have a huge struct that has almost 400 fields that has to be transformed individually.

Please let me know which of these approach is better. If you have a suggestion for a new way of doing this, that would be helpful too.

Thanks in advance.

Conceptually, ProductResponse represents a “view” in SQL-land and is properly part of the store layer. (Not to be confused with “materialized view” in CQL-land.) Here’s an overview - https://en.wikipedia.org/wiki/View_(SQL).