Postman - Upload file and other argument with GraphQL - graphql

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" } }`

Related

Why can I execute mutation function with null parameter with type being `String!`?

Simple table with one two rows. ID (incrementing int) and test_value (TEXT, nullable).
1. Query
query getData($test_value:String!) {
testtable(where: {test_value: {_eq: $test_value}}) {
test_value
}
}
Variables
{"test_value":null}
Result
{
"errors": [
{
"extensions": {
"path": "$.selectionSet.testtable.args.where.test_value._eq",
"code": "validation-failed"
},
"message": "unexpected null value for type \"String\""
}
]
}
This is a correct that I expect.
2. Mutation
mutation InsertData($test_value: String!) {
insert_testtable(objects: {test_value: $test_value}) {
affected_rows
}
}
Variables
{"test_value":null}
Result
{
data: {
insert_testtable: {
affected_rows: 1
}
}
}
I expect and error (because of test_value:String! declaration), but I don't get it.
Why?
P.S.
testable schema looks like this:
id: Int!
test_value: String
My understanding of your issue: Your schema has a mutation insert_testtable that takes a nullable String argument. When you submit a named mutation operation with a non-nullable String! variable, the GraphQL server does not respond with an error.
The GraphQL spec says that is the expected behaviour for mutations and queries. The spec says that if the type in the schema is nullable and of the same type as the variable, the operation is to be considered valid. This is what's happening for your mutation.
If you are not seeing the same behaviour for the query, it is possible that your GraphQL server implementation differs from the spec. You could check your server docs or their GitHub Issues.
For what it's worth, I checked that AppSync, AWS's GraphQL implementation, produces the expected behaviour for both queries and mutations.

FaunaDB - How to bulk update list of entries within single graphQL mutation?

