Usage of GET with request body with GraphQL - rest

I am using REST API GET with payload ( passing input params ) and it returns with JSON response.
I need to convert it into GraphQL, I have the schema and types defined,
but how to merge GET request payload along with GraphQL query JSON and process it to get the desired response back?
Example GET: http://localhost/myproject/getAllCustomers
payload :
{
"name":"Harish"
"passion":"reading"
}
GraphQL query :
{
customer {
name
age
city
}
}

You pass variable to GraphQL query arguments
Query:
query getCustomer($name: String, $passion: String) {
customer(name: $name, passion: $passion) {
name
age
city
}
}
Variable:
{
"name": "Harish",
"passion": "reading"
}

Related

How to return a string from a GraphQL mutation wrapped on restApi?

My restAPI POST call return a uuid string as result, like so:
246f97e8-cdc8-4b01-9881-19278be7e33d
This API is wrapped with GraphQL. The mutation I wrote for this post method works fine, I can see it gets triggered and return a 200 status.
The only problem is that I cannot return that same string as the mutation result. This is what I have:
mutation myMutation($input: any) {
myMutation(input: $input)
#rest(type: "type", path: "apiPath", method: "POST", endpoint: "myEndpoint")
{
id
}
}
That id return an integer and any other value I add besides id return "null".
Any idea on how I can get that uuid through the mutation?

must have a selection of subfields. Did you mean \"createEvent { ... }\"?", [graphql] [duplicate]

Hi I am trying to learn GraphQL language. I have below snippet of code.
// Welcome to Launchpad!
// Log in to edit and save pads, run queries in GraphiQL on the right.
// Click "Download" above to get a zip with a standalone Node.js server.
// See docs and examples at https://github.com/apollographql/awesome-launchpad
// graphql-tools combines a schema string with resolvers.
import { makeExecutableSchema } from 'graphql-tools';
// Construct a schema, using GraphQL schema language
const typeDefs = `
type User {
name: String!
age: Int!
}
type Query {
me: User
}
`;
const user = { name: 'Williams', age: 26};
// Provide resolver functions for your schema fields
const resolvers = {
Query: {
me: (root, args, context) => {
return user;
},
},
};
// Required: Export the GraphQL.js schema object as "schema"
export const schema = makeExecutableSchema({
typeDefs,
resolvers,
});
// Optional: Export a function to get context from the request. It accepts two
// parameters - headers (lowercased http headers) and secrets (secrets defined
// in secrets section). It must return an object (or a promise resolving to it).
export function context(headers, secrets) {
return {
headers,
secrets,
};
};
// Optional: Export a root value to be passed during execution
// export const rootValue = {};
// Optional: Export a root function, that returns root to be passed
// during execution, accepting headers and secrets. It can return a
// promise. rootFunction takes precedence over rootValue.
// export function rootFunction(headers, secrets) {
// return {
// headers,
// secrets,
// };
// };
Request:
{
me
}
Response:
{
"errors": [
{
"message": "Field \"me\" of type \"User\" must have a selection of subfields. Did you mean \"me { ... }\"?",
"locations": [
{
"line": 4,
"column": 3
}
]
}
]
}
Does anyone know what I am doing wrong ? How to fix it ?
From the docs:
A GraphQL object type has a name and fields, but at some point those
fields have to resolve to some concrete data. That's where the scalar
types come in: they represent the leaves of the query.
GraphQL requires that you construct your queries in a way that only returns concrete data. Each field has to ultimately resolve to one or more scalars (or enums). That means you cannot just request a field that resolves to a type without also indicating which fields of that type you want to get back.
That's what the error message you received is telling you -- you requested a User type, but you didn't tell GraphQL at least one field to get back from that type.
To fix it, just change your request to include name like this:
{
me {
name
}
}
... or age. Or both. You cannot, however, request a specific type and expect GraphQL to provide all the fields for it -- you will always have to provide a selection (one or more) of fields for that type.

How to write JOIN in graphQL or get result from multiple types - AWS App sync iOS

