GraphQL Mutation with JSON Patch - graphql

Are there any data types in GraphQL that can be used to describe a JSON Patch operation?
The structure of a JSON Patch operation is as follows.
{ "op": "add|replace|remove", "path": "/hello", "value": ["world"] }
Where value can be any valid JSON literal or object, such as.
"value": { "name": "michael" }
"value": "hello, world"
"value": 42
"value": ["a", "b", "c"]
op and path are always simple strings, value can be anything.

If you need to return JSON type then graphql have scalar JSON
which return any JSON type where you want to return it.
Here is schema
`
scalar JSON
type Response {
status: Boolean
message: String
data: JSON
}
type Test {
value: JSON
}
type Query {
getTest: Test
}
type Mutation {
//If you want to mutation then pass data as `JSON.stringify` or json formate
updateTest(value: JSON): Response
}
`
In resolver you can return anything in json format with key name "value"
//Query resolver
getTest: async (_, {}, { context }) => {
// return { "value": "hello, world" }
// return { "value": 42 }
// return { "value": ["a", "b", "c"] }
// return anything in json or string
return { "value": { "name": "michael" } }
},
// Mutation resolver
async updateTest(_, { value }, { }) {
// Pass data in JSON.stringify
// value : "\"hello, world\""
// value : "132456"
// value : "[\"a\", \"b\", \"c\"]"
// value : "{ \"name\": \"michael\" }"
console.log( JSON.parse(value) )
//JSON.parse return formated required data
return { status: true,
message: 'Test updated successfully!',
data: JSON.parse(value)
}
},
the only thing you need to specifically return "value" key to identify to get in query and mutation
Query
{
getTest {
value
}
}
// Which return
{
"data": {
"getTest": {
"value": {
"name": "michael"
}
}
}
}
Mutation
mutation {
updateTest(value: "{ \"name\": \"michael\" }") {
data
status
message
}
}
// Which return
{
"data": {
"updateTest": {
"data": null,
"status": true,
"message": "success"
}
}
}

Related

How to read GraphQL enum values in AppSync resolver template?

I have an enum in my schema in the following way:
type Item {
name: String!
}
enum ItemType {
Simple
Advanced
}
input ValueSimple { simple: Int }
input ValueAdvanced { advanced: Int }
input InputItemSchedule {
type: ItemType!
valueSimple: ValueSimple
valueAdvanced: ValueAdvanced
}
mutation Mutation {
addItem(name: String!, schedule: [InputItemSchedule]!): Item
}
I am trying to do conditional checks in the AppSync resolver template (data source id DynamoDB) but I don't know how to get the value for the item type:
#set($schedule = {})
#foreach($item in $context.args.schedule)
#set($scheduleItem = { })
#if($item.type == "Simple")
#set($scheduleItem.value = $item.valueSimple)
#elseif($item.type == "Advanced")
#set($scheduleItem.value = $item.valueAdvanced)
#else
## Set the type value to value for testing purposes
#set($scheduleItem.value = $util.dynamodb.toDynamoDBJson($item.type))
#end
$util.qr($schedule.add($scheduleItem))
#end
{
"version" : "2017-02-28",
"operation" : "PutItem",
"key" : {
"id": $util.dynamodb.toDynamoDBJson($util.autoId()),
},
"attributeValues" : {
"name": $util.dynamodb.toDynamoDBJson($ctx.args.name),
"schedule": $util.dynamodb.toDynamoDBJson($schedule)
}
}
When I make a request that triggers the resolver regardless of the enum value, I keep getting the following in DynamoDB:
...
"value": {
"S": "null"
}
How am I supposed to read the GraphQL enum value from the resolver template?

Customize AWS-Appsync subscription response data

In my case, I have an app that users can subscript to some in-app events.
I want to call a mutation from one of my microservices and send several user ids as a list to the mutation, and then all clients that subscript to that mutation receive '[1]'.
schema
type Mutation {
setUsersAlarm(user_id: [Int]): UserIDList
}
type Subscription {
subscripesetUsersAlarm: UserIDList
#aws_subscribe(mutations: ["setUsersAlarm"])
}
type UserIDList {
id_list: [Int]
}
schema {
query: Query
mutation: Mutation
subscription: Subscription
}
Mutation Resolver
request template
{
"version": "2017-02-28",
"payload":$util.toJson($context.args["user_id"])
}
response template
{
"id_list":$util.toJson($context.result)
}
Subscription Resolver
request template
{
"version": "2017-02-28",
"payload": {
"hello": "local",
}
}
response template
$extensions.setSubscriptionFilter({
"filterGroup": [
{
"filters" : [
{
"fieldName" : "id_list",
"operator" : "contains",
#* I can get the value from cognito or from
user input arguments*#
"value" : 10
}
]
}
]
})
#set ($myList = [1])
#set( $ctx.result.id_list =$myList)
$util.toJson($ctx.result)
Query
subscription MySubscription {
subscripesetUsersAlarm {
id_list
}
}
mutation MyMutation {
setUserRefreshToken(user_id: [10, 12]) {
id_list
flg
}
}
Output of mutation
{
"data": {
"setUsersAlarm": {
"id_list": [
10,
12
]
}
}
}
Output of subscription
I want to receive the below result in subscription:
{
"data": {
"subscripesetUsersAlarm": {
"id_list": [1]
}
}
}
but I receive this:
{
"data": {
"subscripesetUsersAlarm": {
"id_list": [
10,
12
]
}
}
}
I want to customize the subscription response depending on my clients

