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

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.

Related

Contentful GraphQL endpoint: how to retrieve all entries of a content type

{
Post {
name
}
}
While trying to retrieve all the entries on a content type, it only gives error of:
"Argument \"id\" of required type \"String!\" was not provided."
Since id field is required. How do I get all entries of a content type then?
Ref: https://www.contentful.com/developers/docs/references/graphql/
From docs here:
The produced Query object exposes two fields that you can use to query content of that type: one to fetch individual content documents (friendlyUser in the example) and another to do queries over all the content of the type (friendlyUserCollection).
So for any resource that you want to retrieve all entries of, you need to append Collection at the end of its id, then use items field to retrieve all entries. As in:
{
PostCollection {
items {
name
}
}
}
Apart from docs, you can also view all available resources at corresponding GraphiQL instance here, which could be pretty useful:
https://graphql.contentful.com/content/v1/spaces/{SPACE_ID}/explore?access_token={ACCESS_TOKEN}
Search or select Query to see all schemas:
Query a single id
I think you can try this in the GraphQL playgound
http://localhost:8000/___graphql
query PostById($id: String!) {
contentfulPost(id: { eq: $id }) {
name
}
}
and add a QUERY VARIABLE
{
"id": "my-awesome-id"
}
Query all the Posts
How do I get all entries of a content type then?
On the GraphQL playground, you should be able to do something like this
{
allContentfulPost {
nodes {
name
}
}
}

How can I insert records in AwsAppSync mutation with proper #connection values?

