ogen-go / ogen

OpenAPI v3 code generator for go
https://ogen.dev
Apache License 2.0
1.46k stars 86 forks source link

Encode/Decode: Unmarshal creates error, while marshal works fine #1254

Closed cugu closed 6 months ago

cugu commented 6 months ago

What version of ogen are you using?

v1.2.0

Can this issue be reproduced with the latest version?

Yes

What did you do?

I have a server created by ogen, which serves user objects with an optional team field, that is a string array. json.Marshal this with teams set to nil becomes null which I think is reasonable. However json.Unmarshal fails and always expects an array.

components:
  schemas:
    User:
      type: object
      properties:
        teams: { type: array, description: "The user teams", items: { type: string } }
      required: []
func TestUserMarshal(t *testing.T) {
    user := api.User{
        Teams: nil,
    }

    b, err := json.Marshal(user)
    if err != nil {
        t.Errorf("error marshalling user: %v", err)
    }

    var u2 api.User
    if err := json.Unmarshal(b, &u2); err != nil {
        t.Errorf("error unmarshalling user: %v", err)
    }
}

What did you expect to see?

Unmarshal without error

What did you see instead?

Unmarshal created an error:

decode User: callback: decode field "teams": "[" expected: unexpected byte 110 'n' at 33
tdakkota commented 6 months ago

Changing api.User to *api.User

 func TestUserMarshal(t *testing.T) {
-       user := api.User{
+       user := &api.User{
                Teams: nil,
        }

solves the issue.

It seems like encoding/json does not call MarshalJSON on pointer receiver: https://go.dev/play/p/tmEeCUL_6NY

cugu commented 6 months ago

That works. Thanks!