I want to bulk update list of entries with graphQL mutation in faunaDB.
The input data is list of coronavirus cases from external source. It will be updated frequently. The mutation should update existing entries if the entry name is present in collectio and create new ones if not present.
Current GRAPHQL MUTATION
mutation UpdateList($data: ListInput!) {
updateList(id: "260351229231628818", data: $data) {
title
cities {
data {
name
infected
}
}
}
}
GRAPHQL VARIABLES
{
"data": {
"title": "COVID-19",
"cities": {
"create": [
{
"id": 22,
"name": "Warsaw",
"location": {
"create": {
"lat": 52.229832,
"lng": 21.011689
}
},
"deaths": 0,
"cured": 0,
"infected": 37,
"type": "ACTIVE",
"created_timestamp": 1583671445,
"last_modified_timestamp": 1584389018
}
]
}
}
}
SCHEMA
type cityEntry {
id: Int!
name: String!
deaths: Int!
cured: Int!
infected: Int!
type: String!
created_timestamp: Int!
last_modified_timestamp: Int!
location: LatLng!
list: List
}
type LatLng {
lat: Float!
lng: Float!
}
type List {
title: String!
cities: [cityEntry] #relation
}
type Query {
items: [cityEntry!]
allCities: [cityEntry!]
cityEntriesByDeathFlag(deaths: Int!): [cityEntry!]
cityEntriesByCuredFlag(cured: Int!): [cityEntry!]
allLists: [List!]
}
Everytime the mutation runs it creates new duplicates.
What is the best way to update the list within single mutation?
my apologies for the delay, I wasn't sure exactly what the missing information was hence why I commented first :).
The Schema
An example of a part of a schema that has arguments:
type Mutation {
register(email: String!, password: String!): Account! #resolver
login(email: String!, password: String!): String! #resolver
}
When such a schema is imported in FaunaDB there will be placeholder functions provided.
The UDF parameters
As you can see all the function does is Abort with the message that the function still has to be implemented. The implementation starts with a Lambda that takes arguments and those arguments have to match what you defined in the resolver.
Query(Lambda(['email', 'password'],
... function body ...
))
Using the arguments is done with Var, that means Var('email') or Var('password') in this case. For example, in my specific case we would use the email that was passed in to get an account by email and use the password to pass on to the Login function which will return a secret (the reason I do the select here is that the return value for a GraphQL resolver has to be a valid GraphQL result (e.g. plain JSON
Query(Lambda(['email', 'password'],
Select(
['secret'],
Login(Match(Index('accountsByEmail'), Var('email')), {
password: Var('password')
})
)
))
Calling the UDF resolver via GraphQL
Finally, how to pass parameters when calling it? That should be clear from the GraphQL playground as it will provide you with the docs and autocompletion. For example, this is what the auto-generated GraphQL docs tell me after my schema import:
Which means we can call it as follows:
mutation CallLogin {
login (
email: "<some email>"
password: "<some pword>"
)
}
Bulk updates
For bulk updates, you can also pass a list of values to the User Defined Function (UDF). Let's say we would want to group a number of accounts together in a specific team via the UI and therefore want to update multiple accounts at the same time.
The mutation in our Schema could look as follows (ID's in GraphQL are similar to Strings)
type Mutation { updateAccounts(accountRefs: [ID]): [ID]! #resolver }
We could then call the mutation by providing in the id's that we receive from FaunaDB (the string, not the Ref in case you are mixing FQL and GraphQL, if you only use GraphQL, don't worry about it).
mutation {
updateAccounts(accountRefs: ["265317328423485952", "265317336075993600"] )
}
Just like before, we will have to fill in the User Defined Function that was generated by FaunaDB. A skeleton function that just takes in the array and returns it would look like:
Query(Lambda(['arr'],
Var('arr')
))
Some people might have seen an easier syntax and would be tempted to use this:
Query(Lambda(arr => arr))
However, this currently does not work with GraphQL when passing in arrays, it's a known issue that will be fixed.
The next step is to actually loop over the array. FQL is not declarative and draws inspiration from functional languages which means you would do that just by using a 'map' or a 'foreach'
Query(Lambda(["accountArray"],
Map(Var("accountArray"),
Lambda("account", Var("account")))
))
We now loop over the list but don't do anything with it yet since we just return the account in the map's body. We will now update the account and just set a value 'teamName' on there. For that we need the Update function which takes a FaunaDB Reference. GraphQL sends us strings and not references so we need to transform these ID strings to a reference with Ref as follows:
Ref(Collection('Account'), Var("account"))
If we put it all together we can add an extra attribute to a list of accounts ids as follows:
Query(Lambda(["accountArray"],
Map(Var("accountArray"),
Lambda("account",
Do(
Update(
Ref(Collection('Account'), Var("account")),
{ data: { teamName: "Awesome live-coders" } }
),
Var("account")
)
)
)
))
At the end of the Map, we just return the ID of the account again with Var("account") in order to return something that is just plain JSON, else we would be returning FaunaDB Refs which are more than just JSON and will not be accepted by the GraphQL call.
Passing in more complex types.
Sometimes you want to pass in more complex types. Let's say we have a simple todo schema.
type Todo {
title: String!
completed: Boolean!
}
And we want to set the completed value of a list of todos with specific titles to true. We can see in the extended schema generated by FaunaDB that there is a TodoInput.
If you see that extended schema you might think, "Hey that's exactly what I need!" but you can't access it when you write your mutations since you do not have that part of the schema at creation time and therefore can't just write:
type Mutation { updateTodos(todos: [TodoInput]): Boolean! #resolver }
As it will return the following error.
However, we can just add it to the schema ourselves. Fauna will just accept that you already wrote it and not override it (make sure that you keep the required fields, else your generated 'createTodo' mutation won't work anymore).
type Todo {
title: String!
completed: Boolean!
}
input TodoInput {
title: String!
completed: Boolean!
}
type Mutation { updateTodos(todos: [TodoInput]): Boolean! #resolver }
Which means that I can now write:
mutation {
updateTodos(todos: [{title: "test", completed: true}])
}
and dive into the FQL function to do things with this input.
Or if you want to include the ID along with data you can define a new type.
input TodoUpdateInput {
id: ID!
title: String!
completed: Boolean!
}
type Mutation { updateTodos(todos: [TodoUpdateInput]): Boolean! #resolver }
Once you get the hang of it and want to learn more about FQL (that's a whole different topic) we are currently writing a series of articles along with code for which the first one appeared here: https://css-tricks.com/rethinking-twitter-as-a-serverless-app/ which is probably a good gentle introduction.

Graphql scalar type for a value that can be string or object?

i have an api for sign up which returns error of string or null,
error: 'Email already use' or error: null
how do i construct it in schema? what i have now is this:
const typeDefs = gql`
type Mutation {
signUp(email: String, password: String): String
}
`;
since typeof null is object, how can i make it like this in graphql?
signUp(email: String, password: String): String || Object
Help?
GraphQL has a standard syntax for returning error values and your schema does not directly need to account for this.
In your schema I would “unconditionally” return whatever type you’d normally expect to return:
type UserAccount { ... }
type Query {
me: UserAccount # or null if not signed in
}
type Mutation {
signUp(email: String!, password: String!): UserAccount!
}
If it’s unsuccessful, you will get back a null field value (even though the schema in theory claims it shouldn’t) and an error.
{
"errors": [
{
"message": "It didn’t work",
"locations": [ { "line": 2, "column": 3 } ],
"path": [ "signUp" ]
}
]
}
In GraphQL you can define what field can be null and what can't.
Take a look at the docs:
https://graphql.org/learn/schema/#object-types-and-fields
String is one of the built-in scalar types - these are types that
resolve to a single scalar object, and can't have sub-selections in
the query. We'll go over scalar types more later.
String! means that the field is non-nullable, meaning that the GraphQL service promises
to always give you a value when you query this field. In the type
language, we'll represent those with an exclamation mark.
So in case of your schema String is absolutely fine. It can be null
type Mutation {
signUp(email: String, password: String): String
}

Graphql mandatory check doesn't work when using GraphiQL UI with input variables

I have defined a mutation like below with email field marked as mandatory
type Mutation {
bookTicket (person: PersonInput! ,email: String!): Ticket
}
input PersonInput{
personId: ID!
name: String!
date: String!
comment: String
}
When I try to execute the mutation through GraphIQl UI withou passing email field the UI doesn't throw validation error and the calls the endpoint with empty value for the email field .
mutation($personInput:PersonInput!, $email :String!){
bookTicket(person:$personInput,email: $email){
id
}
}
Variables
{
"personInput": {
"personId": "111",
"name": "test",
"date": "10-Oct-2018",
"comment": "Book"
}
}
If I try to run the mutation with inline variables the validation works fine and shows exception that email cannot be empty .
mutation{
bookTicket(person:{personId: "111", name: "test", date: "10-Oct-
2018",comment: "Book"}
email:""){
id
}
}
Can anyone help me on why the validation doesn't work in the first case ?

GraphQL mutation variables

I'm trying to do a simple mutation using GraphQL with the GraphiQL interface. My mutation looks like this:
mutation M($name: String) {
addGroup(name:$name) {
id,
name
}
}
with variables:
{
"name": "ben"
}
But it gives me the error: Variable $name of type "String" used in position expecting type "String!"
If I change my mutation to mutation M($name: String = "default") it works as expected. This looks like it's related to the type system, but I can't seem to figure out what the problem is.
You probably defined the input name as a non-null string (something like type: new GraphQLNonNull(GraphQLString) if using js server, or String! in plain GraphQL).
So your input in the mutation must match, which means it must also be a non-null string. If you change to the following, it should work:
mutation M($name: String!) {
addGroup(name:$name) {
id,
name
}
}
Also if you define a default value as you did, it will be a non-null string.
Finally, you could drop the requirement of being a non-null in the server.
I think in you addGroup() mutation the args for name is of type String! that is new GraphQLNonNull(GraphQLString) but in your mutation you specify as String which conflicts with the type system.
When you have an error like this check your database model, in my case I checked my schema and as mongo pluralizes the words was causing me error but I could fix it, also check the documentation.
mutation {
createProject(
name:"project two",
description:"project two"
) {
name
}
}
=> works

Resources