2

I have a JSON struct that looks something like this in pkg/response/foobar.go

type Foo struct {
    RequestID      string                     `json:"request_id"`
    Response       string                     `json:"response"`
}

func (resp *Foo) JSONBytes() []byte {
    result, err := json.Marshal(resp)
    if err != nil {
        // log the error (see below)
    }
    return result
}

I am very new to Go, and I am trying to integrate Uber's Zap logger. In pkg/endpoint/route1.go, I have

func processRequest(s *zap.SugaredLogger, // other params) error {
    for resp := range responses {
        //... other cases

        case *response.Foo:
            resp.Sugar = s // want to do something like this
            respBytes := resp.JSONBytes()
            wsResponses <- respBytes
    }
}

I then want to be able to pass the logger that's being used in processRequest and make it available to use for JSONBytes(). However, I am not sure of the implications of mixing a JSON struct with methods:

type Foo struct {
    RequestID      string                     `json:"request_id"`
    Response       string                     `json:"response"`
    Sugar          *zap.SugaredLogger         `json:"-"`
}

where I can then use the logger in JSONBytes(). If I try passing it as an argument in to JSONBytes(s), I get

resp (variable of type response.Response) cannot have dynamic type *response.Foo (wrong type for method JSONBytes (have func(s *go.uber.org/zap.SugaredLogger) []byte, want func() []byte))compilerImpossibleAssert

What is the most idiomatic way to make the logger available for JSONBytes().

blackgreen
  • 34,072
  • 23
  • 111
  • 129
TheRealFakeNews
  • 7,512
  • 16
  • 73
  • 114
  • 2
    (1) The call to json.Marshal will not fail unless you add fields that cannot be marshaled. Writing to a default logger may be good enough for handling the error (2) It looks like the caller, `processRequest`, handles errors. Another option is to return the error to the caller. (3) The error message is telling you that the type switch case is impossible: the type *resposne.Foo does not statisfy the response.Response interface. –  Dec 16 '21 at 05:32
  • 2
    setting the logger on the data model struct is... quite uncommon. you should return `([]byte, error)` from `JSONBytes` and log at the call site. Also the JSON tag should be `json:"-"` (with quotes) – blackgreen Dec 16 '21 at 07:49
  • I ended up going with Penelope's second choice – TheRealFakeNews Dec 16 '21 at 20:42

0 Answers0