ValidationException in lambda API - node.js

I have the following code:
function updateComplaint(complaints) {
return API.put("kleen", `/Complaint/${state.complaint[0].id}`, {
body: state.complaint[0]
});
}
but when ever I run it, I get the following error:
This is the table I am trying to edit:
What am I doing wrong and what should my code look like?
Code for my API:
import * as dynamoDbLib from "./libs/dynamodb-lib";
import { success, failure } from "./libs/response-lib";
export async function main(event, context) {
const data = JSON.parse(event.body);
const params = {
TableName: process.env.tableName,
// 'Key' defines the partition key and sort key of the item to be updated
// - 'userId': Identity Pool identity id of the authenticated user
// - 'noteId': path parameter
Key: {
typeName: event.requestContext.identity.typeName,
id: event.pathParameters.cognitoIdentityId
},
// 'UpdateExpression' defines the attributes to be updated
// 'ExpressionAttributeValues' defines the value in the update expression
UpdateExpression: "SET adminComment = :adminComment, updatedAt = :updatedAt",
ExpressionAttributeValues: {
":updatedAt": Date.now() || null,
":adminComment": data.adminComment || null
},
// 'ReturnValues' specifies if and how to return the item's attributes,
// where ALL_NEW returns all attributes of the item after the update; you
// can inspect 'result' below to see how it works with different settings
ReturnValues: "ALL_NEW"
};
try {
await dynamoDbLib.call("update", params);
return success({ status: true });
} catch (e) {
console.log(e);
return failure({ status: false });
}
}

Related

Why this return is null and not correct?

import { prisma } from "../../../database/prismaClient"
interface IDeleteHouseRequest {
id: string
tenantId: string
}
export class DeleteHouseUseCase {
async execute({ id, tenantId }: IDeleteHouseRequest) {
const findHouse = await prisma.house.findFirst({
where: {
id: id,
tenantId: tenantId
},
})
if (!findHouse) {
throw new Error("It was not possible to delete this house.")
}
const deletedHouse = await prisma.house.delete({
where: {
id: id
}
})
return deletedHouse
}
}
That is, the code hangs within this verification receiving parameters, which are coming correctly, such as ID and IDTENANT, but my !findhouse is coming as null, the data in the DB is correct, I've already checked, the item exists, and the ids are correct.
I can't pass this check..

How to update Elasticsearch dynamic data multiple fields using UpdateByQuery in NodeJS

