AppSync returns attribute values as null from AuroraDB - aws-appsync

I am trying to implement Appsync with Aurora RDS. Get query returns response with all the attribute values as null. I think it is able to connect with the DB properly because I have seen some error when I deliberately misspelled the table name. I am not sure where the problem is.
I tried the same implementation with Dynamodb and it worked fine. Is this some problem with resolver or something related to permissions?
Response looks like this:
Response:
{
"data": {
"getTest": {
"id": null,
"name": null,
"surname": null
}
}
}
DB table description with:
id int(11)
name text
surname text
AppSync GraphQL schema is:
type Query {
getTest(id: ID!): Test
}
type Test {
id: ID
name: String
surname: String
}
schema {
query: Query
}
Request resolver:
{
"version": "2018-05-29",
"statements": [
"select * from TestTable where id = '$ctx.args.id'"
]
}
Response resolver:
#if($ctx.error)
$utils.error($ctx.error.message, $ctx.error.type)
#end
$utils.toJson($utils.rds.toJsonObject($ctx.result)[0])

I was able to fix my issue. The problem was with referencing the result in response resolver. It worked after adding another [0] to the result object.
#if($ctx.error)
$utils.error($ctx.error.message, $ctx.error.type)
#end
$utils.toJson($utils.rds.toJsonObject($ctx.result)[0][0])

Related

Quarkus Panache MongoDB: Serialize ObjectId as String

I'm following the tutorials https://quarkus.io/guides/rest-data-panache and https://quarkus.io/guides/mongodb-panache to implement a simple MongoDB entity and resource with Quarkus Panache MongoDB.
Here's what I have so far:
#MongoEntity(collection = "guests")
class GuestEntity(
var id: ObjectId? = null,
var name: String? = null
)
#ApplicationScoped
class GuestRepository: PanacheMongoRepository<GuestEntity>
interface GuestResource: PanacheMongoRepositoryResource<GuestRepository, GuestEntity, ObjectId>
When running this, I can create a document by calling
POST localhost:8080/guest
Content-Type: application/json
{
"name": "Foo"
}
The response contains the created entity
{
"id": {
"timestamp": 1618306409,
"date": 1618306409000
},
"name": "Foo"
}
Notice, how the id field is an object whereas I would like it to be a string.
It turns out that the application was using quarkus-resteasy instead of quarkus-resteasy-jackson.
Once the proper dependency was in place, everything worked as expected
To serialize the id field as a String, apply the following annotation to the id field:
import com.fasterxml.jackson.databind.annotation.JsonSerialize
import io.quarkus.mongodb.panache.jackson.ObjectIdSerializer
#MongoEntity(collection = "guests")
class GuestEntity(
// important: apply the annotation to the field
#field:JsonSerialize(using = ObjectIdSerializer::class)
var id: ObjectId? = null,
var name: String
)
Now the response is
{
"id": "607567590ced4472ce95be23",
"name": "Foo"
}

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

Not sure what is wrong with my mongo db statement

I am trying to find the customers name with using the customer id.
this is my statement based on what I found in the mongo docs:
db.customer.find({"_id": "bf3Eva9zyWxJSaWK2"}, { "first_name": 1 });
but it is returning the id not name.
this is what I would do in sql:
SELECT first_name
FROM customer
WHERE _id = "bf3Eva9zyWxJSaWK2"
This seems straight forward but I cant seem to get what I need, Any help is appreciated.
to use db.customer.find({"_id": "bf3Eva9zyWxJSaWK2"}, { "first_name": 1 });
you must have to require const { ObjectID } = require('mongodb') or const ObjectID = require('mongodb').ObjectID
then you use db.customer.find({"_id": ObjctID("bf3Eva9zyWxJSaWK2")}, { "first_name": 1 });
you will also use find Query like this
db.customer.find({"_id": ObjctID("bf3Eva9zyWxJSaWK2")}, "first_name")
db.customer.find({"_id": ObjctID("bf3Eva9zyWxJSaWK2")}, ["first_name"])
If the _id is auto generated, you need to write the following statement.
db.customer.find({"_id": ObjectId("bf3Eva9zyWxJSaWK2")}, { "first_name": 1 });

