graphql-rust / juniper

GraphQL server library for Rust
Other
5.7k stars 421 forks source link

JSON Object/Map is not a valid input type #509

Open UkonnRa opened 4 years ago

UkonnRa commented 4 years ago

Describe the bug In GraphQL Java, JSON Scalar is supported, so I can write the following query:

query {
        user(input : {
                id : "216ae7d9-cbe7-4d6e-9968-33e3424da0fe",
                badges : { Github : "http://example.com" }
        }) {
            id
            email
        }
}

But the same code in juniper will throw an error:

ParseError(Spanning { item: UnexpectedToken(CurlyOpen), start: SourcePosition { index: 94, line: 1, col: 83 }, end: SourcePosition { index: 95, line: 1, col: 84 } })

So JSON Object in input is not suppoerted yet?

davidpdrsn commented 4 years ago

Why not just use a regular structured input type?

UkonnRa commented 4 years ago

Because I want to send something like: HashMap<String, String>. Any advice?

davidpdrsn commented 4 years ago

You could do something like this:

mutation {
  foo(pairs: [Pair!]!): Boolean
}

type Pair {
  key: String!
  value: String!
}
UkonnRa commented 4 years ago

Cool! That's may help in my project. But I still hope that JSON Scalar in Input can be in consideration.

UkonnRa commented 4 years ago

Wait, still get the ParseError even I change to the array? I cannot figure out where is going wrong... @davidpdrsn

mutation {
    createUser(input: {nickname: "nickname", avatar: "http://example.com", badges: [{key: "Github", value: "https://github.com"}]}) {
        id
        nickname
        badges
    }
}

Error:

called `Result::unwrap()` on an `Err` value: ParseError(Spanning { item: UnexpectedToken(CurlyOpen), start: SourcePosition { index: 95, line: 1, col: 84 }, end: SourcePosition { index: 96, line: 1, col: 85 } })
thread 'user::endpoint::graphql::tests::test_graphql' panicked at 'called `Result::unwrap()` on an `Err` value: ParseError(Spanning { item: UnexpectedToken(CurlyOpen), start: SourcePosition { index: 95, line: 1, col: 84 }, end: SourcePosition { index: 96, line: 1, col: 85 } })', src\libcore\result.rs:1165:5
davidpdrsn commented 4 years ago

This works for me

# Schema. You'll have to translate this into rust yourself but it should be pretty straight forward
type Mutation {
  foo(pairs: [Pair!]!): Boolean!
}

input Pair {
  key: String!
  value: String!
}

# Query
mutation {
  foo(pairs: [{key: "foo", value: "bar"}, {key: "foo", value: "bar"}])
}

Regarding allowing raw JSON as input type. I guess it would make sense if the spec says so, otherwise I would be reluctant to adding it. What do you think @theduke @LegNeato?

UkonnRa commented 4 years ago

Now it works! It seems that there are some problems when writing a Scalar manually, so I just change the data structure. Sorry for bothering :-)

LegNeato commented 4 years ago

See https://github.com/graphql/graphql-spec/pull/584 for the RFC to support this I believe. I haven't seen where that RFC ended up though.

LegNeato commented 4 years ago

Also https://github.com/graphql/graphql-spec/issues/627.

UkonnRa commented 4 years ago

Well, I think those are two different things. The RFC want to implement ADT in GraphQL DSL, which is way much harder. What I'm wanting is just a general JSON scalar type

UkonnRa commented 4 years ago

In fact, https://github.com/graphql-rust/juniper/pull/325 is exactlly what I want, hoping this PR can move on...