I am using AWS AppSync for a chat app in one of the my applications. We are able to do setup and basic query successfully.
In one of the case I need to write a customized GraphQL query so that I can have additional data using reference of one type from another. For example, I can have allMessageGroup from a user and also allMessages from a particular group.
Now I want to add the last message in the group and its sender with the list of all message group just like what's app home page.
But I am not able to understand how make JOIN or write such query which give mixed results based on Conversation/Message/User types/table.
Platform:iOS
Language: Swift
For detail below is my Schema and API/Query I am using
Schema
type Conversation {
conversation_cover_pic: String
conversation_type: String!
createdAt: String
id: ID!
messages(after: String, first: Int): MessageConnection
name: String!
privacy: String
}
type Message {
author: User
content: String!
conversationId: ID!
createdAt: String
id: ID!
recipient: User
sender: String
}
type MessageConnection {
messages: [Message]
nextToken: String
}
Query
query getUserConversationConnectionThroughUser($after: String, $first: Int)
{
me
{
id
__typename
conversations(first: $first, after: $after)
{
__typename
nextToken
userConversations
{
__typename
userId
conversationId
associated
{
__typename
userId
}
conversation
{
__typename
id
name
privacy
messages
{
__typename
id
conversationId
content
createdAt
sender
isSent
}
}
}
}
}
}
It sounds like you need multiple requests to one or more datasources to fulfill this graphQL query. In this case, you can use AppSync's pipeline resolver feature.
With pipeline resolvers, you can create multiple functions, each of which can use the results of the previous function and query a database. These functions run in an order you specify.
An example of something you could do with a pipeline resolver:
One function will query the chat group database
A second function will use the results of the chat group to fetch messages
Consolidate all the results into one graphQL response containing group information and messages
Here is the documentation for pipeline resolvers: https://docs.aws.amazon.com/appsync/latest/devguide/pipeline-resolvers.html

Appsync missing resolver

I'm using AWS appsync + DynamoDB.
The problem: I created the new field 'rating' in my 'Users' schema:
type Users {
id: ID!
first: String!
last: String!
rating: String #<----The new field
}
AppSync created all the resources and I can create new records with Mutations and that works like a charm.
mutation createUsers{
createUsers(input:{
first:"John"
last:"Smith"
rating:"B" #<---Writing new field without problem
}){
id
first
last
rating #<---Confirming that is recorded in DynamoDB
}
}
The problem is that I can't figure out how to write the resolver to make the following query work.
query{
queryUsersByRating(rating: "B"){
items{
id
username
rating
}
}
}
The result is this:
{
"data": {
"queryUsersByRating": null
}
}
The problem is clearly identified here under "Missing Resolver", but there's no clear solution.
I tried attaching the following Resolver directly in AppSync interface but is not working:
{
"version" : "2017-02-28",
"operation" : "Query",
"query" : {
"expression": "rating = :rating",
"expressionValues" : {
":rating" : $util.dynamodb.toDynamoDBJson($ctx.args.rating)
}
}
}
Any help would be appreciated, THANKS!
You don't have to write your own resolver for querying by rating, Appsync wrapped all the fields inside filter.
query{
queryUsersByRating(filter: {rating: "B"}){
items{
id
username
rating
}
}
}

Rest API get resource id by field

What is a correct rest way of getting a resource ID by a field, for example a name. Take a look at the following operations:
GET /users/mike-thomas
GET /users/rick-astley
I don't want to use these operations at my API end, instead I want to write an API operation that will get me the ID when submitting a field (name in the case of users) for example:
GET /users/id-by-field
Submitted data:
{
"fullName": "Mike Thomas"
}
Return data:
{
"data": {
"id": "123456789012345678901234"
}
}
What you want is known as an algorithmic URL where the parameters for the algorithm are passed as URL parameters:
GET /users?name="Mike Thomas"
Advantages are that you are using the "root" resource (users) and the search parameters are easily extended without having to change anything in the routing. For example:
GET /users?text="Mike"&year=1962&gender=M
where text would be searched for in more than just the name.
The resultant data would be a list of users and could return more than the identification of those users. Unless fullName uniquely identifies users, that is what you need to allow for anyway. And of course the list could contain a single user if the parameters uniquely identified that user.
{
users: [
{
id: "123456789012345678901234",
fullName: "Mike Thomas",
dateJoined: 19620228
}
, {
id: "234567890123456789012345"
fullName: "Rick Astley",
dateJoined: 19620227
}
]
}