99designs / gqlgen

go generate based graphql server library

Home Page:https://gqlgen.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Test client error while deserializing Time scalar

sobafuchs opened this issue · comments

What happened?

When deserializing a Time scalar, I received an error that expected a map, got 'string'. This seems to be a regression of #1372, unless I'm doing something wrong.

What did you expect?

I expected to be able to deserialize a Time scalar to a time.Time.

Minimal graphql.schema and models to reproduce

I will attach a zip folder of the entire code that you can unzip and run with go test ./... to see what I mean, but here are the relevant files if you just want to copy paste. When I run the tests on the file main_test.go that you see below, I get an error that it expects a map but got a string. I've specified Time as a scalar in my schema in the first line, so I presumed that gqlgen would generate the correct unmarshalling and marshalling logic for me. But something seems to have gone wrong there.

schema.graphqls

# GraphQL schema example
#
# https://gqlgen.com/getting-started/

scalar Time

type Todo {
  text: String!
  date: Time!
}

type Query {
  todos: [Todo!]!
}

input NewTodo {
  text: String!
  date: Time!
}

type Mutation {
  createTodo(input: NewTodo!): Todo!
}

models_gen.go

// Code generated by github.com/99designs/gqlgen, DO NOT EDIT.

package model

import (
	"time"
)

type Mutation struct {
}

type NewTodo struct {
	Text string    `json:"text"`
	Date time.Time `json:"date"`
}

type Query struct {
}

type Todo struct {
	Text string    `json:"text"`
	Date time.Time `json:"date"`
}

main_test.go

package main

import (
	"testing"

	"report/graph"
	"report/graph/model"

	"github.com/99designs/gqlgen/client"
	"github.com/99designs/gqlgen/graphql/handler"
)

func Test_GQL(t *testing.T) {
	srv := handler.NewDefaultServer(
		graph.NewExecutableSchema(
			graph.Config{Resolvers: &graph.Resolver{}},
		),
	)
	query := `
        mutation addTodo {
            createTodo(input: {text: "test", date: "2024-02-02T12:00:00Z"}) {
                text
                date
            }
        } `
	var resp struct {
		CreateTodo model.Todo `json:"createTodo"`
	}

	err := client.
		New(srv).
		Post(query, &resp)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}

	if resp.CreateTodo.Date.String() != "2024-02-02T12:00:00Z" {
		t.Errorf("date did not match")
	}
}

versions

  • go run github.com/99designs/gqlgen version? 0.17.44
  • go version? 1.22.0 darwin/arm64

zip folder of bug report

You can unzip this folder and simply run go test ./... to see what I mean:

gql-gen-bug-report.zip

I've realized now that you have to supply a custom decoder hook. Is this documented anywhere? And is there away that this could be provided by the gqlgen lib itself? It seems a bit unreasonable to require importing mapstructure just so you can deserialize a time scalar with the test client, which I imagine is a very common use case. I would be open to providing a PR if this is a feature you would be open to supporting.