How to write resolver for my query with Spring GraphQL - spring

I need help in writing resolver for my GraphQL query with Spring.
problem is that each of the objects you see here are being passed from different API and I need to combine them with defined dependency. Since Graphql automatically calls instance api for each customer, I am not sure how to write resolver which can filter customers based on certain instance name
Here is my schema query and schema.graphqls
customers(filter: {tenant: {instance: {instanceName: "ABC"}}}){
tenants{
tenantId
instance{
instanceName
}
}
}
}
schema
type Customer{
customerName: String
tenants: [Tenant]
}
type Tenant{
tenantId: ID
instance: Instance
}
type Instance{
instanceId: ID
instanceName: String
}
type Query{
customers(filter: CustomerFilterInput): [Customer]
}
input CustomerFilterInput{
customerName: String
tenant: TenantInput
}
input TenantInput{
tenantId: String
instance: InstanceInput
}
input InstanceInput{
instanceName: String
instanceId: String
}

Related

Querying all objects in Amplify mock api and getting null

I am using Amplify in a simple use case to mock an existing frontend. I have a cutdown schema.graphql as follows:
input AMPLIFY { globalAuthRule: AuthRule = { allow: public } }
schema {
query: Query
}
type Query {
getAirports: [Airport]
}
type Airport #model {
id: Int! #primaryKey
code: String!
city: String!
country: String!
}
The getAirports query is intended to return all the airports. I run amplify mock api and it generates all the resolvers.
When I navigate to http://localhost:20002, I can see the option to use getAirports, however it returns null even when data is present in the mocked database. The response is
{"data":null,"errors":[{"message":"Cannot return null for non-nullable field Query.getAirports.","locations":[{"line":2,"column":3}],"path":["getAirports"]}]}
I'm curious how I can write the schema to have a getAirports query in a way that it returns data a full list of Airports similar to listAirports which is created by default.

Define more than one type of query GraphQL Schema - Best approach to define different types on query one one object

Is this possible to specify more than one type of query in one schema?
type Query {
productsByRegion(match : String) : [Product]
productsByType(match : String) : [Product]
}
type Product {
id: ID
name: String
}
Expected queries which can be fired using single schema definition:
{
productsByRegion {
id
name
}
}
{
productsByType {
id
name
}
}
GraphQL java implementation cached some data. After server, restart both the query works fine.

Nested field resolvers in GraphQL

The goal is to use NestJS to implement a GraphQL schema using the code-first approach.
Let's say I have a Pet type in my GraphQL schema with two fields, name and age. If those two pieces of information come from different sources of truth (and I don't always want to fetch both), I could implement a PetResolver class with resolvers for each field:
#Resolver(() => Pet)
export class PetResolver {
#Query(() => Pet)
pet(): Pet {
return {};
}
#ResolveField()
name(): Promise<string> {
return Promise.resolve('Spot');
}
#ResolveField(() => Int)
age(): Promise<number> {
return Promise.resolve(2);
}
}
which could be used like this:
query GetPet {
pet {
name
}
}
This works and would ensure that the value of each field is only fetched when requested, but what if I wanted to have a pet field on my User type that I could query like this:
query GetUserWithPet {
currentUser {
email
pet {
name
}
}
}
Applying the same principle, I could create a UserResolver class like this:
#Resolver(() => User)
export class UserResolver {
#Query(() => User)
#UseGuards(AuthCognitoGuard)
currentUser(#CurrentUser() user: IdTokenPayload): User {
return {
id: user.sub,
email: user.email,
};
}
#ResolveField()
pet(#Parent() user: User): Promise<Pet> {
return petService.getPetForUserId(user.id);
}
}
but then the PetService implementation would have to be aware of which fields were requested if it only wanted to fetch relevant data.
A) Is there a way to use PetResolver within UserResolver to make use of the individual field resolution logic?
B) If not, what is the best way to determine which fields were requested in the query using NestJS code-first conventions?
C) Is this the "wrong" way to think about GraphQL queries? Do best practices dictate that I keep the separate resolver and use a query like this:
query GetUserWithPet {
currentUser {
email
}
pet {
name
}
}
User should contain some petIds [array] value (internal, DB stored field/column) ...
... making possible to resolve pets: [Pet] prop/relation - list of Pet ...
... like starshipIDs explained in https://graphql.org/learn/execution/
Notice: pets service is asked about records using pet ids.
... but of course pet can contain some ownerId (only or explicitely visible, DB stored field/column) making possible to resolve owner: User prop [reverse] relation - this way you can:
query PetWithOwner {
pet (id: "someID") {
id
name
owner {
id
email
# more pets?
pets {
id
name
# you can loop it ;)
owner {
id
email
pet.owner field resolver can return only { id: ownerId } object (partial response) ... server will try to resolve 'missing' (required by query) email prop using User (owner is User type) type resolver, passing id as an arg (check/console.log parent and args resolver args). You don't have to do it [the same] 'manually' inside pet.owner field resolver.
Query required fields ...
... [selection set] can be read from info object - 4th resolver arg - read docs/tutorial for details

GraphQL: Nesting Reusable Interface Fragment within a Type Fragment

I'm new to GraphQL and Apollo Client.
I'm trying to write DRY queries as much possible and found that Fragments can be of great help.
Here is how my GraphQL schema would look like:
interface header { # Implemented by multiple types
uuid: ID!
created_at: DateTime
created_by: String
updated_at: DateTime
updated_by: String
}
type account implements header #withSubscription {
id: String! #id #search(by:[term])
name: String #search(by:[fulltext])
description: String #search(by:[fulltext])
...
}
on the client side, I'm trying to setup my operations.graphql as follows:
fragment headerData on header {
uuid
created_at
created_by
updated_at
updated_by
}
fragment accountNode on account {
...headerData
id
name
description
#.. rest of the fields
}
query getPaginatedAccounts(first: Int, offset: Int) {
queryaccount {
...accountNode
# .. rest of the fields
}
}
However, when I execute the query, the results set doesn't fetch any data from the accountNode fragment.
Is this correct way to nest the fragments?
I realize that if I change the accountNode fragment as follows, it works and gets me the data:
fragment accountNode on account {
... on header {
uuid
created_at
#..rest of header fields
}
id
name
description
#.. rest of the fields
}
But since header interface is implemented by multiple types, its not DRY to repeat those fields on every Type Fragment.
Thanks in advance.

Datafetcher for nested types in graphql

I am using graphql and graphql-java for a simple API that fetches projects and its assignee
schema {
query: Query
}
type Query {
projects: [Project]
users: [User]
}
type Project {
id: ID!
name: String
assignee : User
status: String
}
type User {
id: ID!
name: String
}
I already have following resolvers:
private RuntimeWiring buildRunTimeWiring() {
return RuntimeWiring.newRuntimeWiring()
.type("Query", typeWiring -> typeWiring
.dataFetcher("projects", allProjectsDataFetcher)
.dataFetcher("users", allUserDataFetcher)
).build();
}
How should I write my resolvers so that when I query
projects {
id
name
assignee
}
it should return projects and its assignees. Is it even possible ?
Not sure about your resolver code (which looks good to me) and hope its resolves Project and associated assignee inside that object, I see problem in your graphQL schema (if you are expecting list of users). It should look like ...
type Project {
id: ID!
name: String
assignee : [User]
status: String
}
Make sure you return Object which should look like
{id:1, name:"someName",status:"Active", assignee :[{id:003, name:"A"}, {id:004, name:"B"}]}

Resources