How to create a ResponseBody without an "entity" tag

I have built a controller which returns a list of objects
fun getUserCommunicationSettings(
#PathVariable commId: String,
#CommunicationTypeConstraint #RequestParam(required = false) commType: CommunicationType?
): ResponseEntity<out UserCommResponse> {
return communicationSettingsService.getUserCommSettings(commType, commId)
.mapError { mapUserCommErrorToResponse(it) }
.map { ResponseEntity.ok(SuccessResponse(it)) }
.fold<ResponseEntity<SuccessResponse<List<CommunicationSettingsDto>>>, ResponseEntity<ErrorResponse>, ResponseEntity<out UserCommResponse>>(
{ it },
{ it },
)
}
problem is it returns the following json with "entity" tag which i'd like to get rid of
{
"entity": [
{
"userId": "1075",
"userType": "CUSTOMER",
"communicationId": "972547784682",
"communicationType": "CALL",
"messageType": "CALL_COLLECTION"
}
]
}
any ideas?

Loopback : Validate model from another model is not returning proper error message

I am validating model from another model like below
Model.addFavorite = function (data, callbackFn) {
if (data) {
var faviroteModel = this.app.models.Favorite;
var objFavorite = new faviroteModel(data);
objFavorite.isValid(function (isValid) {
if (isValid) {
callbackFn(null, objFavorite);
}
else {
callbackFn(objFavorite.errors);
}
});
}
else callbackFn("Post data required", {});
}
If i do this then I am getting error like below
{
"error": {
"statusCode": 500,
"t": [
"is not a valid date"
]
}
}
It should be with error message like below
{
"error": {
"statusCode": 422,
"name": "ValidationError",
"message": "The `Favorite` instance is not valid. Details: `t` is not a valid date (value: Invalid Date).",
"details": {
"context": "Favorite",
"codes": {
"t": [
"date"
]
},
"messages": {
"t": [
"is not a valid date"
]
}
}
}
}
Can anyone tell me what am i missing here.
How can i achieve this.
https://github.com/strongloop/loopback-datasource-juggler/blob/master/lib/validations.js#L843
You might run into situations where you need to raise a validation
error yourself, for example in a "before" hook or a custom model
method.
if (model.isValid()) {
return callback(null, { success: true });
}
// This line shows how to create a ValidationError
var err = new MyModel.ValidationError(model);
callback(err);
}

How to assign a single object to a list?

I'm working with an API rest and it returns me two types of json, object and array.
Object(When there is only one record in the database):
{ "complain": { "id": "1" , "description": "hello", "date": "2017-01-24 11:46:22", "Lat": "20.5204446", "Long": "-100.8249097" } }
Array(When there is more than one record in the database):
{ "complain": [ { "id": "1" , "description": "hello", "date": "2017-01-24 11:46:22", "Lat": "20.587446", "Long": "-100.8246490" }, { "id": "2" , "description": "hello 2", "date": "2017-01-24 11:50:12", "Lat": "20.529876", "Long": "-100.8249097" } ] }
The code I use to consume the json is as follows:
content = await response.Content.ReadAsStringAsync();
var token = JToken.Parse(content);
if (token["complain"] is JArray)
{
var jsonArray = JsonConvert.DeserializeObject<RootArray>(content);
}
else if (token["complain"] is JObject)
{
var jsonObject = JsonConvert.DeserializeObject<RootObject>(content);
}
When it comes to a json array if I can add it to a listview:
myList.ItemsSource = jsonArray.listArray;
But if it is an object I can not and I get the following error:
Cannot implicitly convert type Object to IEnumerable.
Finally I was able to solve my error, it was just a matter of creating a list and adding the deserialized json object.
var jsonObject = JsonConvert.DeserializeObject<RootObject>(content);
List<Complain> simpleList = new List<Complain>();
simpleList.Add(jsonObject.ComplainObject);
myList.ItemsSource = simpleList;
The class to deserialize the Json object:
public class RootObject
{
[JsonProperty("complain")]
public Complain ComplainObject { get; set; }
}

Resources