Postman, test Graphql response - graphql

I have this query:
query SessionQuery {
cliente {
id
clienteId
rut
porcentajeDeCompletitudDeInformacion
fichaCliente {
tipoPersona
razonSocial
}
representantesLegales {
edges {
node {
rutRepresentante
}
}
}
documentosRequeridos {
edges {
node {
iDDocumento
cargado
nombreDocumento
tipoDocumentoHQB
}
}
}
}
usuario {
id
usuarioId
email
nombre
rut
}
}
I'm testing for the first time GraphQL through Postman, like this way:
I'm having this response, I don't understand the error message:
{"data":{"cliente":{"id":"Q2xpZW50ZTow","clienteId":0,"rut":"XXX","porcentajeDeCompletitudDeInformacion":20,"fichaCliente":{"tipoPersona":2,"razonSocial":"ING. Y SISTEMAS BIZWARE (Empresa Relacionada)"},"representantesLegales":{"edges":[{"node":{"rutRepresentante":null}}]},"documentosRequeridos":{"edges":[]}},"usuario":{"id":"VXN1YXJpbzoyMDI4","usuarioId":2028,"email":"XXXX#gmail.com","nombre":"XXXX","rut":"XXXX"}},"errors":[{"message":"GraphQL.ExecutionError: Cannot return null for non-null type. Field: rutRepresentante, Type: String!.\r\n at GraphQL.Execution.ExecutionStrategy.ValidateNodeResult(ExecutionContext context, ExecutionNode node)\r\n at GraphQL.Execution.ExecutionStrategy.ExecuteNodeAsync(ExecutionContext context, ExecutionNode node)","locations":[{"line":14,"column":11}],"path":["cliente","representantesLegales","edges","0","node","rutRepresentante"]}]}
I not sure what it means the error. My problem is when I call this Graphql endpoint from JavaScript I have a CORS problem in my app, but I detected with Postman that maybe the problem is this one, and the query or something is broken. Any idea please, thanks.

xadm's comment is correct - in a standard GraphQL schema, the exclamation point means that the field is required. It's likely that the rutRepresentante field is NULL for the database record that your query retrieves.
Either remove the exclamation mark from String! in order to make the field nullable, or populate the row in the database for the rutRepresentante column (or key, if you're not using SQL...)

Related

Getting Unsupported token `on` [GraphQL]

Issue: We goto 'on' in the query, while build apollo is complaining about the on keyword in the query (*.graphql)
GraphQL query:
query TimeLine($inputData: InputData!) {
getTimeLine(inputData: $inputData) {
on
updated
}
}
Error: Unsupported token on
(com.apollographql.apollo.compiler.parser.GraphQLDocumentParseException).
Env: Kotlin, apolloGraphQLVersion: "1.3.2"
This happens because the on keyword is a reserved keyword in GraphQL.
One of the Type Conditions is on NamedType, see the official spec file of GraphQL.
query FragmentTyping {
profiles(handles: ["zuck", "cocacola"]) {
handle
...userFragment
...pageFragment
}
}
fragment userFragment on User {
friends {
count
}
}
fragment pageFragment on Page {
likers {
count
}
}
See the on used in fragment userFragment on User? Your GraphQL got confused because you are using on as a field within the query, while it expects to be a fragment. Read more about fragments here. Also, a fragment's name can be anything, except for on, see the official spec file.
One way to solve this issue might be to rename the field in your query, but I am not sure if GraphQL will complain about this approach as well:
query TimeLine($inputData: InputData!) {
getTimeLine(inputData: $inputData) {
dataOn: on
updated
}
}

Passing variables from mutation to query

I have a GraphQL mutation that creates an item and returns the data that's created. I need to pass some of the created fields into a query. Is this possible? This is almost working but I can't figure out how to get the data between the mutation and the query:
mutation {
createToken(
input: { tokenname: "my token", tokendescription: "my valuable token" }
) {
id
randomdata
}
insert__helloworld_article(objects: [{randomdata: "Hello" , author_id: 1}]) {
returning {
id
}
}
}
So my problem is getting "randomdata" from the mutation to insert into the helloworld_article
You wouldn't be able to use the return value in the same mutation with GraphQL, however if those objects have a relationship you could do a nested insert.

Is there a way to avoid returing keys with null values in Apollo GraphQL?

I have a nullable attribute in a type:
type Person {
job: String
}
And a query:
query Persons() {
persons() {
job
}
}
Whevener I query the object, I always get the job key, either with a string or a null value.
{
"job": null
}
But what I need is the job key to be present in the result only when the job is defined, otherwise I want it to be skipped altogether.
{}
I have tried returning null, undefined and skipping the key from the data, but Apollo always returns the key no matter what.
It is much easier to delete field afterwards:
if (result.job === null) {
delete result.job;
}
To achieve the same result with graphql you'll have to split Person into two types: PersonWithJob and PersonWithoutJob. Return a union from persons query and change your query to something like:
query Persons() {
persons() {
... on PersonWithJob {
job
}
}
}

Handle graphql schema stitching error in child query

I am new to graphql and want to understand the concept here. I have this graphql schema (stitched using graphic-tools). Not all cars have registration. So if I query for 5 cars and one car doesn’t have a registration (no id to link between cars and registration), my whole query fails.
How do I handle this and return null for that 1 car and return registration details for the other 4?
{
Vehicles {
Cars {
id
registration {
id
}
}
}
}
If you mark a field as non-null (by appending ! to the type) and then resolve that field to null, GraphQL will always throw an error -- that's unavoidable. If it's possible for a field to end up null in the normal operation of your API, you should probably make it nullable.
However, errors "bubble up" to the nearest nullable field.
So given a schema like this:
type Query {
cars: [Car!]!
}
type Car {
registration: Registration!
}
and this query
{
cars {
registrations
}
}
resolving the registration field for any one Car to null will result in the following because the cars field is non-null and each individual Car must also not be null:
{
"data": null,
"errors": [...]
}
If you make the cars field nullable ([Car!]), the error will stop there:
{
"data": {
"cars": null
},
"errors": [...]
}
However, you can make each Car nullable (whether the field is or not), which will let the error stop there and result in an array of objects and nulls (the nulls being the cars that errored). So making the cars type [Car]! or [Car] will give us:
{
"data": {
"cars": [{...}, {...}, null]
},
"errors": [...]
}

Document all potential errors on GraphQL server?

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.

Resources