Golang和gRPC编组/解组或手动方法

Following the "clean architecture", I'm now implementing a gRPC delivery package to interact with my managers(services). My domain entities are defined as pure Go structs with json tagging. The storage layer have its own definitions of the entities to allow custom types (such as sql.NullInt64). Here I use a manual approach to convert domain entities to sql types and vice versa. On the handler side, I see the same pattern emerges. I have to convert from/to gRPC types.

gRPC entity struct <-> Domain entity struct <-> SQL entity struct

I tested the following and it seems to work:

func (h *RPCHandler) DescribeRealm(ctx context.Context, in
*pb.DescribeRealmReq) (*pb.DescribeRealmResp, error) {

rlm, err := h.Manager.DescribeRealm(ctx, in.GetRealmId())
if err != nil {
    return nil, err
}

jb, err := json.Marshal(rlm)
if err != nil {
    return nil, err
}

r := &pb.Realm{}
if err := jsonpb.Unmarshal(bytes.NewReader(jb), r); err != nil {
    return nil, err
}

return &pb.DescribeRealmResp{
    Realm: r,
}, nil

My question is as follows:

Is this the preferred way to convert data between the different types of structs/layers, or should I stick with the manual approach?

Best regards, Karl.