Linking schema in Apollor server 2 - graphql

I have a case that I'm not sure to implement, I have a REST API that returns an array of user IDs. Like this:
{
status: ""
"users": [
{
"userId": ID
},
{
"userId": ID
}
]
}
I want to have the ability to get the user details for each userID, so I want to pass the ID to another API that gets the user details.
The issue is that the second API returns the information as follows
{
status: ""
data:[{
Info:{
userId:
name:
...
}
Permissions{
...
}
...
}]
}
My issue is how can I represent this relation in the schema?
This is the schema I came up with:
Query{
EventUsersSummary(eventId: ID): EventResponse!
}
type EventResponse{
status: String!
users: [EventUser!]!
}
type EventUser {
userId: ID!
}
type User {
info: Info
permissions: Permissions
....
}
type Info{
userId: ID
firstName: String
lastName: String
email: Email
}
....
In the resolver for EventResponse I'm removing status from the result. In the resolver I plan to return the information for each user.

Related

Cant Return Array in Graphql Query

I'm pretty new to graphql and I'm working on a project in nodejs where I am trying to return users when a getUsers query is performed. The issue is that when I test this query in graphql studio, I'm getting an error stating: "GraphQLError: Cannot query field \"users\" on type \"User\". I'm really confused as to why I'm having this issue. I've seen a number of examples where people where able to return just an array and didn't have a problem, but every time I've tried this I end up getting a similar error. Due to this, I've only been able to return a value for a query or mutation when I am super specific such as for my user query:
...
const user = await requireAuth(user)
return {
_id: user._id,
username: user.username,
firstName: user.firstName,
email: user.email,
}
Does anyone know why this is happening? I would really appreciate any help or advice. Thank you!
Query getUsers in graphql,
{
getUsers {
users
}
}
Query in user-resolvers.js
getUsers: async(parent, args, context, info) => {
try {
let users = await User.find()
console.log(users)
// console.log(users) shows all of the users in the format found in type Users
return users;
}
catch (error) {
throw error;
}
},
schema.js
export default`
type Users {
_id: ID!
username: String
email: String!
firstName: String
lastName: String
basicInfo: [BasicInfo]!
avatar: String
date: Date
}
type BasicInfo {
birth_date: String!
age: Int!
feet: Int!
inches: Int!
}
...
type Query {
getUsers: [Users]
}
...
schema {
query: Query
mutation: Mutation
}
`;
index.js
import UserResolvers from './user-resolvers.js';
import User from '../../models/User.js';
export default {
Query: {
user: UserResolvers.user,
getUsers: UserResolvers.getUsers,
},
...
};
In the query you specify the fields you want to return and you don't have a field users, you must only specify fields that exist in your schema:
{
getUsers {
id
username
email
...
}
}
More info here

Graphql insert a child while indicating his parent

I'm very new into graphql but I'm able to insert a new "notification" that belongs to a "Tienda" which means store, however I'm not able to indicate to which store it belongs to.
This is the schema
type Tienda #model {
id: ID!
name: String!
cliente: [Cliente] #manyToMany(relationName: "clienteDeTienda")
news: [Notificacion] #hasMany
}
type Cliente #model {
id: ID!
name: String!
stores: [Tienda] #manyToMany(relationName: "clienteDeTienda")
}
type Notificacion #model {
id: ID!
store: Tienda #belongsTo
content: String!
}
This is how I insert a new notification:
const response = await API.graphql(graphqlOperation(createNotificacion, {input:data}))
This is what data has inside:
Object {
"content": "Nueva notificacion",
}
And this is the response I get from console.log(response):
Object {
"data": Object {
"createNotificacion": Object {
"content": "Nueva notificacion",
"createdAt": "2022-11-13T18:04:55.000Z",
"id": "9f50d333-fc9e-478f-be6a-c54275797a27",
"store": null,
"tiendaNewsId": null,
"updatedAt": "2022-11-13T18:04:55.000Z",
},
},
}
As you can see "content" was added to the notification but "store" is null but I haven't been successful in inserting the store ID in there.
This is how the mutations is defined:
export const createNotificacion = /* GraphQL */ `
mutation CreateNotificacion(
$input: CreateNotificacionInput!
$condition: ModelNotificacionConditionInput
) {
createNotificacion(input: $input, condition: $condition) {
id
store {
id
name
cliente {
nextToken
}
news {
nextToken
}
createdAt
updatedAt
}
content
createdAt
updatedAt
tiendaNewsId
}
}
`;
I've tried with the following 3 methods which give no error but still doesn't link to it's parent:
API.graphql(graphqlOperation(createNotificacion, {input:data, store:{id:'55988776-11af-42b8-b93b-9de9af35f7dc'}}))
And
API.graphql(graphqlOperation(createNotificacion, {input:data, store:'55988776-11af-42b8-b93b-9de9af35f7dc'}))
And:
API.graphql(graphqlOperation(createNotificacion, {input:data},{store:'55988776-11af-42b8-b93b-9de9af35f7dc'}))
Please somebody point me the right path or documentation about how to do this. I need to know how to perform the graphqlOperation correctly.
Thank you very much
In the end what I had to do is this:
const response = await API.graphql(graphqlOperation(createNotification, {input:{...data, storeNotificationsId:'someValidStoreId'}}));

