vektah / gqlparser Goto Github PK
View Code? Open in Web Editor NEWA port of the parser from graphql-js into golang
License: MIT License
A port of the parser from graphql-js into golang
License: MIT License
Hello!
I have an input that contains a declared field called number, with an int value. sending a variable with the numerical value triggers the error
trigger:
validator.VariableValues
gqlparser version: 2.4.1
Details:
Error:
*github.com/vektah/gqlparser/v2/gqlerror.Error {err: error nil, Message: "cannot use float64 as Int", Path: github.com/vektah/gqlparser/v2/ast.Path len: 3, cap: 4, [*(*"github.com/vektah/gqlparser/v2/ast.PathElement")(0xc000204a40),*(*"github.com/vektah/gqlparser/v2/ast.PathElement")(0xc000204a50),*(*"github.com/vektah/gqlparser/v2/ast.PathElement")(0xc000204a60)], Locations: []github.com/vektah/gqlparser/v2/gqlerror.Location len: 0, cap: 0, nil, Extensions: map[string]interface {} nil, Rule: ""}
github.com/vektah/gqlparser/v2/ast.Path len: 3, cap: 4, ["variable","vars","number"]
gql:
input insertData{
name:String!
data: data!
lo:[String]!
number:Int
}
input data{
name: String
value: String
}
type Query{
readProviders(input: insertData):[Provider]
}
variable:
{"vars": { "name": "valor de name", "data": {},"lo":["cadena 1","cadena 2"], "number":10 }}
Query:
query($vars:insertData){
readProvidersx(input:$vars) {
_id
name
rif
address
phone1
phone2
email
nameLegal
companyClass
withholdingAgent
}
}
If I have a type like this:
extend type Foo @key(fields: "id") {
id: ID!
}
Then adding a doc comment will fail to parse.
Sample input:
"""
Doc comment
"""
extend type Foo @key(fields: "id") {
id: ID!
}
Expected behavior: parses
Actual behavior:
failed to load schema:schema.graphqls:3: Unexpected BlockString "Doc comment"exit status 1
A possible workaround is available: the following code block parses correctly.
"""
Doc comment
"""
type Foo @key(fields: "id") @extends {
id: ID!
}
It is known that any number in map[string]interface{} would be parsed as float (even though the required field is Int).
https://github.com/vektah/gqlparser/blob/master/validator/vars.go#L31
So is any struct embeded inside the variables.
Can you add a number parser here so that we can continue using CreateOperationContext() function?
We observed that the VariableValues function of the validator and more specifically validateVarType allows to pass variable values of different types than expected in a few cases.
When supplying a variable of type String, the value could be numeric.
mutation ($var: String) {
doSomething(stringField: $var)
}
with variables
{
"var": 1
}
When supplying a variable of type Int/Float, the value could be a string.
mutation ($var: Int) {
doSomething(intField $var)
}
with variables
{
"var": "some string"
}
The most important question here is whether this is intended to be the case, which could very well work if the final value is transformed in a later piece of logic. However, it seemed counterintuitive to allow type mismatch in a function that verifies that types do line up.
As the scalar validation makes heavy use of reflection, based on the variable type declared in the operation, the validator checks against the kind of the provided value and makes sure that for a specific GraphQL scalar type only allows specific value kinds.
This one-sided check already becomes the problem in our case: As numeric values are unmarshalled to be json.Number
values, which are stored as strings underneath, kind
will evaluate to a string for numeric values.
In the validation case for String
variables, numerics will pass the kind check in that way and won't get caught. This implies that we can add another check based on the actual type of the value, to make sure no json.Number
is passed for a String variable. We introduced the following change for String scalar validation:
case "String":
if kind == reflect.String {
if val.Type().String() == "json.Number" {
return gqlerror.ErrorPathf(v.path, "cannot use number as String")
}
return nil
}
When validating the built-in numeric scalars (Int and Float), we naturally allow values with the kind String
(for the reason that json.Number
values are essentially Strings), but don't prevent "regular" String values from being supplied. For this case, we've added the following check:
case "String":
if kind == reflect.String {
if val.Type().String() == "json.Number" {
return gqlerror.ErrorPathf(v.path, "cannot use number as String")
}
return nil
}
Depending on the outcome of the question whether this is intended or not, I'd like to contribute a fix (could be the one above, or a different one with the same outcome).
The 2021 GraphQL spec introduced intermediate interface which the parser does not currently support.
Spec PR: graphql/graphql-spec#373
Reference PR: graphql/graphql-js#2084
Found that introspection returns empty descriptions for standard types. Not a big issue, but I found it curios why. Found that gqlparser/validator/prelude.graphql uses comments instead of description.
Currently:
# The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1.
scalar Int
# The `Float` scalar type represents signed double-precision fractional values as specified by [IEEE 754](http://en.wikipedia.org/wiki/IEEE_floating_point).
scalar Float
# The `String`scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text.
scalar String
Should be:
"The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1."
scalar Int
"The `Float` scalar type represents signed double-precision fractional values as specified by [IEEE 754](http://en.wikipedia.org/wiki/IEEE_floating_point)."
scalar Float
"The `String`scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text."
scalar String
See: https://facebook.github.io/graphql/June2018/#Description
Hello,
Just by updating from v2.1.0
to v2.2.0
I noticed in my generated code I have now a new resolver:
__DirectiveResolver
I guess it's linked to: graphql/graphql-spec#510
I don't now if it's a bug, or if I have to implement something :)
type ResolverRoot interface {
// ...
__Directive() __DirectiveResolver
}
type __DirectiveResolver interface {
IsRepeatable(ctx context.Context, obj *introspection.Directive) (bool, error)
}
Hello!
I have a memory issue while using gqlgen websocket transport. I measured memory using pprof and it seems there's a memory leak in gqlparser's code. Here's a dump https://gist.github.com/fletcherist/94f0bb3bc7b09ec5177fccd6cdf4d2d5
Also attaching some screenshots which points to gqlparser
Issue Example:
```{"operationName":null,"variables":{"storeID":2018,"data":{"name":"Demo","uuid":null,"treeDisplayType":"TREE","modelTree":[{"type":"NORMAL","level":1,"__typename":"ModuleModelTree"},{"level":2,"type":"NORMAL"},{"level":3,"type":"NORMAL"},{"level":4,"type":"NORMAL"},{"level":5,"type":"NORMAL"}],"modelID":250}},"query":"mutation ($storeID: Int, $data: UpdateModuleModelInput!) {
updateModuleModel(storeID: $storeID, input: $data) {
id
name
type
uuid
storeID
treeDisplayType
modelTree {
level
type
__typename
}
__typename
}
}
"}
How to Fix:
maybe we need skip __typename on variable validation.
We're excited to start using #148 among other things. If a maintainer has time, would it be possible to tag a new release? (Or if there's anything others can do to help make that easier, I or my coworkers may have some time to help.)
Right now the gqlparser v2.2.0 has a bug that has been fixed in master. This fix will let the deprecated
directive to work in gqlgen. Wondering if there is anything we can do to cut a new version so gqlgen can update gqlparser version with fix?
The following code doesn't give any errors, while it should have:
package main
import (
"fmt"
"github.com/vektah/gqlparser/v2/ast"
"github.com/vektah/gqlparser/v2/parser"
"github.com/vektah/gqlparser/v2/validator"
)
func main() {
schema := `
directive @test on OBJECT
type T1 @test {
f: String
}
type T2 {
f: String
}
union U @test = T1 | T2
input I1 @test {
f: String
}
interface I2 @test {
f: String
}
`
doc, err := parser.ParseSchemas(validator.Prelude, &ast.Source{Input: schema})
if err != nil {
panic(err)
}
_, err = validator.ValidateSchemaDocument(doc)
if err != nil {
panic(err)
}
fmt.Println("Oops! got a bug :(")
}
The directive @test
is defined to be applicable only on an OBJECT
type, but it doesn't give any error when applied on union, input, interface, or any other types.
Try it on The Go Playground.
Maybe related to #107?
Having one big long string literal in validator/prelude.go is a bit problematic. Foremostly it makes it hard to see what changes have been made in git history or blame. (I was trying to check if/when description: String
field has been added to type __Schema
.)
Is there any reason not to have it extend over multiple lines? (String literals joined with the + operator are combined into one literal at compile time, I believe.)
Perhaps even better would be to embed it (//go:embed), since go.mod is already at Go 1.16. (File embedding was added in 1.16.)
https://github.com/vektah/gqlparser/blob/master/lexer/lexer.go#L124-L125
The lexer does not return a comment token.
How can I get comment tokens from the lexer?
In gqlparser all methods which are returning an error are using the explicit struct type (e.g. *gqlerror.Error
or gqlerror.List
).
As long as you use the explicit types everything is fine, but as soon as you convert them to the error
interface type, nil checks will fail.
See the golang FAQ for information why the checks fail.
https://golang.org/doc/faq#nil_error
read.go
func ReadSchema(dir string) (*ast.Schema, error) {
var files []*ast.Source
// ... read files, may return io errors ...
// Here the returned *gqlerror.Error gets converted to the error return type.
return gqlparser.LoadSchema(files...)
}
The ReadSchema function may return io errors and graphql errors. Because of this I can't use *gqlerror.Error
as return type. When testing this I noticed that my nil checks failed.
read_test.go
func TestReadSchema(t *testing.T) {
schema, err := readSchema(schemaTestDir)
// This check always fails
assert.Assert(t, err == nil)
// A workaround is to convert the error back to its struct type.
// When handling multiple error types this quickly becomes impractical.
assert.Assert(t, err.(*gqlerror.Error) == nil)
}
It's kind of strange that gqlparser returns errors as struct types. I've never seen anywhere else. All other go packages (including the internal ones) use the error
interface type.
I think this should be changed so all methods use the error
interface when returning errors.
I'm trying to implement OverlappingFieldsCanBeMerged validator in here.
but I got some issues.
observers.OnFragmentLeave
, but walkSelection(parentDef *ast.Definition, it ast.Selection)
and any other walker method using call by value.
type SelectionSet []Selection
โ type SelectionSet []*Selection
func (Field) isSelection() {}
โ func (*Field) isSelection() {}
As a reasonable solution, I think that setting all the definitions before calling visitor. ๐ค
However, I recommend using more pointers.
graphql-js
has some utilities specified here: https://graphql.org/graphql-js/utilities/
It would be very nice for gqlparser
also to support those utilities.
For example: something like buildClientSchema
is very useful if you want to just re-create ast.Schema
from introspection response of a server.
We have been using gqlgen-v0.9.2
since a year, and now we are updating it to latest version. Straight forward I updated all the dependencies. But still after 2 days of efforts, I am getting errors.
Getting error message
vendor/github.com/99designs/gqlgen/graphql/context_field.go:7:2: cannot find package "github.com/vektah/gqlparser/v2/ast" in any of:
gqlgen version: 0.12.2
I have the following mutation:
extend type Mutation{
createProject(clientMutationId: String, input: ProjectDraft!): ProjectOperationResponse!
}
input ProjectDraft {
test: Boolean! = true
name: String!
}
When I call it with the query:
mutation($projectDraft: ProjectDraft!) {
createProject(input: $projectDraft) {
...
}
}
And the variables:
{
"projectDraft": {
"name": "Toto"
}
}
=> I receive the must be defined
error on the field test
, even if there is a default value (true).
But I don't get any error when I call my mutation without variables:
mutation($projectDraft: ProjectDraft!) {
createProject(input: {name: "toto"}) {
...
}
}
It appears that the default values โโof the input field definitions are not checked to determine whether a not null field is valid or not.
Hi @vektah
thanks for writing awesome library, but if possible can have some document to use the lib
Best regards,
Toan
Hi. have found endless recursion in case of incorrect graphql request. is there a way to prohibit that?
request:
query Streams {
Streams {
...StreamFragment
}
}
fragment StreamFragment on Stream {
ID
Streams {
...StreamFragment
Streams {
...StreamFragment
Streams {
...StreamFragment
}
}
}
}
schema:
type Stream
ID: ID!
Streams: [Stream]
}
stack trace
runtime: goroutine stack exceeds 1000000000-byte limit
runtime: sp=0xc033200400 stack=[0xc033200000, 0xc053200000]
fatal error: stack overflow
runtime stack:
runtime.throw({0xddc55b, 0x147ad20})
/usr/local/go/src/runtime/panic.go:1198 +0x71
runtime.newstack()
/usr/local/go/src/runtime/stack.go:1088 +0x5ac
runtime.morestack()
/usr/local/go/src/runtime/asm_amd64.s:461 +0x8b
goroutine 8 [running]:
runtime.heapBitsSetType(0xc05358ee50, 0x10, 0x10, 0xcb1b20)
/usr/local/go/src/runtime/mbitmap.go:822 +0xbcc fp=0xc033200410 sp=0xc033200408 pc=0x415a0c
runtime.mallocgc(0x10, 0xcb1b20, 0x1)
/usr/local/go/src/runtime/malloc.go:1100 +0x65e fp=0xc033200490 sp=0xc033200410 pc=0x40ccbe
runtime.growslice(0xcb1b20, {0x0, 0xc000020bc9, 0x2}, 0x30)
/usr/local/go/src/runtime/slice.go:267 +0x4ea fp=0xc0332004f8 sp=0xc033200490 pc=0x44b1aa
github.com/vektah/gqlparser/v2/validator/rules.(*sequentialFieldsMap).Push(...)
/go/pkg/mod/github.com/vektah/gqlparser/[email protected]/validator/rules/overlapping_fields_can_be_merged.go:160
github.com/vektah/gqlparser/v2/validator/rules.getFieldsAndFragmentNames.func1({0xc00038adc0, 0x3, 0xd51740})
/go/pkg/mod/github.com/vektah/gqlparser/[email protected]/validator/rules/overlapping_fields_can_be_merged.go:544 +0x165 fp=0xc0332005b0 sp=0xc0332004f8 pc=0xbbd5c5
github.com/vektah/gqlparser/v2/validator/rules.getFieldsAndFragmentNames({0xc00038adc0, 0x3, 0x4})
/go/pkg/mod/github.com/vektah/gqlparser/[email protected]/validator/rules/overlapping_fields_can_be_merged.go:554 +0xea fp=0xc033200620 sp=0xc0332005b0 pc=0xbbd40a
github.com/vektah/gqlparser/v2/validator/rules.(*overlappingFieldsCanBeMergedManager).collectConflictsBetweenFieldsAndFragment(0xc0001ab038, 0xc05a8d8678, 0x2, 0x100000000000000, 0xc00038ac>
/go/pkg/mod/github.com/vektah/gqlparser/[email protected]/validator/rules/overlapping_fields_can_be_merged.go:282 +0xaa fp=0xc033200698 sp=0xc033200620 pc=0xbbbd2a
github.com/vektah/gqlparser/v2/validator/rules.(*overlappingFieldsCanBeMergedManager).findConflictsBetweenSubSelectionSets(0xc0001ab038, 0x0, {0xc000386c60, 0x1, 0x1}, {0xc00006a220, 0x2, 0>
/go/pkg/mod/github.com/vektah/gqlparser/[email protected]/validator/rules/overlapping_fields_can_be_merged.go:360 +0x125 fp=0xc033200738 sp=0xc033200698 pc=0xbbc2c5
github.com/vektah/gqlparser/v2/validator/rules.(*overlappingFieldsCanBeMergedManager).findConflict(0xc0001ab038, 0xfe, 0xc000205e80, 0xc000205e00)
/go/pkg/mod/github.com/vektah/gqlparser/[email protected]/validator/rules/overlapping_fields_can_be_merged.go:465 +0x4b5 fp=0xc0332007e8 sp=0xc033200738 pc=0xbbce15
github.com/vektah/gqlparser/v2/validator/rules.(*overlappingFieldsCanBeMergedManager).collectConflictsBetween(0xc00006a260, 0xc05a8d8660, 0x2, 0x10000000048a9ba, 0xc026dcdb80)
/go/pkg/mod/github.com/vektah/gqlparser/[email protected]/validator/rules/overlapping_fields_can_be_merged.go:407 +0x179 fp=0xc0332008a8 sp=0xc0332007e8 pc=0xbbc879
github.com/vektah/gqlparser/v2/validator/rules.(*overlappingFieldsCanBeMergedManager).findConflictsBetweenSubSelectionSets(0xc0001ab038, 0x0, {0xc00006a220, 0x2, 0x2}, {0xc00006a260, 0x2, 0>
/go/pkg/mod/github.com/vektah/gqlparser/[email protected]/validator/rules/overlapping_fields_can_be_merged.go:354 +0xfd fp=0xc033200948 sp=0xc0332008a8 pc=0xbbc29d
github.com/vektah/gqlparser/v2/validator/rules.(*overlappingFieldsCanBeMergedManager).findConflict(0xc0001ab038, 0x0, 0xc000205e00, 0xc000205d80)
/go/pkg/mod/github.com/vektah/gqlparser/[email protected]/validator/rules/overlapping_fields_can_be_merged.go:465 +0x4b5 fp=0xc0332009f8 sp=0xc033200948 pc=0xbbce15
github.com/vektah/gqlparser/v2/validator/rules.(*overlappingFieldsCanBeMergedManager).collectConflictsBetween(0xd1d720, 0xc05a8d8648, 0x20, 0xc026dcdac0, 0xc026dcdac0)
/go/pkg/mod/github.com/vektah/gqlparser/[email protected]/validator/rules/overlapping_fields_can_be_merged.go:407 +0x179 fp=0xc033200ab8 sp=0xc0332009f8 pc=0xbbc879
github.com/vektah/gqlparser/v2/validator/rules.(*overlappingFieldsCanBeMergedManager).collectConflictsBetweenFieldsAndFragment(0xc0001ab038, 0xc05a8d8648, 0x2, 0x10000000048a9ba, 0xc00038ad>
/go/pkg/mod/github.com/vektah/gqlparser/[email protected]/validator/rules/overlapping_fields_can_be_merged.go:291 +0xf2 fp=0xc033200b30 sp=0xc033200ab8 pc=0xbbbd72
github.com/vektah/gqlparser/v2/validator/rules.(*overlappingFieldsCanBeMergedManager).findConflictsBetweenSubSelectionSets(0xc0001ab038, 0x0, {0xc000386c60, 0x1, 0x1}, {0xc00006a260, 0x2, 0>
/go/pkg/mod/github.com/vektah/gqlparser/[email protected]/validator/rules/overlapping_fields_can_be_merged.go:367 +0x197 fp=0xc033200bd0 sp=0xc033200b30 pc=0xbbc337
github.com/vektah/gqlparser/v2/validator/rules.(*overlappingFieldsCanBeMergedManager).findConflict(0xc0001ab038, 0x0, 0xc000205e80, 0xc000205d80)
/go/pkg/mod/github.com/vektah/gqlparser/[email protected]/validator/rules/overlapping_fields_can_be_merged.go:465 +0x4b5 fp=0xc033200c80 sp=0xc033200bd0 pc=0xbbce15
github.com/vektah/gqlparser/v2/validator/rules.(*overlappingFieldsCanBeMergedManager).collectConflictsBetween(0xd1d720, 0xc05a8d8630, 0x20, 0xc026dcd9a0, 0xc026dcd9a0)
/go/pkg/mod/github.com/vektah/gqlparser/[email protected]/validator/rules/overlapping_fields_can_be_merged.go:407 +0x179 fp=0xc033200d40 sp=0xc033200c80 pc=0xbbc879
github.com/vektah/gqlparser/v2/validator/rules.(*overlappingFieldsCanBeMergedManager).collectConflictsBetweenFieldsAndFragment(0xc0001ab038, 0xc05a8d8630, 0x2, 0x100000000000000, 0xc00038ad>
/go/pkg/mod/github.com/vektah/gqlparser/[email protected]/validator/rules/overlapping_fields_can_be_merged.go:291 +0xf2 fp=0xc033200db8 sp=0xc033200d40 pc=0xbbbd72
github.com/vektah/gqlparser/v2/validator/rules.(*overlappingFieldsCanBeMergedManager).findConflictsBetweenSubSelectionSets(0xc0001ab038, 0x0, {0xc000386c60, 0x1, 0x1}, {0xc00006a220, 0x2, 0>
/go/pkg/mod/github.com/vektah/gqlparser/[email protected]/validator/rules/overlapping_fields_can_be_merged.go:367 +0x197 fp=0xc033200e58 sp=0xc033200db8 pc=0xbbc337
github.com/vektah/gqlparser/v2/validator/rules.(*overlappingFieldsCanBeMergedManager).findConflict(0xc0001ab038, 0xfe, 0xc000205e80, 0xc000205e00)
/go/pkg/mod/github.com/vektah/gqlparser/[email protected]/validator/rules/overlapping_fields_can_be_merged.go:465 +0x4b5 fp=0xc033200f08 sp=0xc033200e58 pc=0xbbce15
The error has caused on master branch (7e475a7)
I used gqlparser.LoadSchema
and use GitHub public schema to reproduce this error. expected INPUT_FIELD_DEFINITION
directive @possibleTypes(
abstractType: String
concreteTypes: [String!]!
) on INPUT_FIELD_DEFINITION
input AcceptEnterpriseAdministratorInvitationInput {
clientMutationId: String
invitationId: ID! @possibleTypes(concreteTypes: ["EnterpriseAdministratorInvitation"])
}
type Query {
id: ID!
}
type Mutation {
hello(input: AcceptEnterpriseAdministratorInvitationInput): ID!
}
We have a custom scalar type and want to add input validation for it.
As of now, there is no hook provided for it. We have to either fork and modify the library or write the validation in our own code.
It would be better if we can add custom validation rules as we do for events like on operation
, onField,
etc in walk.go
.
receive an graphQLError result object
panic is thrown.
http: panic serving [::1]:64085: runtime error: invalid memory address or nil pointer dereference
goroutine 4285 [running]:
net/http.(*conn).serve.func1(0xc4206c8000)
/usr/local/Cellar/go/1.10.3/libexec/src/net/http/server.go:1726 +0xd0
panic(0x1607600, 0x1beac80)
/usr/local/Cellar/go/1.10.3/libexec/src/runtime/panic.go:502 +0x229
github.rakops.com/prospecting/prospr-api/vendor/github.com/vektah/gqlparser/validator/rules.(*overlappingFieldsCanBeMergedManager).findConflict(0xc420468300, 0xc42088ea00, 0xc4202a8300, 0xc4202a8400, 0xc4200e8608)
/Users/jonlundy/Documents/go/src/github.rakops.com/prospecting/prospr-api/vendor/github.com/vektah/gqlparser/validator/rules/overlapping_fields_can_be_merged.go:419 +0x73a
github.rakops.com/prospecting/prospr-api/vendor/github.com/vektah/gqlparser/validator/rules.(*overlappingFieldsCanBeMergedManager).collectConflictsBetween(0xc420468300, 0xc420aa9528, 0x1628e00, 0xc420468660, 0xc4204686e0)
/Users/jonlundy/Documents/go/src/github.rakops.com/prospecting/prospr-api/vendor/github.com/vektah/gqlparser/validator/rules/overlapping_fields_can_be_merged.go:403 +0xc4
github.rakops.com/prospecting/prospr-api/vendor/github.com/vektah/gqlparser/validator/rules.(*overlappingFieldsCanBeMergedManager).collectConflictsBetweenFieldsAndFragment(0xc420468300, 0xc420aa9528, 0xc420468600, 0xc420468660, 0xc420520980)
/Users/jonlundy/Documents/go/src/github.rakops.com/prospecting/prospr-api/vendor/github.com/vektah/gqlparser/validator/rules/overlapping_fields_can_be_merged.go:291 +0x160
github.rakops.com/prospecting/prospr-api/vendor/github.com/vektah/gqlparser/validator/rules.(*overlappingFieldsCanBeMergedManager).findConflictsWithinSelectionSet(0xc420468300, 0xc420468220, 0x2, 0x2, 0xc42088e3f0, 0xc420a50050, 0xc42088ea20)
/Users/jonlundy/Documents/go/src/github.rakops.com/prospecting/prospr-api/vendor/github.com/vektah/gqlparser/validator/rules/overlapping_fields_can_be_merged.go:258 +0x1b2
github.rakops.com/prospecting/prospr-api/vendor/github.com/vektah/gqlparser/validator/rules.init.11.func1.2(0xc420520bc0, 0xc4202a8280)
/Users/jonlundy/Documents/go/src/github.rakops.com/prospecting/prospr-api/vendor/github.com/vektah/gqlparser/validator/rules/overlapping_fields_can_be_merged.go:87 +0x7c
github.rakops.com/prospecting/prospr-api/vendor/github.com/vektah/gqlparser/validator.(*Walker).walkSelection(0xc420520bc0, 0xc4201bc8f0, 0x172ee40, 0xc4202a8280)
/Users/jonlundy/Documents/go/src/github.rakops.com/prospecting/prospr-api/vendor/github.com/vektah/gqlparser/validator/walk.go:243 +0x26a
github.rakops.com/prospecting/prospr-api/vendor/github.com/vektah/gqlparser/validator.(*Walker).walkSelectionSet(0xc420520bc0, 0xc4201bc8f0, 0xc4207af620, 0x1, 0x1)
/Users/jonlundy/Documents/go/src/github.rakops.com/prospecting/prospr-api/vendor/github.com/vektah/gqlparser/validator/walk.go:205 +0x59
github.rakops.com/prospecting/prospr-api/vendor/github.com/vektah/gqlparser/validator.(*Walker).walkOperation(0xc420520bc0, 0xc42066a3f0)
/Users/jonlundy/Documents/go/src/github.rakops.com/prospecting/prospr-api/vendor/github.com/vektah/gqlparser/validator/walk.go:110 +0x2d7
github.rakops.com/prospecting/prospr-api/vendor/github.com/vektah/gqlparser/validator.(*Walker).walk(0xc420520bc0)
/Users/jonlundy/Documents/go/src/github.rakops.com/prospecting/prospr-api/vendor/github.com/vektah/gqlparser/validator/walk.go:69 +0x52
github.rakops.com/prospecting/prospr-api/vendor/github.com/vektah/gqlparser/validator.Walk(0xc4201cdec0, 0xc420520840, 0xc42035e0c0)
/Users/jonlundy/Documents/go/src/github.rakops.com/prospecting/prospr-api/vendor/github.com/vektah/gqlparser/validator/walk.go:53 +0xa6
github.rakops.com/prospecting/prospr-api/vendor/github.com/vektah/gqlparser/validator.Validate(0xc4201cdec0, 0xc420520840, 0x0, 0x16bd5aa, 0xc)
/Users/jonlundy/Documents/go/src/github.rakops.com/prospecting/prospr-api/vendor/github.com/vektah/gqlparser/validator/validator.go:42 +0x181
github.rakops.com/prospecting/prospr-api/vendor/github.com/vektah/gqlparser.LoadQuery(0xc4201cdec0, 0xc4206ad880, 0x314, 0x16c00e2, 0x10, 0x0, 0x168b9c0)
/Users/jonlundy/Documents/go/src/github.rakops.com/prospecting/prospr-api/vendor/github.com/vektah/gqlparser/gqlparser.go:28 +0xe7
github.rakops.com/prospecting/prospr-api/vendor/github.com/99designs/gqlgen/handler.GraphQL.func1(0x1731c80, 0xc420232460, 0xc420136700)
/Users/jonlundy/Documents/go/src/github.rakops.com/prospecting/prospr-api/vendor/github.com/99designs/gqlgen/handler/graphql.go:160 +0x267
net/http.HandlerFunc.ServeHTTP(0xc4204681c0, 0x1731c80, 0xc420232460, 0xc420136700)
/usr/local/Cellar/go/1.10.3/libexec/src/net/http/server.go:1947 +0x44
net/http.StripPrefix.func1(0x1731c80, 0xc420232460, 0xc420136600)
/usr/local/Cellar/go/1.10.3/libexec/src/net/http/server.go:1986 +0x19a
net/http.HandlerFunc.ServeHTTP(0xc42088e360, 0x1731c80, 0xc420232460, 0xc420136600)
/usr/local/Cellar/go/1.10.3/libexec/src/net/http/server.go:1947 +0x44
github.rakops.com/prospecting/prospr-api/internal/routes.getQuery(0x1731c80, 0xc420232460, 0xc420520500, 0xc420136600, 0x1734860, 0xc42088e300)
/Users/jonlundy/Documents/go/src/github.rakops.com/prospecting/prospr-api/internal/routes/graphql.go:37 +0x1cc
github.rakops.com/prospecting/prospr-api/vendor/sour.is/x/toolbox/httpsrv.HandlerFunc.ServeHTTP(0x16e2bc8, 0x1731c80, 0xc420232460, 0xc420520500, 0xc420136500, 0x1734860, 0xc42088e300)
/Users/jonlundy/Documents/go/src/github.rakops.com/prospecting/prospr-api/vendor/sour.is/x/toolbox/httpsrv/routes_ident.go:33 +0x173
github.rakops.com/prospecting/prospr-api/vendor/sour.is/x/toolbox/httpsrv.identWrapper.func1(0x1731c80, 0xc420232460, 0xc420136500)
/Users/jonlundy/Documents/go/src/github.rakops.com/prospecting/prospr-api/vendor/sour.is/x/toolbox/httpsrv/wrappers.go:23 +0x484
net/http.HandlerFunc.ServeHTTP(0xc4203009a0, 0x1731c80, 0xc420232460, 0xc420136500)
/usr/local/Cellar/go/1.10.3/libexec/src/net/http/server.go:1947 +0x44
github.rakops.com/prospecting/prospr-api/vendor/github.com/gorilla/mux.(*Router).ServeHTTP(0xc42020ecb0, 0x1731c80, 0xc420232460, 0xc420136500)
/Users/jonlundy/Documents/go/src/github.rakops.com/prospecting/prospr-api/vendor/github.com/gorilla/mux/mux.go:162 +0xed
net/http.serverHandler.ServeHTTP(0xc4202091e0, 0x1731c80, 0xc420232460, 0xc420596100)
/usr/local/Cellar/go/1.10.3/libexec/src/net/http/server.go:2694 +0xbc
net/http.(*conn).serve(0xc4206c8000, 0x1732180, 0xc4201c6040)
/usr/local/Cellar/go/1.10.3/libexec/src/net/http/server.go:1830 +0x651
created by net/http.(*Server).Serve
/usr/local/Cellar/go/1.10.3/libexec/src/net/http/server.go:2795 +0x27b
query panic{
panic{
...PanicInput
__typename
}
}
fragment PanicInput on Panic {
__typename
}
This was filed over under 99designs/gqlgen#290 but probably fits here better as it originates from the parser.
Hello,
I use Bazel Gazelle to generate BUILD files. It seems Bazel cannot load vektah gqlparser. But I don't have no more ideas how to look into this issue. Maybe the repository isn't compatible because of this "v2" sub folder?
no such package '@com_github_vektah_gqlparser_v2//ast': The repository '@com_github_vektah_gqlparser_v2' could not be resolved and referenced by '//src/graph/generated:generated'
Thank you for your help!
require (
github.com/99designs/gqlgen v0.13.0 // indirect
github.com/vektah/gqlparser/v2 v2.1.0 // indirect
)
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "generated",
srcs = ["generated.go"],
importpath = "src/graph/generated",
visibility = ["//visibility:public"],
deps = [
"//src/graph/model",
"@com_github_99designs_gqlgen//graphql:go_default_library",
"@com_github_99designs_gqlgen//graphql/introspection:go_default_library",
"@com_github_vektah_gqlparser_v2//:go_default_library",
"@com_github_vektah_gqlparser_v2//ast:go_default_library",
],
)
Looks like the tests exported from the graphql-js repo are very out of date. I looked through the history of the graphql-js repo and it looks like the package.json in validator/imported/package.json file comes from https://github.com/graphql/graphql-js/blob/68577079930e24da9c25b6c3f8fcadd488d94014/package.json. Trying to update the tests with ./export.sh
doesn't work any more. The first problem seems related to babel, but there might be a lot more broken things here. I'm curious to know how much the two repos have diverged, so I'd like to get these tests updated. Any tips would be appreciated.
apollo-client & apollo-server has a new feature that recognize error code by reading extensions.code
from graphql error response. Also, in graphql spec, it allows extensions
with code
field. Current gqlerror
only allows to set file
as a field of extension map. Can we set any arbitrary field on it?
Would like a method to generate the string representation of an AST object that could be directly used in a query. For example, if had a Field that was generated from
object(id:$id){ id name value subobject(index:9){ id name }}
would like to be able to call something like
ast.String(field)
to return an equivalent string.
I wrote a utility function to do this in my own project, but it is specific to ast.Field
and doubt it covers all possible definitions:
func fieldQueryString(field *ast.Field) string {
query := field.Name
if len(field.Arguments) > 0 {
query += "("
for _, arg := range field.Arguments {
query += arg.Name + ":"
query += field.Arguments.ForName(arg.Name).Value.String()
}
query += ")"
}
if len(field.SelectionSet) > 0 {
query += "{"
for _, f := range field.SelectionSet {
field := f.(*ast.Field)
query += fieldQueryString(field) + ","
}
query += "}"
}
return query
}
I think this would be generally useful for logging/debugging.
Apologies if this already exists, please point to where it is found if exists.
I am new to graphql but I think adding a nullable embedded input type should not break the tests since it is nullable and not required but instead it is checking for the required fields inside the nullable input type.
// vars.graphql
type Query {
optionalIntArg(i: Int): Boolean!
intArg(i: Int!): Boolean!
stringArg(i: String): Boolean!
boolArg(i: Boolean!): Boolean!
floatArg(i: Float!): Boolean!
idArg(i: ID!): Boolean!
scalarArg(i: Custom!): Boolean!
structArg(i: InputType!): Boolean!
defaultStructArg(i: InputType! = { name: "foo" }): Boolean!
arrayArg(i: [InputType!]): Boolean!
}
input InputType {
embedded: Embedded
name: String!
nullName: String
}
input Embedded {
name: String!
}
scalar Custom
--- FAIL: TestValidateVars (0.00s)
--- FAIL: TestValidateVars/input_object (0.00s)
--- FAIL: TestValidateVars/input_object/null_required_field (0.00s)
/Users/cbelsole/go/src/github.com/vektah/gqlparser/validator/vars_test.go:103:
Error Trace: vars_test.go:103
Error: Error message not equal:
expected: "input: variable.var.name cannot be null"
actual : "input: variable.var.embedded.name cannot be null"
Test: TestValidateVars/input_object/null_required_field
Hi there,
this might be related to #107 but I figured it would be better to open a new issue as it's related to field arguments.
The following query will raise an error as expected:
{
country(code: "DE") {
name
}
country(code: "US") {
name
}
}
panic: input:6: Fields "country" conflict because they have differing arguments. Use different aliases on the fields to fetch both if this was intentional.
Whereas the same query with nested arguments will not:
{
countryWhere(where: {code: "DE"}) {
name
}
countryWhere(where: {code: "US"}) {
name
}
}
Full test case:
package main
import (
"fmt"
"github.com/vektah/gqlparser"
"github.com/vektah/gqlparser/ast"
)
func main() {
typedef := `
type Country {
name: String
}
type Query {
country(code: String): Country
countryWhere(where: CountryWhereUniqueInput!): Country
}
input CountryWhereUniqueInput {
code: String
}
`
// query := `
// {
// country(code: "DE") {
// name
// }
// country(code: "US") {
// name
// }
// }
// `
query := `
{
countryWhere(where: {code: "DE"}) {
name
}
countryWhere(where: {code: "US"}) {
name
}
}
`
schema, schemaErr := gqlparser.LoadSchema(&ast.Source{
Input: typedef,
})
if schemaErr != nil {
panic(schemaErr)
}
doc, queryErr := gqlparser.LoadQuery(schema, query)
if queryErr != nil {
panic(queryErr)
}
fmt.Println(schema, doc)
}
Is this issue of the same origin as #107 or a different beast?
Thanks for the all the great work with gqlparser!
schema.graphql
type Query {
x (y: Int = 100): Int
}
When requesting query without setting variables,
query ($y: Int) {
x(y: $y)
}
# curl 'http://localhost:4000/' -H 'content-type: application/json' --data-binary '{"operationName":null,"variables":{},"query":"query ($y: Int) {\n x(y: $y)\n}\n"}' --compressed
y
should be set as 100
(default value), but actually it was set as 0
.
I am not sure that it is specified in the official spec, but the gqlgen's old parser and apollo set it to 100
.
Upgrading from github.com/vektah/gqlparser/v2 v2.1.0
to github.com/vektah/gqlparser/v2 v2.2.0
with the same generated ([email protected]
) code and all the same files I get a monster error:
runtime error: invalid memory address or nil pointer dereference
.
After a long time of debugging I realized the problem is here:
func (f *Field) ArgumentMap(vars map[string]interface{}) map[string]interface{} {
return arg2map(f.Definition.Arguments, f.Arguments, vars)
}
f.Definition
here is nil
with v2.2.0
, not with 2.1.0
! Why?
How to fix this?
query is
source := `{
a:list(size: 2) {
list(size: 5) {
list(size: 15) {
scalar
}
}
}
b:list(size: 6) {
list(size: 3) {
scalar
}
}
}`
query := gqlparser.MustLoadQuery(schema, source)
for _, selection := range query.Operations[0].SelectionSet {
}
Any way to get sub query a and b separately in the for range loop?
Using Go 1.13 and Go modules, looks like the package formatter
is not available, and in effect it's not available in the tagged v1.1.2
. I don't know whether or not it supposed to be this way, but for coherence, maybe it's worth to cut another release that would include the formatter, so that the behavior is the same when using GOPATH mode and Go modules.
Line 316 in 6f09700
Note that this line calls the function we are in, parseTypeReference
. I'll try to
I am getting a great many errors like this as I try to write a schema. I cant seem to construct a small test case, but if I find one I'll update this ticket.
$ gqlgen init
runtime: goroutine stack exceeds 1000000000-byte limit
fatal error: stack overflow
runtime stack:
runtime.throw(0x13409f2, 0xe)
/Users/iansmith/go1.10.3.src/go/src/runtime/panic.go:616 +0x81
runtime.newstack()
/Users/iansmith/go1.10.3.src/go/src/runtime/stack.go:1054 +0x71f
runtime.morestack()
/Users/iansmith/go1.10.3.src/go/src/runtime/asm_amd64.s:480 +0x89
goroutine 1 [running]:
runtime.heapBitsSetType(0xc42eef6db0, 0x30, 0x28, 0x1308b40)
/Users/iansmith/go1.10.3.src/go/src/runtime/mbitmap.go:864 +0x61c fp=0xc440200358 sp=0xc440200350 pc=0x10128bc
runtime.mallocgc(0x30, 0x1308b40, 0x1, 0x0)
/Users/iansmith/go1.10.3.src/go/src/runtime/malloc.go:740 +0x548 fp=0xc4402003f8 sp=0xc440200358 pc=0x100f928
runtime.newobject(0x1308b40, 0x2d)
/Users/iansmith/go1.10.3.src/go/src/runtime/malloc.go:839 +0x38 fp=0xc440200428 sp=0xc4402003f8 pc=0x100ff28
github.com/vektah/gqlparser/parser.(*parser).parseTypeReference(0xc4201a7c70, 0x0)
/Users/iansmith/graphql.src/graphiql/src/github.com/vektah/gqlparser/parser/query.go:312 +0x31 fp=0xc440200490 sp=0xc440200428 pc=0x1213051
...
github.com/vektah/gqlparser/parser.(*parser).parseTypeReference(0xc4201a7c70, 0x0)
/Users/iansmith/graphql.src/graphiql/src/github.com/vektah/gqlparser/parser/query.go:316 +0x9b fp=0xc440202b28 sp=0xc440202ac0 pc=0x12130bb
github.com/vektah/gqlparser/parser.(*parser).parseTypeReference(0xc4201a7c70, 0x0)
/Users/iansmith/graphql.src/graphiql/src/github.com/vektah/gqlparser/parser/query.go:316 +0x9b fp=0xc440202b90 sp=0xc440202b28 pc=0x12130bb
...additional frames elided...
Have you ever consider write some methods to customer design doc? For example, there is a query doc:
doc, _ := gqlparser.LoadQuery(parsedSchema, "mutation($text: String!, $userId: String!) {createTodo(input: {text: $text, userId: $userId}) {id}}")
we can customer design and change the doc ( remove or and some selection, remove or add some arguments), something like:
addArguments(doc, "key"), then the doc will be:
var buf bytes.Buffer
formatter.NewFormatter(&buf).FormatQueryDocument(doc)
fmt.Println(buf.String())
output:
mutation($text: String!, $userId: String!, $key: String!) {createTodo(input: {text: $text, userId: $userId, key: $key}) {id}}"
As titled. GraphQL has a great API for that https://graphql.org/graphql-js/language/#visit
This is in accordance with the principles of this library.
close to reference: Where it doesn't impact on the above, it should stay close to the graphql/graphql-js reference implementation.
https://github.com/dgraph-io/gqlparser has been maintaining their own fork of the parser, and they have made a number of improvements. I would like to upstream these. I have pushed their current commits to a branch https://github.com/vektah/gqlparser/compare/dgraph-master?expand=1 in case their current difficulties cause their repository to become unavailable for any reason.
Hi,
As specified in graphql spec, introspection queries can be like:
__schema: __Schema!
__type(name: String!): __Type
i.e., argument name
for __type
is non-null while the field definition for __type
can be null.
The same can also be verified in graphql-js implementation here.
In the current implementation of this library,
Lines 156 to 162 in a7a59ec
the name
argument is defined to be nullable, while the filed definition for type
is defined to be non-null.
I think this should be corrected.
I've got this error, don't know what's going on
Using the latest gqlparser and gqlparser.
goroutine 209 [running]:
runtime/debug.Stack()
/usr/lib/go/src/runtime/debug/stack.go:24 +0x65
runtime/debug.PrintStack()
/usr/lib/go/src/runtime/debug/stack.go:16 +0x19
github.com/99designs/gqlgen/graphql.DefaultRecover({0xc0001226c0?, 0x0?}, {0x1052760?, 0xc00059f410?})
/home/micro/.go/pkg/mod/github.com/99designs/[email protected]/graphql/recovery.go:17 +0x71
github.com/99designs/gqlgen/graphql/executor.(*Executor).PresentRecoveredError(0xc000119a40, {0x1359630, 0xc000542930}, {0x1052760?, 0xc00059f410?})
/home/micro/.go/pkg/mod/github.com/99designs/[email protected]/graphql/executor/executor.go:143 +0x46
github.com/99designs/gqlgen/graphql/handler.(*Server).ServeHTTP.func1()
/home/micro/.go/pkg/mod/github.com/99designs/[email protected]/graphql/handler/server.go:104 +0x99
panic({0x1052760, 0xc00059f410})
/usr/lib/go/src/runtime/panic.go:838 +0x207
reflect.Value.Type({0x0?, 0x0?, 0x122a902?})
/usr/lib/go/src/reflect/value.go:2451 +0x12e
github.com/vektah/gqlparser/v2/validator.(*varValidator).validateVarType(0xc0000ee800, 0xc00048ff50, {0x0?, 0x0?, 0x100f340?})
/home/micro/.go/pkg/mod/github.com/vektah/gqlparser/[email protected]/validator/vars.go:105 +0xc96
github.com/vektah/gqlparser/v2/validator.(*varValidator).validateVarType(0xc0000ee800, 0xc00048ff20, {0xffd760?, 0xc00059f3e0?, 0xc00006dc50?})
/home/micro/.go/pkg/mod/github.com/vektah/gqlparser/[email protected]/validator/vars.go:119 +0xf7c
github.com/vektah/gqlparser/v2/validator.(*varValidator).validateVarType(0xc0000ee800, 0xc000588d50, {0x1062400?, 0xc00025be90?, 0xbc373d?})
/home/micro/.go/pkg/mod/github.com/vektah/gqlparser/[email protected]/validator/vars.go:231 +0x15c5
github.com/vektah/gqlparser/v2/validator.VariableValues(0xc0001780a0, 0xc0005298f0, 0xc0000c8090?)
/home/micro/.go/pkg/mod/github.com/vektah/gqlparser/[email protected]/validator/vars.go:77 +0x5ce
github.com/99designs/gqlgen/graphql/executor.(*Executor).CreateOperationContext(0xc000119a40, {0x1359630, 0xc00025bdd0}, 0xc00011dc20)
/home/micro/.go/pkg/mod/github.com/99designs/[email protected]/graphql/executor/executor.go:74 +0x48c
github.com/99designs/gqlgen/graphql/handler/transport.(*wsConnection).subscribe(0xc0002a60f0, {0xc000542930?, 0xc000171040?, 0x1a93380?}, 0xc0005435c0)
/home/micro/.go/pkg/mod/github.com/99designs/[email protected]/graphql/handler/transport/websocket.go:307 +0x22d
github.com/99designs/gqlgen/graphql/handler/transport.(*wsConnection).run(0xc0002a60f0)
/home/micro/.go/pkg/mod/github.com/99designs/[email protected]/graphql/handler/transport/websocket.go:237 +0x629
github.com/99designs/gqlgen/graphql/handler/transport.Websocket.Do({{0x0, 0x0, 0x0, {0x0, 0x0}, {0xc000044120, 0x2, 0x2}, 0x0, 0x0, ...}, ...}, ...)
/home/micro/.go/pkg/mod/github.com/99designs/[email protected]/graphql/handler/transport/websocket.go:94 +0x311
github.com/99designs/gqlgen/graphql/handler.(*Server).ServeHTTP(0xc00054c480, {0x1358ef0, 0xc00021a380}, 0xc00009a600)
/home/micro/.go/pkg/mod/github.com/99designs/[email protected]/graphql/handler/server.go:120 +0x33d
I thought the following example would result in validation errors, but it passes without error.
Are directive arguments not checked by validation? ...or have I done something silly?
package main
import (
"github.com/vektah/gqlparser/ast"
"github.com/vektah/gqlparser/parser"
"github.com/vektah/gqlparser/validator"
)
func main() {
schema := `
scalar Int
directive @foo(bla: Int!) on FIELD_DEFINITION
type P {
f: Int @foo(bla: "asdf")
g: Int @foo(notblaa: "asdf")
h: Int @foo
}
`
doc, gqlErr := parser.ParseSchema(&ast.Source{Input: schema})
if gqlErr != nil {
panic(gqlErr)
}
_, gqlErr = validator.ValidateSchemaDocument(doc)
if gqlErr != nil {
panic(gqlErr)
}
}
I am currently building a test tool that allows you to write queries and mutations which are run against an API endpoint. The expected result can be specified directly in the query using directives:
query QueryUserName {
user {
name @expect(v: "John Brown")
}
}
My test tool then uses gqlparser to parse the directives from the query.
Before sending the query to the API endpoint I now need to cut away all @expect
directives.
The query which is sent to the API should look like this:
query QueryUserName {
user {
name
}
}
I originally thought that I could use the start and end of the Position
struct that's attached to alt element of the directive. I later found that the Position only points to the name of the directive, not the whole thing.
Is there a way for me to find out where the directive actually ends?
The current implementation of sameArguments
is invalid due to early exit in the loops.
function sameArguments(
arguments1: ReadonlyArray<ArgumentNode>,
arguments2: ReadonlyArray<ArgumentNode>,
): boolean {
if (arguments1.length !== arguments2.length) {
return false;
}
return arguments1.every((argument1) => {
const argument2 = arguments2.find(
(argument) => argument.name.value === argument1.name.value,
);
if (!argument2) {
return false;
}
return sameValue(argument1.value, argument2.value);
});
}
As can be seen here, the first step in the loop on args1 is to discover the matching argument in args2 by name. If it can't be found, return false, otherwise true if matching or false if not โ but javascript has the extra nice every
option to ensure that each iteration is true.
The current golang implementation ignores the every
, and as such will throw invalid if there is more than one argument in the slice.
for _, arg1 := range args1 {
for _, arg2 := range args2 {
if arg1.Name != arg2.Name {
return false
}
if !sameValue(arg1.Value, arg2.Value) {
return false
}
}
}
return true
#170 also adds test cases to cover this capability.
The parser does not currently support the @specifiedBy
directive. It looks like this was previously brought up on #152 by @Code-Hex but never merged.
Reference implementation: graphql/graphql-js#2276
Original Issue: 99designs/gqlgen#437
It looks like the parser is reading the schema in order and reporting on the missing field. The output shows an incorrect path to where the missing field is. It should be variables -> newTodo -> todo -> requiredTodo
. I moved the fields around in the schema and verified that when I move the todo above the users in the NewTodo input it does not display the user information. After digging into the problem it looks like it is because the varValidator.path
is appended to but has no concept of depth. So it does not back out twice when moving onto a new object.
POST http://localhost:8080/query
{
"query": "mutation($newTodo: NewTodo!) { createTodo(input: $newTodo) { id } }",
"variables": {
"newTodo": {
"user1": {
"requiredUser": ""
},
"todo": {
}
}
}
}
{
"errors": [
{
"message": "must be defined",
"path": [
"variable",
"newTodo",
"todo",
"requiredTodo"
]
}
],
"data": null
}
{
"errors": [
{
"message": "must be defined",
"path": [
"variable",
"newTodo",
"user1",
"user2",
"todo",
"notRequiredTodo",
"requiredTodo"
]
}
],
"data": null
}
Upgrading to 2.2.0 and regenerating all the code delete all mutations!
Something is wrong with 2.2.0.
The spec now allows the following syntax:
directive @myDirective(...) repeatable on ...
which allows you to use the same directive several times (presumably with different arguments) on the same node:
type MyType @myDirective(...) @myDirective(...) { ... }
(It's only in the working draft spec, but it's been there for several years, they just haven't released a new version; and graphql-js supports it.) This is used by Apollo's federation library (specifically their "composed SDL" uses such directives; you don't need them to use the library, but they can be useful in tooling).
But this library doesn't support it: it says Expected "on", found Name "repeatable"
. It would be great to add support!
package main
import (
"os"
"github.com/vektah/gqlparser/v2/ast"
"github.com/vektah/gqlparser/v2/formatter"
"github.com/vektah/gqlparser/v2/parser"
"github.com/vektah/gqlparser/v2/validator"
)
func main() {
src := ast.Source{
Input: `
directive @dir on ARGUMENT_DEFINITION
type Query {
get1(arg: Int = 7): Int
get2(arg: Int): Int
get3(arg: Int = 7 @dir): Int
get4(arg: Int @dir): Int
}
`[1:],
}
doc, err := parser.ParseSchemas(validator.Prelude, &src)
if err != nil {
panic(err)
}
vdoc, err := validator.ValidateSchemaDocument(doc)
if err != nil {
panic(err)
}
formatter.NewFormatter(os.Stdout).FormatSchema(vdoc)
}
produces
type Query {
get1(arg: Int = 7): Int
get2(arg: Int): Int
get3(arg: Int = 7): Int
get4(arg: Int): Int
}
Server should coercion single value in input to list, not raise a error.
https://spec.graphql.org/June2018/#sec-Type-System.List
This causes 99designs/gqlgen#1369
gqlparser/validator/vars_test.go
Lines 154 to 160 in b778db6
similar test from graphql.js:
https://github.com/graphql/graphql-js/blob/bbd8429b85594d9ee8cc632436e2d0f900d703ef/src/execution/__tests__/variables-test.js#L341-L350
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.