Giter VIP home page Giter VIP logo

Comments (11)

karthikvt26 avatar karthikvt26 commented on July 28, 2024 3

Bumped into this issue. Any update on supporting this?
Thanks

from graphql.

adamgoose avatar adamgoose commented on July 28, 2024 1

I have gone ahead and introduced the issue into the boilerplate code you provided above.

package main

import (
	"context"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"net/http/httptest"

	"github.com/shurcooL/graphql"
)

func main() {
	mux := http.NewServeMux()
	mux.HandleFunc("/graphql", func(w http.ResponseWriter, req *http.Request) {
		w.Header().Set("Content-Type", "application/json")
		io.WriteString(w, `{"data": {"viewer": {"login": "gopher", "bio": "The Go gopher.", "meta": {"foo": "bar"}}}}`)
	})
	client := graphql.NewClient("/graphql", &http.Client{Transport: localRoundTripper{handler: mux}})

	var query struct {
		Viewer struct {
			Login     string
			Biography string `graphql:"bio"`
			Meta      json.RawMessage
		}
	}
	err := client.Query(context.Background(), &query, nil)
	fmt.Println("error:", err)
	fmt.Printf("query: %+v\n", query)

	// Output:
	// error: <nil>
	// query: {Viewer:{Login:gopher Biography:The Go gopher.}}
}

// localRoundTripper is an http.RoundTripper that executes HTTP transactions
// by using handler directly, instead of going over an HTTP connection.
type localRoundTripper struct {
	handler http.Handler
}

func (l localRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
	w := httptest.NewRecorder()
	l.handler.ServeHTTP(w, req)
	return w.Result(), nil
}

from graphql.

cameronbrunner avatar cameronbrunner commented on July 28, 2024 1

@cor My #41 branch is still here... https://github.com/Navops/graphql/tree/support-raw-json (the v0.0.2 tag is pointing at this branches current HEAD/tip). You can use that directly, fork it, etc. We do something similar in our project by adding the following line to our go.mod

replace github.com/shurcooL/graphql => github.com/navops/graphql v0.0.2

from graphql.

brandonbloom avatar brandonbloom commented on July 28, 2024 1

This is now supported in my transport-agnostic fork: https://github.com/deref/graphql-go

The specific changes are here: deref/graphql-go@c7885fd...e2b4739

from graphql.

dmitshur avatar dmitshur commented on July 28, 2024

Thanks for the report. How can I reproduce this?

from graphql.

seta-tonypham avatar seta-tonypham commented on July 28, 2024

@dmitshur I have same issue too, My GQL like struct below
query { example(id:"123456") { id jsondata } }
jsondata result example is {foo: bar}

from graphql.

dmitshur avatar dmitshur commented on July 28, 2024

There's not enough information there for me to reproduce this. Can you please post a minimal working Go program that triggers that error? Or at least include the query (or a minified version of it) you wrote, and the JSON response from the GraphQL server?

Here's a starting point to make it easier; you just need to replace the query and JSON response:

package main

import (
	"context"
	"fmt"
	"io"
	"net/http"
	"net/http/httptest"

	"github.com/shurcooL/graphql"
)

func main() {
	mux := http.NewServeMux()
	mux.HandleFunc("/graphql", func(w http.ResponseWriter, req *http.Request) {
		w.Header().Set("Content-Type", "application/json")
		io.WriteString(w, `{"data": {"viewer": {"login": "gopher", "bio": "The Go gopher."}}}`)
	})
	client := graphql.NewClient("/graphql", &http.Client{Transport: localRoundTripper{handler: mux}})

	var query struct {
		Viewer struct {
			Login     string
			Biography string `graphql:"bio"`
		}
	}
	err := client.Query(context.Background(), &query, nil)
	fmt.Println("error:", err)
	fmt.Printf("query: %+v\n", query)

	// Output:
	// error: <nil>
	// query: {Viewer:{Login:gopher Biography:The Go gopher.}}
}

