GO dynamic update queries with Gin and PGX

Viewed 315

I'm trying to build a web service which would receive an HTTP PATCH request to update some fields in a "users" table (so I don't know how many nor which ones have to be updated).

I decided to work with Gin and because I'm working with Postgres, I'm using pgx.

The request...

PATCH {{protocol}}{{host}}/update-user/USER_ID_XXX HTTP/1.1
content-type: application/json
Authorization: Bearer : TOKEN_XXX

{
    "review_count": 2,
    "rating": 2.2,
}

... is handled by the Patch method

func (handler *userHandler) Patch(c *gin.Context) {
    reqBody := &users.User{}
    err := c.BindJSON(reqBody) <------ BREAKS
    if err != nil {
        c.JSON(http.StatusBadRequest, rest_errors.NewInternalServerError("JSON Binding Failed while trying to patch user", err))
        return
    }
    ...

The User struct makes uses of pgtypes. This is because, in the context of a GET request, if I retrieve a User from Postgres who has a review_count field set to null, i get an error when trying to marshal the result. So the pgtype.Int struct encapsulate the original value, a few other fields and contains a MarshalJSON() function to do the job properly ( see the MarshalJSON function here in pgtype.Int2 )

user_dto.go

type User struct {
    Id                string        `json:"id"`
    ...
    ReviewCount       pgtype.Int2   `json:"review_count"`
    Rating            float32       `json:"rating"`
    ...
}

Back to our PATCH request, the problem naturally comes in when I receive a field that is "pgtyped" like review_count .... Gin tries to unmarshal it and fails because it parses an int value and he's asked to put it into the pgtype.Int2 struct. So when I call err := c.BindJSON(reqBody) I get this error

"json: cannot unmarshal number into Go struct field User.ReviewCount of type pgtype.Int2"

I never had to implement this kind of feature before and I must confess that I know nothing about the "best options" if only I knew one that is working :D

0 Answers
Related