Querying Many-To-Many Relationships in AWS Amplify

I have two models in my graphql schema and the one I am trying to query on, Sessions, has two #belongsTo directives (read on a forum this matters). I can successfully save these models and view them on the AWS AppSync Queries Tab where I can query getSessions successfully BUT when I try to the exact same query locally following these docs:
(https://docs.amplify.aws/lib/graphqlapi/advanced-workflows/q/platform/flutter/#combining-multiple-operations)
I get an error locally:
type "Null" is not a subtype of type 'string'
What am I doing wrong and how do I fix this so I can successfully retrieve my nested query:
Here are my models as a reference:
Sessions:
type Session
#model
#auth(
rules: [
{ allow: public }
{ allow: owner }
{ allow: groups, groups: ["Admin"] }
]
) {
id: ID!
name: String
numPeoplePresent: Int
notes: String
eIdReader: String
weighTiming: String
cows: [Cow] #manyToMany(relationName: "CowSession")
proceduresID: ID
procedures: Procedures #hasOne(fields: ["proceduresID"])
}
Cow:
type Cow
#model
#auth(
rules: [
{ allow: public }
{ allow: owner }
{ allow: groups, groups: ["Admin"] }
]
) {
id: ID!
name: String!
RfId: String
weight: [Float!]!
temperament: [Int]
breed: String
type: String
dateOfBirth: AWSDate
sessions: [Session] #manyToMany(relationName: "CowSession")
procedures: [Procedures] #manyToMany(relationName: "CowProcedures")
}
This is the query that is causing the error:
const getSession = 'getSession';
String graphQLDocument = '''query getSession(\$id: ID!) {
$getSession(id: \$id) {
numPeoplePresent
notes
name
eIdReader
id
owner
proceduresID
updatedAt
weighTiming
cows {
items {
cow {
RfId
}
}
}
}
}''';
final getSessionRequest = GraphQLRequest<Session>(
document: graphQLDocument,
modelType: Session.classType,
variables: <String, String>{'id': sessID}, //parameter of the current session can hardcode to whatever you need here
decodePath: getSession,
);
final response =
await Amplify.API.query(request: getSessionRequest).response;
print('Response: ${response.data}');
The wonderful people at amplify answered this quickly so I will relay the information here:
the problem was the intermediary ids were not included in my local query so it was unable to retrieve the nested Cows. Updated query looks like this:
getSession = 'getSession';
String graphQLDocument = '''query getSession(\$id: ID!) {
$getSession(id: \$id) {
numPeoplePresent
notes
name
eIdReader
id
owner
proceduresID
updatedAt
weighTiming
cows {
items {
id <-- needed this one
cow {
id <-- and this id too
RfId
breed
dateOfBirth
name
type
weight
}
}
}
}
}''';

Unable to fetch component data using Graphql in Strapi

I am building Graphql api with Strapi. It's a simple application which user can signup and save some of his/her information. I have two tables for that, User [Which is Strapi provided] and Profile which i use to store user additional information. The two tables has relationship
User [User has and belongs to one Profile]
Profile Profile has and belongs to one User and contact component structure.
I want to be able to fetch the current logged in user and it's information from Profile table, but the Contact field which i save as component type return null.
Here is what i am doing so far
extensions/user-permission/config/schema.graphql.js
module.exports = {
definition: `
extend type UsersPermissionsMe {
profile: ProfileMe
}
type ProfileMe {
id: ID!
website: String!
description: String!
contact: ContactMe
}
type ContactMe {
id: ID!
name: String!
phone: String!
email: String!
}
`
}
extensions/user-permission/services/User.js
'use strict';
module.exports = {
fetchAuthenticatedUser(id) {
return strapi.query('user', 'users-permissions').findOne({ id }, ['role', 'profile']);
},
};
And when run GraphQl Query
query {
me {
username
email
profile {
website
description
contact {
name
phone
email
}
}
}
}
it returned
{
"data": {
"me": {
"username": "company",
"email": "company#test.com",
"profile": {
"website": "http://localhost.com",
"description": "lorem text",
"contact": null
}
}
}
}
I want to also get contact data here. I hope someone on Internet can help me.
please help, thanks you.

Relation GraphQL

Trying to implement join but always getting null.
type User {
id: Int!
username: String!
recipes: [Recipe]
}
type Recipe {
id: Int!
title: String!
author: User
}
So basically i want to get data something like this:
User {
username,
recipes: [{//recipe}, {//recipe}]
}
And for Recipe i expecting
Recipe {
title,
author: {//user}
}
So i have query like below, and i want to get all recipes from database with included user
type Query {
recipes: [Recipe!]!
}
Here is my GraphiQL query
{
recipes {
id,
author {
id,
username
}
}
}
But in response i have author: null
{
"data": {
"recipes": [
{
"id": 1,
"author": null
}]
}
}
Any suggestions? Thanks!
Maybe somebody will face with similar issue.
Have fixed this. As said #Daniel Rearden in comments - yes issue was in resolver.
So you have to add this fields to resolver:
const resolverFunctions = {
User: {
recipes(author) {
return author.getRecipes();
}
},
Recipe: {
author(recipe) {
return recipe.getUser();
}
}
}
After you will get data what i needed above.

Resources