// localRoundTripper is an http.RoundTripper that executes HTTP transactions
// by using handler directly, instead of going over an HTTP connection.
type localRoundTripper struct {
	handler http.Handler
}

func (l localRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
	w := httptest.NewRecorder()
	l.handler.ServeHTTP(w, req)
	return w.Result(), nil
}

from graphql.

adamgoose avatar adamgoose commented on July 28, 2024

I'm also running into this issue. I am using Prisma as my GraphQL Server, which provides a scalar Json type. Consider the following schema:

type Query {
  metaObjectType(id:ID!): MetaObjectType
}
type MetaObjectType {
  parentId: String!
  meta: Json!
}

The following query is valid.

query {
  metaObjectType(id:$id) {
    parentId
    meta
  }
}

The following query is invalid, and produces an error: "Field 'meta' of type 'Json' must not have a sub selection."

query {
  metaObjectType(id:$id) {
    parentId
    meta {
      someMetaKey
    }
  }
}

I'd like to define my struct like this:

type MyQuery struct {
  MetaObjectType struct {
    ParentID string
    Meta     json.RawMessage
  } `graphql:"metaObjectType(id:$id)"`
}

However, as reported above, the "no place to unmarshal" error is returned when the response json contains more fields than the provided struct.

My vote is to queries to be specified as json.RawMessage for this use case.

from graphql.

cameronbrunner avatar cameronbrunner commented on July 28, 2024

With the changes from #41:

package main
  
import (
        "context"
        "encoding/json"
        "fmt"
        "io"
        "net/http"
        "net/http/httptest"

        "github.com/shurcooL/graphql"
)

func main() {
        mux := http.NewServeMux()
        mux.HandleFunc("/graphql", func(w http.ResponseWriter, req *http.Request) {
                w.Header().Set("Content-Type", "application/json")
                io.WriteString(w, `{"data": {"viewer": {"login": "gopher", "bio": "The Go gopher.", "meta": {"foo": "bar"}}}}`)
        })
        client := graphql.NewClient("/graphql", &http.Client{Transport: localRoundTripper{handler: mux}})

        var query struct {
                Viewer struct {
                        Login     string
                        Biography string `graphql:"bio"`
                        Meta      json.RawMessage
                }
        }
        err := client.Query(context.Background(), &query, nil)
        fmt.Println("error:", err)
        fmt.Printf("query: %+v\n", query)
        fmt.Printf("raw: %+v\n", string(query.Viewer.Meta))

        // Output:
        // error: <nil>
        // query: {Viewer:{Login:gopher Biography:The Go gopher. Meta:[123 34 102 111 111 34 58 34 98 97 114 34 125]}}
        // raw: {"foo":"bar"}
}

// localRoundTripper is an http.RoundTripper that executes HTTP transactions
// by using handler directly, instead of going over an HTTP connection.
type localRoundTripper struct {
        handler http.Handler
}

func (l localRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
        w := httptest.NewRecorder()
        l.handler.ServeHTTP(w, req)
        return w.Result(), nil
}
cbrunner-mac:graphql cbrunner$ go run cmd/main.go 
error: <nil>
query: {Viewer:{Login:gopher Biography:The Go gopher. Meta:[123 34 102 111 111 34 58 34 98 97 114 34 125]}}
raw: {"foo":"bar"}

from graphql.

dmitshur avatar dmitshur commented on July 28, 2024

Thank you @adamgoose for providing additional information and the reproducible snippet. It has helped a lot, I'm able to understand this issue now. I haven't run into it myself because GitHub API v4 doesn't have a JSON scalar type.

Thanks for working on a PR @cameronbrunner, and sorry about the slow response there. I don't have a lot of bandwidth left to do reviews in this repo unfortunately.

Using json.RawMessage seems reasonable, but I'll want to think if there any other solutions, and then I'll try to find some time for code review. I just wanted to post this update here for now.

from graphql.

cor avatar cor commented on July 28, 2024

Is there a workaround for this? I really need to insert a jsonb into a Hasura database

from graphql.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.