Preferences

homebrewer parent
I don't know about Go, but in Java and .NET world this is trivially solvable with libraries like MapStruct. If you have a model with 20 fields and need to create a tiny slice of it (with let's say three fields), you need a few lines of boilerplate: create a record with those fields (1-3 LOC):

  record Profile(int id, String login, boolean isAdmin) {}
create a mapper for it:

  interface UserMapper {
    // arrays are just one example, plain models and plenty
    // of other data structures are supported
    Profile[] usersToProfiles(User[] user);

    // other mappers...
  }
and then use it:

  class UserController {
    //
    @GET("/profiles")
    Profile[] getUserProfiles() {
      var users = userRepo.getUsers();
      return userMapper.usersToProfiles(users);
    }
  }
As long as fields' names match, everything will be handled for you. Adding another "view" of your users requires creating that "view" (as a record or as a plain class) and adding just one line to the mapper interface, even if that class contains all User's fields but one. So no need to write and maintain 19+ lines of copying data around.

It also handles nested/recursive entities, nulls, etc. It's also using codegen, not reflection, so performance is exactly the same as if you had written it by hand, and the code is easy to read.

https://mapstruct.org

Go developers usually "don't need these complications", so this is just another self-inflicted problem. Or maybe it's solved, look around.


Actually it's even easier in Go with struct embedding:

    type SmallerThing struct {
        Id     int
        Login  string
        IsAdmin bool
    }

    type UserController struct {
        SmallerThing
        OtherField  Whatever
        OtherField2 SomethingElse
    }
In principle this could break down if you need super, super complicated non-overlapping mappings, in practice I have yet to need that.
kgeist
>you have a model with 20 fields and need to create a tiny slice of it (with let's say three fields), you need a few lines of boilerplate: create a record with those fields (1-3 LOC):

>create a mapper for it:

> ...

>Go developers usually "don't need these complications", so this is just another self-inflicted problem.

In Go:

  type DTO struct {
    A, B, C string
  }
Somewhere in your API layer:

  // copy the fields to the DTO
  return DTO{A: o.A, B: o.B, C: o.C}
I fail to see where the "self-inflicted problem" is and why it requires a whole library? (which seems to require around the same number of lines of code at the end of the day, if you count the imports, the additional mapper interface)

This item has no comments currently.