I am using graphlQL-playground web to send this request:
gift.createCard({card: {_: inputGiftCard, currency: string, amount: string, recipients_count: int, distribution_type: {_: distributeRandom}, display_balance: Bool}})
and I get this response:
error: {
error_message: "Not required field {display_balance}"
}
to be honest, I don’t understand what the error is in the request and why playground doesn’t see this parameter
Related
I am trying to use Postman to upload a file to GraphQL.
I know how I can upload a file, however, in my mutation I have to pass a String! together with the Upload!.
I am not sure where I can pass this String! in Postman.
My mutation:
mutation AddBookImageOne($bookId: string, $bookImageOne: Upload!){
addBookImageOne(bookId: $bookId, bookImageOne: $bookImageOne)
}
I tried to pass bookId in the variables key but I keep getting the error:
"message": "Variable "$bookId" of required type "String!" was not provided.",
I checked this: Graphql mutation to upload file with other fields
but they use CURL
"Operations" in postman field is:
{"query":"mutation AddBookImageOne($bookId: String!, $bookImageOne: Upload!){\n addBookImageOne(bookId: $bookId, bookImageOne: $bookImageOne)\n}"}
SOLVED thanks to #xadm
I had to pass the variables in the operations field like:
{"query":"mutation AddBookImageOne($bookId: String!, $bookImageOne: Upload!){\n addBookImageOne(bookId: $bookId, bookImageOne: $bookImageOne)\n}", "variables": { "bookImageOne": null, "bookId": "be96934c-d20c-4fad-b4bb-a1165468bad9" } }`
I have the following method that parses the mutation into a GraphqL-readable format using GQL
def query(attributes:)
<<~GQL
mutation {
createBook(
attributes: #{attributes}
) {
id
title
publicationDate
genre
}
}
GQL
end
I then send a post request to the /graphql endpoint while passing what the query returns as params. As follows
post '/graphql', params: { query: query(attributes: attributes) }
When I hit the endpoint, I get the following error
{"errors"=>[{"message"=>"Parse error on \":\" (COLON) }]}
I later realised that GQL cannot parse Ruby symbols , i.e :first_name. So I tried to convert the attributes hash keys into strings with attributes.stringify, but seems GQL doesn't also recognise Ruby hashrockets, so it threw the error
{"errors"=>[{"message"=>"Parse error on \"first_name\" (STRING) }]}
Is there a way to make GraphQL to parse Ruby symbols and/or hashrockets?
For a mutation addVoucher there are a limited list of potential errors that can occur.
Voucher code invalid
Voucher has expired
Voucher has already been redeemed
At the moment I'm throwing a custom error when one of these occurs.
// On the server:
const addVoucherResolver = () => {
if(checkIfInvalid) {
throw new Error('Voucher code invalid')
}
return {
// data
}
}
Then on the client I search the message description so I can alert the user. However this feels brittle and also the GraphQL API doesn't automatically document the potential errors. Is there a way to define the potential errors in the GraphQL schema?
Currently my schema looks like this:
type Mutation {
addVoucherResolver(id: ID!): Order
}
type Order {
cost: Int!
}
It would be nice to be able to do something like this:
type Mutation {
addVoucherResolver(id: ID!): Order || VoucherError
}
type Order {
cost: Int!
}
enum ErrorType {
INVALID
EXPIRED
REDEEMED
}
type VoucherError {
status: ErrorType!
}
Then anyone consuming the API would know all the potential errors. This feels like a standard requirement to me but from reading up there doesn't seem to be a standardises GraphQL approach.
It's possible to use a Union or Interface to do what you're trying to accomplish:
type Mutation {
addVoucher(id: ID!): AddVoucherPayload
}
union AddVoucherPayload = Order | VoucherError
You're right that there isn't a standardized way to handle user-visible errors. With certain implementations, like apollo-server, it is possible to expose additional properties on the errors returned in the response, as described here. This does make parsing the errors easier, but is still not ideal.
A "Payload" pattern has emerged fairly recently for handling these errors as part of the schema. You see can see it in public API's like Shopify's. Instead of a Union like in the example above, we just utilize an Object Type:
type Mutation {
addVoucher(id: ID!): AddVoucherPayload
otherMutation: OtherMutationPayload
}
type AddVoucherPayload {
order: Order
errors: [Error!]!
}
type OtherMutationPayload {
something: Something
errors: [Error!]!
}
type Error {
message: String!
code: ErrorCode! # or a String if you like
}
enum ErrorCode {
INVALID_VOUCHER
EXPIRED_VOUCHER
REDEEMED_VOUCHER
# etc
}
Some implementations add a status or success field as well, although I find that making the actual data field (order is our example) nullable and then returning null when the mutation fails is also sufficient. We can even take this one step further and add an interface to help ensure consistency across our payload types:
interface Payload {
errors: [Error!]!
}
Of course, if you want to be more granular and distinguish between different types of errors to better document which mutation can return what set of errors, you won't be able to use an interface.
I've had success with this sort of approach, as it not only documents possible errors, but also makes it easier for clients to deal with them. It also means that any other errors that are returned with a response should serve as an immediately red flag that something has gone wrong with either the client or the server. YMMV.
You can use scalar type present in graphql
just write scalar JSON and return any JSON type where you want to return it.
`
scalar JSON
type Response {
status: Boolean
message: String
data: [JSON]
}
`
Here is Mutation which return Response
`
type Mutation {
addVoucherResolver(id: ID!): Response
}
`
You can return from resolver
return {
status: false,
message: 'Voucher code invalid(or any error based on condition)',
data: null
}
or
return {
status: true,
message: 'Order fetch successfully.',
data: [{
object of order
}]
}
on Front end you can use status key to identify response is fetch or error occurs.
My CRUD operations work. But many of them also generate a single, specific console error I haven't been able to track down.
[GraphQL error]: Message: Variable "$id" of required type "ID!" was not provided., Location: [object Object], Path: undefined
Example: I can view a list of users without generating an error, and I can access the "details" view of a single user without generating an error. Those two work fine in isolation. But somehow, traversing from the former to the latter generates the error.
I tested both queries (users and user) in GraphQL-Playground, and did not receive errors. I also tried the IDs as type "String" rather than type "ID!". (Also without the !). I experimented with other "hacky" ways of feeding the user id to the resolver. And I've tried passing in other fields in lieu of the "info" argument in the query resolver.
To reiterate, Viewing either page in isolation (ie: clearing the console and reloading either page) does NOT trigger the error. It seems to be something about the journey from /users to user?id=12345.
from datamodel.prisma:
type User {
id: ID! #unique
createdAt: DateTime!
updatedAt: DateTime!
name: String!
email: String! #unique
password: String!
resetToken: String
resetTokenExpiry: Float
permissions: Permission
posts: [Post]! #relation(name: "PostsOfUser" onDelete: CASCADE)
comments: [Comment!]! #relation(name: "CommentsOfUser" onDelete:
CASCADE)
from query object in schema.graphql:
user(id: ID!): User
user query resolver:
async user(parent, { id }, { db, request }, info) {
const user = await db.query.user({ where: { id } }, info);
return user;
gql query using react-apollo and graphql-tag packages:
const SINGLE_USER_QUERY = gql`
query SINGLE_USER_QUERY($id: ID!){
user(id: $id) {
id
name
email
permissions
createdAt
updatedAt
}
}
`;
Expected behavior: User can click on a single user from a list of users, and the following page will contain details about that user.
Actual results: It works, but also generates console errors:
[GraphQL error]: Message: Variable "$id" of required type "ID!" was
not provided., Location: [object Object], Path: undefined
index.js:86
[Network error]: ServerError: Response not successful: Received status code 400
index.js:2178 GraphQL error occurred [getDataFromTree] Error:
Network error: Response not successful: Received status code 400
at new ApolloError (ApolloError.js:37)
at QueryManager.js:328
at QueryManager.js:700
at Array.forEach (<anonymous>)
at QueryManager.js:699
at Map.forEach (<anonymous>)
at QueryManager.push../node_modules/apollo-client/core/QueryManager.js.QueryManager.broadcastQueries (QueryManager.js:694)
at QueryManager.js:277
Please add an if condition for the parameter and check whether it is true. Then add a get(REST API) or query(GrahQL) function inside it. Then it won't show this error. Please see the below example
async user(parent, { id }, { db, request }, info) {
if ( id ) {
//enter your code
const user = await db.query.user({ where: { id } }, info);
return user;
}
}
I've got a graphql server implemented with graphql-go, and I'm using Apollo on the front end. Simple queries without arguments, and mutations using input object types work fine, but for some reason passing a scalar type argument in a query returns the error:
[{"message":"Unknown type \"Int\".","locations":[{"line":1,"column":19}]}]
My use could not be simpler; on the client side, my query is:
export const GET_CLIENT = gql`
query client($id: Int) {
client(id: $id) {
id
name
}
}`
which is used in a component like so:
<Query
query={GET_CLIENT}
variables={{
id: 1
}} />
which resolves to this field on the backend:
// ClientQuery takes an ID and returns one client or nil
var ClientQuery = &graphql.Field{
Type: ClientType,
Args: graphql.FieldConfigArgument{
"id": &graphql.ArgumentConfig{
Type: graphql.Int,
},
},
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
return p.Context.Value("service").(*model.Service).FindClientByID(id)
},
}
I've tried passing input objects, strings, etc. but it seems that no query arguments, scalar or otherwise are ever satisfied on the backend. I've tried both master and v0.7.5 of graphql-go. Am I missing something? Help very much appreciated, it feels weird for something this basic to be such a huge blocker.
As the other post that mentioned having to go from int to float, this error occurs because the types set up in your graphQL schema are conflicting with the types you are trying to use when querying.
It's saying: 'Unknown type Int'
But what it really means is: 'Expected type Float but got Int' then you'd go change it where it is wrong.
I fixed this by changing the variable type of ID from Int to Float