Graphql - How to perform where clause - graphql

I am new to graphql and I am struggling with a query.
I want to return a user by their email address
I have a type defined call V1User and it has the following fields
id,
email,
password,
role
What needs to change in this query to return a user based on email?
query GetAllV1User {
viewer {
allV1Users{
edges {
node {
id
email
role
createdAt
modifiedAt
}
}
}
}
}
I tried this query
query getV1UserQuery($email: String!) {
getV1User(email: $email) {
id
email
}
}
With these params
{"email": "test#test.com"}
But get the following errors
{
"errors": [
{
"message": "Unknown argument \"email\" on field \"getV1User\" of type \"Query\".",
"locations": [
{
"line": 2,
"column": 13
}
],
"name": "GraphQLError"
},
{
"message": "Field \"getV1User\" argument \"id\" of type \"ID!\" is required but not provided.",
"locations": [
{
"line": 2,
"column": 3
}
],
"name": "GraphQLError"
}
]
}
My Schema is as follows
Name Type Constraints
id ID NonNull Unique
modifiedAt DateTime NonNull
createdAt DateTime NonNull
role String NonNull
password String NonNull
email String NonNull Unique Indexed
Thanks
Hi
This query solved my issue
query getUserForEmailAddressAndPassword($where: V1UserWhereArgs) {
viewer {
allV1Users(where: $where) {
edges {
node {
email
id
createdAt
password
modifiedAt
role
}
}
}
}
}
Along with these query variables
{"where": {"email": {"eq" : "test#test.com"}, "password": {"eq":"te2st"}}}

You can do so by using the where clause and comparison operators.
https://hasura.io/docs/latest/graphql/core/databases/postgres/queries/query-filters.html#the-where-argument
query {
authors (where: {articles: {rating: {_gt: 4}}}) {
id
name
articles (where: {rating: {_gt: 4}}) {
id
title
rating
}
}
}

I wouldn't recommend using the string "where" in your filter clause. Don't try to emulate SQL. What are you trying to filter using the where clause. If it's an email address then the query in your schema should contain user as the field and email as a parameter to that field.
So the first example that you sent is the right way to do it.
Also, avoid declaring queries using verbs like getUsers or getUser. The schema should just declare the query using nouns
Query
{
Users(email:String):[User!]
}
type User
{
id
email
createdAt
otherStuff
}

Related

GraphQL: Variable is used by anonymous query but not declared

I am new to GraphQL. I have a query, but it shows error message of "Variable is used by anonymous query but not declared".
{
"query":"{customers(first: 1, query: $input) {edges{node {addresses{ id }}}}}",
"variables":{
"input":{
"id":"gid://shopify/Customer/5044061470926"
}
}
}
Can I get some help what I did wrong?
Thanks!
The error is correct. Your query is
{
customers(first: 1, query: $input) {
edges{
node {
addresses{
id
}
}
}
}
}
and $input is indeed not declared, so GraphQL has no idea what it is supposed to be or how to link it up with your variables values.
You'll need to do
query ($input: <THE_TYPE>!) {
customers(first: 1, query: $input) {
edges{
node {
addresses{
id
}
}
}
}
}
I don't know your API schema, so you'll have to replace <THE_TYPE> with whatever type is defined in your API schema.

GraphQL mutation - confusion designing gql tag for Apollo Client