I have added a resources table to my schema, connecting to a Plants table:
type Resource #model
{
id: ID!
name: String!
Plants: [Plant] #connection(name: "ResourcePlant")
}
Ran amplify push, and all resources were created properly.
Now I wanted to add a Resource, and link it to all Plants properly.
Do you know how is the sintaxe I should use to run the recently created mutation createResource in order to add the items on Plant I want to include to that resource?
I tried to run like this:
mutation CreateResource {
createResource (input: {
name: "Plant",
Plants : {
items :
{ id: "f9a0468e-da74-41d5-8287-1cb6a76b25a5" }
}
}
) {
name,
Plants {
items {
id
}
nextToken
}
}
}
This was the error message:
Validation error of type WrongType: argument 'input' with value
'ObjectValue{objectFields=[ObjectField{name='name',
value=StringValue{value='Plant'}}, ObjectField{name='Plants',
value=ObjectValue{objectFields=[ObjectField{name='items', value=ObjectValue{objectFields=[ObjectField{name='id',
value=StringValue{value='f9a0468e-da74-41d5-8287-1cb6a76b25a5'}}]}}]}}]}'
contains a field not in 'CreateResourceInput': 'Plants' # 'createResource'
How did you define Plant?
And have you checked this example? https://aws-amplify.github.io/docs/cli-toolchain/graphql#connection
Ok, after some headache, I found what was missing in my model. For me so far it has proved to be the best way of doing this relationship...
I have added on my Plant type, on schema definition, a field named plantResourceId (other than the one used for the #connection directive). What I found out was that, by convention, when inserting/updating a record on "Plant" and adding the resource "id" field content of the resource I want to "connect" to that plant, it will automatically be retrieved when "Resources" is queried, for each item - what is better: Out-of-the-box from codegen.
Insert example
mutation CreatePlant {
createPlant(input:{
name: "MyPlant",
plantResourceId: "id-for-connected-resource"
}) {
name,
plantResourceId
}
}
Query example to retrieve items:
query listPlantsOnResource {
listResources(filter: {
name: {
contains: "myfilter"
}
}) {
items {
id
name
Plants
{
items {
id
name
description
}
}
}
}
}
It worked very well!
Thanks all who contributed!

Cannot perform update query because update values are not defined

I am trying to execute a mutation like so
mutation creating {
createTeam(
payload: {
name: "Team von abc"
tacts:["94b4cbc2-b996-482f-b712-967bdb646e73"]
}
) {
id
name
}
}
This results in :
"message": "Cannot perform update query because update values are not
defined. Call \"qb.set(...)\" method to specify updated values.",
My graphql is defined like this:
input CreateTeamPayload {
name: String
tacts:[ID!]
}
type Team {
id: ID!
name: String
tacts: [Tact]!
}
type Query {
fetchTeams: [Team]!
fetchTeamById(id: ID!): Team
}
type Mutation {
createTeam(payload: CreateTeamPayload): Team!
}
My Team requires an ID from a "tact" so I provide him with an ID from a "tact" I created before. Is this approach wrong? How can I mutate types that reference other types? is there some documentation that actually does this?

Validation error of type UndefinedFragment: Undefined fragment

I've a graphql-jave v8.0 app running on Spring boot v1.5.10, and I'm trying to utilize 'fragment' feature of GraphQL to fetch limited number of fields with the following schema type definition:
type School {
id: ID
name: String
address: String
age: String
jobTitle: String
...
}
fragment UserFields on School {
age
jobTitle
}
type Query {
user (id: String!): School!
}
schema {
query: Query
}
When I execute this query:
{
user (id: "123")
{
... UserFields
}
}
The expected result should be:
{
"user": {
"age": "12",
"jobTitle": "student"
}
}
However, It results in the following error
"message": "Validation error of type UndefinedFragment: Undefined fragment
UserFields # 'user'",
Off course I can do this with explicitly passing the field name in the query but for the sake of example, I'm interested in utilizing fragment feature of GraphQL.
Any idea what I'm doing wrong please?
Fragments aren't defined in the schema, they're something for letting you create abstractions whilst building complex queries -- the main purpose is to allow you to avoid repetition when querying the same type in multiple parts of your query.
As Andrew said, and as the official docs exemplify, fragments are not defined in the schema but (ad hoc) in the query:
{
user (id: "123") {
... UserFields
}
}
fragment UserFields on School {
age
jobTitle
}
Unconditional fragments (like the one here) are used to avoid repetition. Imagine having multiple places where you want to select age and jobTitle in the same operation.
Conditional fragments, on the other hand, are used to make a conditional selection depending on the concrete interface implementation or union subtype.

How to expose graphql field with different name

I am exploring GraphQL and would like to know if there is any way of renaming the response field for example i have a POJO with these field
class POJO {
Long id;
String name;
}
GraphQL query:
type POJO {
id: Long
name: String
}
My response is something like this
{
"POJO" {
"id": 123,
"name": "abc"
}
}
Can i rename the name field to something like userName so that my response is below
{
"POJO" {
"id": 123,
"userName": "abc"
}
}
You can use GraphQL Aliases to modify individual keys in the JSON response.
If this is your original query
query {
POJO {
id
name
}
}
you can introduce a GraphQL alias userName for the field name like so:
query {
POJO {
id
userName: name
}
}
You can also use GraphQL aliases to use the same query or mutation field multiple times in the same GraphQL operation. This get's especially interesting when using field parameters:
query {
first: POJO(first: 1) {
id
name
}
second: POJO(first: 1, skip: 1) {
id
name
}
}
The question is: how are you creating the schema in the first place? There's no intrinsic connection between Java and GraphQL types - they are completely unrelated unless you correlate them. So you can name the fields any way you want in the schema, and make a resolver (DataFetcher) that gets the value from anywhere (thus any POJO field too).
If you're using a tool to generate the schema from Java types (graphql-java-annotations, graphql-spqr etc), then use that tool's facilities to drive the mapping. Both the mentioned tools allow customizing the mapping via annotations. GraphQL-SPQR enables the same via external configuration as well.
If you clarify your question further, I'll be able to give a more precise answer.
Looks like GraphQLName annotation can help.
Example from documentation :
"Additionally, #GraphQLName can be used to override field name. You can use #GraphQLDescription to set a description."
These can also be used for field parameters:
public String field(#GraphQLName("val") String value) {
return value;
}
I know this question is very old but following code is used for renaming the field:
public class ProductReviewType: ObjectGraphType<ProductReview>
{
public ProductReviewType()
{
Field(x => x.ProductReviewId, type: typeof(IdGraphType)).Description("some desc here");
Field(x => x.ProductId).Description("some desc here");
Field("reviewername", x => x.ReviewerName).Description("some desc here");
Field("reviewdate",x => x.ReviewDate).Description("some desc here");
Field("emailaddress", x => x.EmailAddress).Description("some desc here");
Field("rating", x => x.Rating).Description("some desc here");
Field("comments",x => x.Comments).Description("some desc here");
Field("modifieddate", x => x.ModifiedDate).Description("some desc here");
}
}
In the above code, modifieddate would be the field name for property "ModifiedDate".

Resources