join 3 tables using graphql query - graphql

I want to join 3 tables just like we do in mysql based on primary and foreign keys.
Can I do such using graphql(http://graphql.org/)
My table structure along with graphql query is below. Thanks
query($companyId:String){
Data{
reach{
department {
departmentId
departmentName
description
}
companyDepartment(companyId:$companyId) {
primaryId
departmentId
companyId
createdDate
modifiedDate
modifiedBy
}
company(companyId:$companyId) {
companyId
companyName
}
}
}
}

You must break your mind and think in Graph way model :)
Type Company(node) <- CompanyDepartmentConection (name of connection edge) -> Type Department(node)
based on this very useful article, anyway i do for you eg. Schema
Concept
interface Node {
id: ID!
name: String
}
type Company implements Node {
id: ID!
name: String
departmentsConnection: CompanyDepartmentConnection
}
type CompanyDepartmentConnection {
pageInfo: PageInfo!
edges: [CompanyDepartmentEdge]
}
type CompanyDepartmentEdge {
cursor: String!
node: Company
linkedAt: DateTime
}

Related

Search By Column in Laravel/Lighthouse GraphQL API

currently i'm creating a GraphQL implementation of an existing API.
i want to create Search Function not with primary column, which is not id, but id_position.
here is my scheme :
type Query #guard {
subordinate(
positionId: ID
): [Employee!]! #all
}
type Position #key(fields: "id") {
id: ID
name: String
}
"Account of a person who utilizes this application."
type Employee #key(fields: "id") {
id: ID
name: String
id_position: Int
}
but, when I run this :
query EmployeeSubordinate($id: ID) {
subordinate(positionId: $id) {
name
}
}
{
"id" : 93
}
I ve got result all rows of employee, not employee with id_position = 93
how to solve this?
I think the problem is here
type Query #guard {
subordinate(
positionId: ID
): [Employee!]! #all
}
The #all is getting all records from DB #all docs
The correct way is this
type Query #guard {
subordinate(
positionId: ID
): Employee
}
I removed ! from Employee because your ID is not required, so in some cases it masy return null, i you handle like thatin backend.
And alsoe I removed [] because you no longer getting many Employee you just getting one.

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
}
}
}
}
}''';

GraphQL alias top-level data into a nested object

Currently I’m querying the currentUser for a city.
query user {
currentUser {
city
}
}
However the requirements of my front-end requires the city as an object containing label and value.
// this doesn’t work, but is the idea…
query user {
currentUser {
city {
label: city
value: city
}
}
}
Is this possible to do at the GraphQL query level?
I haven't seen your database model, but you could have a City model, something like:
type City {
id: ID! #unique
label: String
value: String
}
Then, in your User model you could do something like this:
type User {
id: ID! #unique
.... other User fields
city: City
}
With that schema, you would be able to query the city values inside an user:
query user {
currentUser {
city {
label
value
}
}
}
You should adapt that to your needs, but that's the main idea that I think you are looking for.

Indexing List Type field in a GraphQL type from within a Query

Say I have the following GraphQL Schema
query {
allAuthors: [Author]
}
type Author {
id: ID!
name: String!
books: [Book]
}
type Book {
id: ID!
name: String!
author: Author!
}
Now I can successfully run the following query to get all the authors and their associated books
query {
allAuthors {
name,
books {
name
}
}
}
However, if I only want to get the first three books for all authors, how would I go about doing something like that? Can we index the books field in the Author type from within a query? If so, how?
I tried something like this and it doesn't work
query {
allAuthors {
name,
books[3] {
name
}
}
}
GraphQL doesn't have syntax for this.
You can add a "limit" parameter to a field, and this is common enough:
type Query {
allAuthors(limit: Int, offset: Int): [Author!]!
}
type Author {
id: ID!
name: String!
books(limit: Int, offset: Int): [Book!]!
}
If you add parameters like this to the schema, then the query you want (for all authors, get the first three books) could look like
{
allAuthors {
name
books(limit: 3) {
name
}
}
}

graphql - querying multiple tables

I am new to graphql and I need to query multiple tables at once to display some data. I have a dashboard that shows information on a home where it comes from 5 tables: address, person, hostinfo, room, and image. I initially have the person_id to query address table which contains the person_id etc... Here's what a brief scratch up of a uml looks like:
entity Address {
AddressId BigInteger,
FK_PersonId BigInteger,
StreetNumber Integer,
...
}
entity HostInfo {
HostInfoId BigInteger,
FK_AddressId BigInt,
HomestayName String,
...
}
entity Room {
RoomId BigInteger,
FK_HostInfoId BigInteger,
RoomName String,
...
}
entity Image {
FK_AddressId BigInt,
FK_RoomID BigInt,
Name String,
....
}
entity Person {
PersonId,
FirstName String,
Age Integer required, //TODO remember to check age
}
My question is, how do I use graphql to grab all the data from these tables using just PersonId?
EDIT--------
I refactored the typedefiniton as follows:
export type Address = {
StreetNumber: number,
//..
Person:Person
}
export type HostInfo = {
HomestayName: string,
//..
Person:Person,
Room:[Room!],
Address:Address
}
export type Room = {
RoomName: string,
//..
RoomImage:[RoomImage!],
HostInfo:HostInfo
}
export type RoomImage = {
Name: string,
//..
Room:Room,
}
export type HostInfoImage = {
Name: string,
..
HostInfo:HostInfo
}
export type PersonImage = {
Name: string,
//..
Person:Person
}
export type Person = {
FirstName: string,
..
PersonImage:[PersonImage]
Address:Address
}
and perform the query as so:
query HostInfo($id: ID!) {
node(id: $id) {
... on Person {
firstName
address {
streetNumber
hostInfo {
HostName,
//...
Room {
RoomName,
[RoomImage],
//....
}
}
}
}
}
}
I would explicitly show the relationship both ways in my entities... I was expecting more of a sql(ly) way to do it.
Typically GraphQL would represent all of the links between objects explicitly in the schema: if in your database model an Address references a Person, then your Person GraphQL type would have a list of addresses. In the GraphQL schema language, you might have:
type Person implements Node {
id: ID!,
firstName: String,
age: Int!,
address: [Address!]!
}
If you knew the ID of a person, a typical query to retrieve much of the available data might hypothetically look like
query Person($id: ID!) {
node(id: $id) {
... on Person {
firstName
age
address {
streetNumber
hostInfo { ... }
}
}
}
}

Resources