I need help figuring out the GraphQL tag for use with Apollo Client. The Docs don't go far beyond the most basic use case for mutations.
My goal is to have the only required input be an email. If the other variables are present, I would like those to be accepted and create a proposal with all that information.
I have the mutation (in both only email and full variables scenarios) working successfully on the GraphQl Playground (if it helps, you can find it here and test it out, look at the schema, etc.,): https://prisma2-graphql-yoga-shield.now.sh/playground)
mutation {
createOneProposal(
data: {
email: "fake#gmail.com"
name: "Sean"
types: {
create: {
model: PURCHASE
name: "e-commerce"
cost: 600
services: {
create: [
{ service: "Responsive web design" }
{ service: "Another service!" }
{ service: "And yet another service!" }
]
}
}
}
}
) {
created_at
proposal_id
types {
cost
model
name
type_id
services {
service
service_id
}
}
}
}
Producing as a result:
{
"data": {
"createOneProposal": {
"created_at": "2020-02-27T21:28:53.256Z",
"proposal_id": 35,
"types": [
{
"cost": 600,
"model": "PURCHASE",
"name": "e-commerce",
"type_id": 6,
"services": [
{
"service": "Responsive web design",
"service_id": 10
},
{
"service": "Another service!",
"service_id": 11
},
{
"service": "And yet another service!",
"service_id": 12
}
]
}
]
}
}
}
My initial design for the gql tag:
export const NEW_PROPOSAL = gql`
mutation createOneProposal(
$email: String!
$name: String
$cost: Int
$model: Model
$service: Service
) {
createOneProposal(
email: $email
name: $name
cost: $cost
model: $model
service: $service
) {
created_at
proposal_id
types {
services {
service_id
}
}
}
}
`;
But, I get a lot of errors with this.
{"errors":[
{"Variable "$service" cannot be non-input type `"Service`".","locations":[{"line":1,"column":97}]},
{"Unknown argument "email" on field "createOneProposal`" of type "Mutation`".","locations":[{"line":2,"column":21}]},
{"Unknown argument "name" on field "createOneProposal`" of type "Mutation`".","locations":[{"line":2,"column":36}]},
{"Unknown argument"cost" on field "createOneProposal\" of type "Mutation`".","locations":[{"line":2,"column":49}]},
{"Unknown argument "model" on field "createOneProposal`" of type "Mutation`".","locations":[{"line":2,"column":62}]},
{"Unknown argument "service" on field "createOneProposal`" of type "Mutation`".","locations":[{"line":2,"column":77}]},
{"Field "createOneProposal" argument "data" of type "ProposalCreateInput!`" is required, but it was not provided.","locations":[{"line":2,"column":3}]}]}
So, how can I go about this... I figured out the query version (much easier...), but I just can't figure this out!
My schema, if it helps:
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "mysql"
url = env("MYSQL_URL_PRISMA2")
}
model Post {
content String #default("")
created_at DateTime #default(now())
post_id Int #default(autoincrement()) #id
published Boolean #default(false)
published_at DateTime?
title String #default("")
author User
}
model Profile {
bio String?
profile_id Int #default(autoincrement()) #id
user_id User
}
model Proposal {
email String #unique
name String?
proposal_id Int #default(autoincrement()) #id
created_at DateTime #default(now())
types Type[]
}
model Type {
cost Int?
name String?
model Model? #default(SUBSCRIPTION)
services Service[]
type_id Int #default(autoincrement()) #id
proposal_id Proposal
}
model Service {
service_id Int #default(autoincrement()) #id
service String?
type_id Type
}
model User {
email String #default("") #unique
name String #default("")
password String #default("")
role Role #default(USER)
user_id Int #default(autoincrement()) #id
posts Post[]
profiles Profile[]
}
enum Role {
USER ADMIN
}
enum Model {
SUBSCRIPTION PURCHASE CUSTOM
}
GraphQL types are categorized as either input types or output types. Input types are used for inputs like variable definitions or argument definitions. Output types are used for typing fields, which are what compose the actual response. Certain types, like scalars and enums, can be used as either an input or an output. However, with objects, there are output object types (sometimes referred to just object types or objects) and input object types.
Service is an output type, so it can't be used where an input type is expected (in this case, a variable definition). Examine the schema generated by Prisma to determine the appropriate type to use.
Thanks to some very needed direction from #xadm, I figured out the structure of the tag! For anyone who comes across this in the future:
mutation createOneProposal($input: ProposalCreateInput!){
createOneProposal(data:$input){
created_at
name
email
proposal_id
type{
cost
description
model
name
type_id
services{
service
cost
service_id
}
}
}
}

Cannot Return null or non-nullable field User.Role not able to retrive relation data from prisma mutation

I am trying play arroud APOLO SERVER, GRAPHQL PRISMA and struct at very basic thing .. I am not able to return relation data from simple query ..
WHen i try to add user along with role id .. i am not able to get role information back
WHat i am using ?
"dependencies": {
"apollo-server": "^2.9.3",
"bcryptjs": "^2.4.3",
"graphql": "^14.5.5",
"graphql-import": "^0.7.1",
"jsonwebtoken": "^8.5.1",
"prisma-client-lib": "^1.34.8"
}
for My SIMPLE QUERY ;
mutation{
createUser(name:"tst",
roleId:"ck0lx425n00z50782jgcl4qg8")
{
name
role{
code}
Graphql returning error saying
{
"errors": [
{
"message": "Cannot return null for non-nullable field User.role.",
"locations": [
{
"line": 4,
"column": 5
}
],
"path": [
"createUser",
"role"
],
"extensions": {
"code": "INTERNAL_SERVER_ERROR",
"exception": {
"stacktrace": [
"Error: Cannot return null for non-nullable field User.role.",
GAPHQL SHCHEMA
scalar DateTime
type User {
id: ID!
name: String!
role:Role!
createdAt:DateTime
}
type Role{
id:ID!,
code:String!
users:[User!]!
}
type Query {
users:[User!]!
user:User!
roles:[Role!]!
role:Role!
}
type Mutation {
createRole(code:String!):Role!
createUser(name:String!,roleId:String!):User!
}
QUERY
function users(parent, args, context) {
return context.prisma.uses()
}
function roles(parent,args,context){
return context.prisma.roles()
}
MUTAIONS
function createRole(parent,args,context,info){
return context.prisma.createRole({
code:args.code
});
function createUser(parent,args,context,info){
return context.prisma.createUser({
name:args.name,
role:{
connect:{id:args.roleId}
}
},info);
}
PRISMA DATAMODEL
type User {
id: ID! #id
name:String!
createdAt:DateTime #createdAt
role:Role! #relation(Name:"Role Assinged To User")
}
type Role{
id:ID! #id
code:String!
users:[User!]! #relation(Name:"Role Assinged To User")
}
can some body help me , how to fix is this .. I know it will be basic one that i missing out .. I am struggling to understand ? am i missing something very basic ?
When you create roles you would need to also specify a user since you made it a requirement that can cause errors

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": [...]
}

Any reason I am getting back the query name in the GraphQL results?

Using the makeExecutableSchema with the following Query definition:
# Interface for simple presence in front-end.
type AccountType {
email: Email!
firstName: String!
lastName: String!
}
# The Root Query
type Query {
# Get's the account per ID or with an authToken.
getAccount(
email: Email
) : AccountType!
}
schema {
query: Query
}
And the following resolver:
export default {
Query: {
async getAccount(_, {email}, { authToken }) {
/**
* Authentication
*/
//const user = security.requireAuth(authToken)
/**
* Resolution
*/
const account = await accounts.find({email})
if (account.length !== 1) {
throw new GraphQLError('No account was found with the given email.', GraphQLError.codes.GRAPHQL_NOT_FOUND)
}
return account
}
}
}
When I query with:
query {
getAccount(email: "test#testing.com") {
firstName
lastName
}
}
I am getting the following result in GraphiQL:
{
"data": {
"getAccount": {
"firstName": "John",
"lastName": "Doe"
}
}
}
So, any reason I am getting this "getAccount" back in the result?
Because getAccount is not a query name. It's just a regular field on the root query type Query.
And having results on the exact same shape as the query is one of the core design principles of GraphQL:
Screenshot from http://graphql.org/ site
Query name in GraphQL goes after query keyword:
query myQueryName {
getAccount(email: "test#testing.com") {
firstName
lastName
}
}

Resources