Retrieve UserName from ServiceNow

I am able to retrieve records for a particular Incident ID using Invoke-RestMethod. However, while retrieving the data, values like Resolved To, Updated By, etc. get populated by a sysid.
Resolved By comes in this format:
https<!>://devinstance.servicenow.com/api/sysid, value= sysid
I would like to view the username instead of the sysid.
The 'User ID' (user_name) isn't on the Incident, it's on the sys_user table, so you'll have to dot-walk to it.
If you're using the table API, you'll need to specify a dot-walked field to return, using the sysparm_fields query parameter.
This is no problem, just specify your endpoint like this:
$uri = "https://YOUR_INSTANCE.service-now.com/api/now/table/incident?sysparm_query=number%3DINC0000001&sysparm_fields=resolved_by.user_name"
I've specified a query for a specific incident number is requested, but you can replace that with whatever your query is.The important part is sysparm_fields=resolved_by.user_name. You'll want to specify any other fields you need here, as well.
The JSON I get as a result of running this API call, is the following:
{
"result": [
{
"resolved_by.user_name": "admin"
}
]
}
Note the element name: "resolved_by.user_name".
Another option for doing this, would be to tell the API to return both display, and actual values by specifying the sysparm_display_value parameter and setting it to all to return both sys_id and display value, or just true to return only display values.
Your URI would then look like this:
https://dev12567.service-now.com/api/now/table/incident?sysparm_query=resolved_byISNOTEMPTY%5Enumber%3DINC0000001&sysparm_display_value=all
And your JSON would contain the following:
"number": {
"display_value": "INC0000001",
"value": "INC0000001"
},
"resolved_by": {
"display_value": "System Administrator",
"link": "https://YOUR_INSTANCE.service-now.com/api/now/table/sys_user/6816f79cc0a8016401c5a33be04be441",
"value": "6816f79cc0a8016401c5a33be04be441"
},
"sys_updated_by": {
"display_value": "admin",
"value": "admin"
},
This would be accessed by:
answer.result[n].resolved_by.display_value

Querying Postgres composite types from golang

So I am using go-gorp to query postgres and I can't seem to query the composite type inside my table is giving an error. All I want is appropriately nested JSON response. My postgres schema is:
CREATE TYPE PhoneType AS ENUM ('MOBILE', 'HOME', 'WORK');
CREATE TYPE PhoneNumber AS (
"Number" VARCHAR,
"Type" PhoneType
);
CREATE TABLE Person (
"Id" SERIAL PRIMARY KEY NOT NULL,
"Name" VARCHAR NOT NULL,
"Email" VARCHAR,
"Number" PhoneNumber[]
);
Correspondingly in golang, I have
const (
MOBILE PhoneType = iota
HOME
WORK
)
type PhoneNumber struct {
Number string
Type PhoneType
}
type Person struct {
Id int
Name string
Email string
PhoneNumber // not sure how to get array of phone numbers here
}
And to query, I am using go-gorp as follows:
dbmap := &gorp.DbMap{Db: db, Dialect: gorp.PostgresDialect{}}
var data []Person
_, err := dbmap.Select(&data, "SELECT * FROM Person")
the result I get has the format
{
"Id":
"Name":
"Email"
"Number": "{\"(..., ...)\"}"
"Type": 0
}
what I'm expecting is:
{
"Id":
"Name":
"Email":
"PhoneNumber": [{
"Number":
"Type":
}]
}
How can I change this nested composite type to the type friendly to my declaration in go?
EDIT: Looks like postres arrays and composite types become strings in go. How can I redesign the schema to achieve similar result?
your type declaration is wrong, try this for example:
type Phone struct {
Number string
Type PhoneType
}
type Person struct {
Id int
Name string
Email string
PhoneNumber []Phone
}