I have some groups created by users in my database. Each group has multiple members in it. This is what a typical group looks like:
{
"groupName": "some-group-name",
"userIds": ["001", "002", "003"]
}
I also have a separate node of users in my database. This is what a user looks like:
{
"id": "001",
"userName": "some-unique-username"
}
I want to list every single group and its members. So, it would be:
group1
user1 id; user1 name;
user2 id; user2 name;
group2
user3 id; user3 name;
user4 id; user4 name;
and so on...
How would it be possible (if at all) to fetch these groups and their user ids and also query for users by id and return a single JSON containing all the data only with one request?
Right now I'm just fetching some amount of groups and iterating over the userIds of each of them and sending a request for each user separately.
I'm not asking about pagination or simple querying, I just want to get every group and the users inside those groups.
Figured it out myself.
What I needed to do was to create a separate resolver for fetching members of each group:
resolvers: {
...
Group: {
members: (group, _, context) => group.members.map(memberId => context.db.findUserById(memberId)
}
...
}
The parent group object is passed as the first argument to the resolver so when I query:
{
groups(count: 10){
name
members {
name
}
}
}
It returns the names of the first 10 groups along with its members' names.
With the following schema,
type User {
name: String
firstName: String
location: String
}
type Group {
groupname:String!
users:[User!]
}
type Query {
groups:[Group!]
group(name: String): Group
}
the following query:
{
groups
{
groupname
users {
name
firstName
location
}
}
}
could return
{
{ name: "group1",
users: [{name:"user1", firstName:"firstName1", location:"Localtion1"},
{name:"user2", firstName:"firstName2", location:"Localtion2"}]
},
{ name: "group2",
users: [{name:"user1", firstName:"firstName1", location:"Localtion1"}]
},
...etc..
}
Hope this helps,
Related
My schema defines an Employee type that has 15 or so fields on it. It's then used multiple times in other areas:
type Employee {
active: Boolean!
name: String
id: Int!
...
}
type Room {
owner: Employee!
delegate: Employee
}
99% of the time, I want the same three fields when returning data on an employee. So I end up writing a query like this:
query {
rooms {
owner: {
name
id
active
}
}
}
which is repetative when something has multiple employees. Is there a way to define some type of transformation so that instead I'd do something like:
query {
rooms {
owner: #commEmpFields
}
}
My initial thought was to create a custom ObjectType<Employee> but then I realized that I didn't know how to map that to the query.
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
}
}
}
}
}''';
I have a User model along UserRelationship model
I have created trainer/client relationship with the UserRelationship model.
model User {
id Int #id #default(autoincrement())
trainerRelationship UserRelationship[] #relation("trainer")
traineeRelationship UserRelationship[] #relation("trainee")
}
model UserRelationship {
id Int #id #default(autoincrement())
trainerId Int?
traineeId Int?
trainerUser User? #relation("trainer", fields: [trainerId], references: [id])
traineeUser User? #relation("trainee", fields: [traineeId], references: [id])
}
I am able to query the user also able to query their relationship
For eg:
const trainer = await client.user
.findUnique({ where: { id }, include: { trainerRelationship: true } })
The output i am getting here is like:
{
id: 1,
username: hellouser
trainerRelationship: [
{
id: 4,
trainerId: 1,
traineeId: 34
}
]
}
Now i want to fetch the details of the traineeId/trainerId user details, What should be my query?
Ok, so I have solved it by the below query, incase someone is stuck:
.findUnique({ where: { id } }).trainerRelationship({
include: {
trainerUser: true,
},
})
Maybe the title is not accurate but I really don't know how to describe it anymore. I went through multiple documentations and descriptions but still couldn't figure it out.
I want to implement a basic social media like followers/following query on my type User. I am using MySQL and for that I made a separate table called Follow as it's a many-to-many connection.
Here is a pseudo-ish representation of my tables in the database without the unnecessary columns:
Table - User
user_id primary key Int
Table - Follow
follow_er foreign_key -> User(user_id) Int
follow_ed foreign_key -> User(user_id) Int
A user could "act" as a follow_er so I can get the followed people
And a user could be follow_ed, so I can get the followers.
My prisma schema look like this:
model User {
user_id Int #id #default(autoincrement())
following Follow[] #relation("follower")
followed Follow[] #relation("followed")
}
model Follow {
follow_er Int
follower User #relation("follower", fields: [follow_er], references: [user_id])
follow_ed Int
followed User #relation("followed", fields: [follow_ed], references: [user_id])
##id([follow_er, follow_ed])
##map("follow")
}
By implementing this I can get the followers and following object attached to the root query of the user:
const resolvers = {
Query: {
user: async (parent, arg, ctx) => {
const data = await ctx.user.findUnique({
where: {
user_id: arg.id
},
include: {
following: true,
followed:true
}
})
return data
}....
Here is my GraphQL schema I tried to make:
type Query{
user(id: Int!): User
}
type User{
id: ID
following: [User]
followed: [User]
}
So I can get something like:
query {
user(id: $id) {
id
following {
id
}
followed{
id
}
}
}
}
But I couldn't make it work as even if I get the the array of objects of {follow-connections}:
[
{
follow_er:1,
follow_ed:2
},
{
follow_er:1,
follow_ed:3
},
{
follow_er:3,
follow_ed:1
},
]
I can't iterate through the array. As far as I know, I have to pass either the follow_er or follow_ed, which is a user_id to get a User object.
What am I missing? Maybe I try to solve it from a wrong direction. If anybody could help me with this, or just tell me some keywords or concepts I have to look for it would be cool. Thanks!
I would suggest creating self-relations for this structure in the following format:
model User {
id Int #id #default(autoincrement())
name String?
followedBy User[] #relation("UserFollows", references: [id])
following User[] #relation("UserFollows", references: [id])
}
And then querying as follows:
await prisma.user.findUnique({
where: { id: 1 },
include: { followedBy: true, following: true },
})
So you will get a response like this:
I am looking for something like the below pseudo query:
query users($ids: [String!]) {
"id from $ids": getUser(id){
id
name
dob
}
}
To get a response like:
data: {
'039ccf5c-3070-4368-b790-0884669e759d': {id: '039ccf5c-3070-4368-b790-0884669e759d', name: 'u1', 'dob': 12-12-12'},
'139ccf5c-3070-4368-b790-0884669e759d': {id: '139ccf5c-3070-4368-b790-0884669e759d', name: 'u1', 'dob': 12-12-12'},
}
Is this possible?
You can use aliases to query to the same field multiple times:
query users($id1: String!, $id2: String!) {
user1: getUser(id: $id1) {
...UserFragment
}
user2: getUser(id: $id1) {
...UserFragment
}
}
fragment UserFragment on User {
id
name
dob
}
There are no control structures in GraphQL, so there's no way to loop through a value that is a list. If your list of IDs is of variable length, then you'll have to construct a query similar to the above programmatically, dynamically generating both the variable definitions and the aliased fields.