How to update Elasticsearch data multiple fields using UpdateByQuery in NodeJS ?
Note - My data is coming dynamically. I can't pass static value. I have to pass like - data.name, data.id
Code -
function updateInELK(data) { // Update by Id
const updateScript = {
inline: {
"ctx._source.name = "+data.name,
"ctx._source.role = "+data.role,
};
return new Promise((resolve, reject) => {
elasticsearch.updateByQuery({
index: indexName,
body: {
query: { match: { id: data.id } },
script: updateScript,
lang: 'painless',
}
}).then((response) => {
resolve(response);
}).catch((err) => {
console.log(err);
reject("Elasticsearch ERROR - data not updated")
})
});
}
Error -
TypeError: "ctx._source.name = " is not a function
Please let me know, if any other options are there. I can't update using id, because I don't know the id. I wanted to use updateByQuery, with conditions in the query parameters.
Here are the solutions -
await esClient.updateByQuery({
index: "data",
type: "doc",
refresh: true,
body:{
query:{
match: {
dataId: "70897e86-9d69-4700-b70e-881a7f74e9f9"
}
},
script:{
lang:"painless",
source:`ctx._source.data='This is updated test data';ctx._source.updatedAt=params.date;ctx._source.segmentId=params.segmentId`,
params:{
date: Date.now(),
segmentId: null
}
}
}
});

How to remove a nested attribute from dynamodb table?

How to remove a nest attribute from dynamodb table on the basis of id? I m using nodejs(Typescript) with local dynamodb.
// check if post exists
const post = await dynamo.get({
TableName: "PostTable",
Key: { id: event.body.postId }
}).promise();
if (!post.Item) {
return formatJSONResponse({
message: `no post with this id`,
statuscode: 404
});
}
const params = {
TableName: "PostTable",
Key: { id: event.body.postId },
UpdateExpression:
"REMOVE comments.#id",
ExpressionAttributeValues: {
"#id": event.body.id
},
ReturnValues : "UPDATED_NEW"
}
let res= await dynamo.update(params).promise();
return formatJSONResponse({
message: `Comment has been removed
event,
result: res
});
dynamobdb table picture

Getting error response = null from api gateway and dynamoDb

{
"error": "Cannot read property 'playerId' of null"
}
I have created a list lambda function
that passes in a playerId. This playerId is used like so.
export const main = handler(async (event, context) => {
const data = JSON.parse(event.body);
const params = {
TableName: process.env.teamsTable,
ExpressionAttributeValues : {
':playerId' : { S: data.playerId }
},
FilterExpression: "contains (players, :playerId)"
};
try {
const result = await dynamoDb.scan(params);
if (!result.Items) {
throw new Error("Teams not found.");
}
return {
status: 200,
body: result.Items,
};
} catch (e) {
return {
statusCode: 500,
body: JSON.stringify({ error: e.message }),
};}});
I have tested it locally with serverless mocks and it works. Create a call to use it in the FE and hitting this error: {error: "Cannot read property 'playerId' of null"}
error: "Cannot read property 'playerId' of null", also hit it through API gateway and hitting same.
frontEnd call -
const endpoint = "/teams";
console.log(playerId);
try {
const response = await API.get(amplifyAPIName, endpoint, {
body: playerId
});
return response;
} catch {
return [];
}
}
help
Answer: I was using the get method instead of post. I am passing playerId as a filter expression in aws. By changing it to post I was able to receive my results.

Graphql with Azure functions

is there a way to implement Graphql via azure functions and nodejs. For example, something like - https://www.npmjs.com/package/graphql-server-lambda
Apollo provides Azure Function Integration for GraphQL:
apollo-server-azure-functions
Here is the sample provided on their github repo:
const server = require("apollo-server-azure-functions");
const graphqlTools = require("graphql-tools");
const typeDefs = `
type Random {
id: Int!
rand: String
}
type Query {
rands: [Random]
rand(id: Int!): Random
}
`;
const rands = [{ id: 1, rand: "random" }, { id: 2, rand: "modnar" }];
const resolvers = {
Query: {
rands: () => rands,
rand: (_, { id }) => rands.find(rand => rand.id === id)
}
};
const schema = graphqlTools.makeExecutableSchema({
typeDefs,
resolvers
});
module.exports = function run(context, request) {
if (request.method === "POST") {
server.graphqlAzureFunctions({
endpointURL: '/api/graphql'
})(context, request);
} else if (request.method === "GET") {
return server.graphiqlAzureFunctions({
endpointURL: '/api/graphql'
})(context, request);
}
};
So I got this working using Apollo and Azure Functions. There is a mistake in the example for apollo-server-azure-functions, and a minor error in that wrapper library that returns string and not JSON data. You also need to install graphql-tools separately.
In the example code the schema object is created, but not added to the parameters passed to Apollo server. The working code is below. I've just added schema to the options passed.
const server = require("apollo-server-azure-functions");
const graphqlTools = require("graphql-tools");
const typeDefs = `
type Random {
id: Int!
rand: String
}
type Query {
rands: [Random]
rand(id: Int!): Random
}
`;
const rands = [{ id: 1, rand: "random" }, { id: 2, rand: "modnar" }];
const resolvers = {
Query: {
rands: () => rands,
rand: (_, { id }) => rands.find(rand => rand.id === id)
}
};
const schema = graphqlTools.makeExecutableSchema({
typeDefs,
resolvers
});
module.exports = function run(context, req) {
if (req.method === 'POST') {
server.graphqlAzureFunctions({
endpointURL: '/api/graphql',
schema: schema
})(context, req);
} else if (req.method === 'GET') {
return server.graphiqlAzureFunctions({
endpointURL: '/api/graphql',
schema: schema
})(context, req);
}
};
Just doing this change you will start to get data back from your endpoint, but unfortunately it will not be of type application/json. For that a small change needs to be made to apollo-server-azure-functions to convert the body from string to JSON. I've submitted a PR for this to happen, but not sure when they will get to it.
If you're not patient, you can create your own wrapper function with the code below which will work with the example above and return JSON not a string.
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var apollo_server_core_1 = require("apollo-server-core");
var GraphiQL = require("apollo-server-module-graphiql");
function graphqlAzureFunctions(options) {
if (!options) {
throw new Error('Apollo Server requires options.');
}
if (arguments.length > 1) {
throw new Error("Apollo Server expects exactly one argument, got " + arguments.length);
}
return function (httpContext, request) {
var queryRequest = {
method: request.method,
options: options,
query: request.method === 'POST' ? request.body : request.query,
};
if (queryRequest.query && typeof queryRequest.query === 'string') {
queryRequest.query = JSON.parse(queryRequest.query);
}
return apollo_server_core_1.runHttpQuery([httpContext, request], queryRequest)
.then(function (gqlResponse) {
var result = {
status: 200,
headers: { 'Content-Type': 'application/json' },
body: JSON.parse(gqlResponse),
};
httpContext.res = result;
httpContext.done(null, result);
})
.catch(function (error) {
var result = {
status: error.statusCode,
headers: error.headers,
body: error.message,
};
httpContext.res = result;
httpContext.done(null, result);
});
};
}
exports.graphqlAzureFunctions = graphqlAzureFunctions;
function graphiqlAzureFunctions(options) {
return function (httpContext, request) {
var query = request.query;
GraphiQL.resolveGraphiQLString(query, options, httpContext, request).then(function (graphiqlString) {
httpContext.res = {
status: 200,
headers: {
'Content-Type': 'text/html',
},
body: graphiqlString,
};
httpContext.done(null, httpContext.res);
}, function (error) {
httpContext.res = {
status: 500,
body: error.message,
};
httpContext.done(null, httpContext.res);
});
};
}
exports.graphiqlAzureFunctions = graphiqlAzureFunctions;
For this to work you will need to install apollo-server-core and apollo-server-module-grapiql as dependencies via npm.
There's no native support for this, but there's nothing preventing you from creating a GraphQL schema that calls into Azure Functions.
However, there are some community offerings in the space like scaphold which work to integrate Azure Functions / serverless providers with GraphQL:
https://docs.scaphold.io/custom-logic/
For anyone looking to develop a GraphQL API with Typescript and Azure Functions, here's a starter repo you may consider: azure-function-graphql-typescript-starter (disclaimer: I'm the author)
It's built on top of:
Apollo Server
with Azure Functions integration
TypeGraphQL to make developing GraphQL APIs simple
and fun
PostgreSQL as persistence layer
TypeORM for database migrations and useful repository
classes

Resources