Add a Get Note API

I see. Thanks for reporting back.

Why pass a callback to an async function?

export async function main(event, context, callback) {
2 Likes

Oh good catch. You can return right away instead of calling the callback. We need to update this.

I’m getting no response when running

$ serverless invoke local --function create --path mocks/create-event.json

Nothing happens. I only have on IAM identity, and it is configured in the ~/.aws/credentials file. My code is identical to the guide except for the regions which I have changed to us-east-2. An error message would be really helpful, but I don’t know how to produce one. Any advice?

Not sure but you can try setting SLS_DEBUG=* while running the command to see what is going on.

How do we notify aws when there is an error if we don’t throw e in the catch block?

@starkos Same thing for me. Does anyone know why we have to add the “body”: “{“text”:”"}" to the get-event.json file to make it work???

@pobch What do you mean by notify AWS?

@lopezdp Can you elaborate a bit on what you are trying to do? Does the standard get-event.json not work?

@jayair I’m not sure on this point. As my understanding, if we call callback(error) in our lambda functions whenever an error occurred, the error will be notified to AWS service like CloudWatch for logging/monitoring purpose. However, the updated version of this chapter use return instead of callback() function.

Reference: https://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-mode-exceptions.html

@jayair in the list-event.json file for the mock input used to test the new list service locally, @starkos and I had to use “body”: “{“text”:”"}" as an attribute in the list-event.json file to get the test to work.

My question is why do we have to use it here and not in other areas?

Thanks!

You can use the callback(error) if you’d like. But we didn’t use it in the past since we are essentially handling the error ourself and we want to control which headers we want to send out. There is a way to tell API Gateway which headers to use in the case of a Lambda exception but it is a bit more complicated.

Prior to this return change, we were simply doing callback(null, response). That is exactly the same as the return response. The way we would send it to CloudWatch would be to console.log(error). Hope that makes sense.

1 Like

Hmm usually you need the body if it is not a GET request. Can you confirm that it is a GET request?

I am also getting the “Item not found” error, while I can get a record query dynamoDB directly using the same userId and noteId in the get-event.json. Do you have suggestion where may be wrong?

Thanks!

No worries, I had a typo, it works now!

Thanks!

1 Like

I’m a relative noob on all this (aws, serverless), but this might be one of the absolute best tutorials i ever came across. On any topic that is. I made heaps of progress on aws, react, bootstrap, and serverless with this.

Me and my bud have been trying to set up a serverless backend with both a web frontend, and an iOS native swift client.
The latter would have to use a swift aws api-gateway sdk which is generated from the aws console. But it seems that this function is unaware of the path parameter (being {id} in this case) the API endpoint needs. So for example, when i generate the SDK for the notes app in this tutorial after deploying the functions to aws with serverless deploy, the getNote function in the generated swift sdk doesn’t take an id parameter.
Turns out path parameters have to be explicitely defined in serverless.yml for the SDK functions to be properly generated, including the path parameters as its function parameters. This might be a new addition since this tutorial was written, and if it is i’m sorry. But the function setup in serverless.yml for iOS SDK generation to work properly would be as follows:

 - http:
          path: notes/{id}
          method: get
          cors: true
          authorizer: aws_iam
          request:
                 parameters:
                        paths:
                               id: true

So the request part and below are new, they define the path parameters. For interaction with a react frontend, obviously explicitely defining this doesn’t seem to be necessary, but for the iOS SDK turns out it is. Oh well, that’s AWS for ya!

1 Like

I got this issue on running get-event.json. Could anyone find out what is this?

    $ serverless invoke local --function get --path mocks/get-event.json
 
  Serverless Error ---------------------------------------
 
  Events for "get" must be an array, not an object

Hey guys, sorry I got the solution for my above mentioned issued. It is because of the space between - and http in serverless.yml

get:
    handler: get.main
    events: 
      - http:
          path: notes/{id}
          method: get
          cors: true
          authorizer: aws_iam
1 Like

Thanks for the kind words!

And thanks for the feedback. I’ll add a note to the chapter with this!

Glad you figured it out! Thanks for reporting back.

I am getting the following error. I have checked and checked I cannot see what I did wrong. I can create an event just cant get it.

C:\Users\activated\myfitnessbook-app-api>serverless invoke local --function create --path mocks\get-event.json
Serverless: Bundling with Webpack...
Time: 620ms
Built at: 07/07/2019 9:04:46 PM
        Asset      Size  Chunks             Chunk Names
    create.js  10.1 KiB  create  [emitted]  create
create.js.map  7.23 KiB  create  [emitted]  create
Entrypoint create = create.js create.js.map
[./create.js] 2.37 KiB {create} [built]
[./libs/dynamodb-lib.js] 468 bytes {create} [built]
[./libs/response-lib.js] 762 bytes {create} [built]
[aws-sdk] external "aws-sdk" 42 bytes {create} [built]
[babel-runtime/core-js/json/stringify] external "babel-runtime/core-js/json/stringify" 42 bytes {create} [built]
[babel-runtime/helpers/asyncToGenerator] external "babel-runtime/helpers/asyncToGenerator" 42 bytes {create} [built]
[babel-runtime/regenerator] external "babel-runtime/regenerator" 42 bytes {create} [built]
[source-map-support/register] external "source-map-support/register" 42 bytes {create} [built]
[uuid] external "uuid" 42 bytes {create} [built]
{
    "errorMessage": "Unexpected token u in JSON at position 0",
    "errorType": "SyntaxError",
    "stackTrace": [
        "SyntaxError: Unexpected token u in JSON at position 0",
        "    at JSON.parse (<anonymous>)",
        "    at _callee$ (C:\\Users\\activated\\myfitnessbook-app-api\\.webpack\\service\\webpack:\\create.js:6:21)",
        "    at tryCatch (C:\\Users\\activated\\myfitnessbook-app-api\\node_modules\\regenerator-runtime\\runtime.js:62:40)",
        "    at Generator.invoke [as _invoke] (C:\\Users\\activated\\myfitnessbook-app-api\\node_modules\\regenerator-runtime\\runtime.js:296:22)",
        "    at Generator.prototype.(anonymous function) [as next] (C:\\Users\\activated\\myfitnessbook-app-api\\node_modules\\regenerator-runtime\\runtime.js:114:21)",
        "    at step (C:\\Users\\activated\\myfitnessbook-app-api\\node_modules\\babel-runtime\\helpers\\asyncToGenerator.js:17:30)",
        "    at C:\\Users\\activated\\myfitnessbook-app-api\\node_modules\\babel-runtime\\helpers\\asyncToGenerator.js:35:14",
        "    at new Promise (<anonymous>)",
        "    at new F (C:\\Users\\activated\\myfitnessbook-app-api\\node_modules\\core-js\\library\\modules\\_export.js:35:28)",
        "    at C:\\Users\\activated\\myfitnessbook-app-api\\node_modules\\babel-runtime\\helpers\\asyncToGenerator.js:14:12",
        "    at main (C:\\Users\\activated\\myfitnessbook-app-api\\.webpack\\service\\create.js:153:17)",
        "    at BbPromise (C:\\Users\\activated\\AppData\\Roaming\\npm\\node_modules\\serverless\\lib\\plugins\\aws\\invokeLocal\\index.js:628:30)",
        "    at Promise._execute (C:\\Users\\activated\\AppData\\Roaming\\npm\\node_modules\\serverless\\node_modules\\bluebird\\js\\release\\debuggability.js:313:9)",
        "    at Promise._resolveFromExecutor (C:\\Users\\activated\\AppData\\Roaming\\npm\\node_modules\\serverless\\node_modules\\bluebird\\js\\release\\promise.js:488:18)",
        "    at new Promise (C:\\Users\\activated\\AppData\\Roaming\\npm\\node_modules\\serverless\\node_modules\\bluebird\\js\\release\\promise.js:79:10)",
        "    at AwsInvokeLocal.invokeLocalNodeJs (C:\\Users\\activated\\AppData\\Roaming\\npm\\node_modules\\serverless\\lib\\plugins\\aws\\invokeLocal\\index.js:582:12)",
        "    at AwsInvokeLocal.invokeLocal (C:\\Users\\activated\\AppData\\Roaming\\npm\\node_modules\\serverless\\lib\\plugins\\aws\\invokeLocal\\index.js:151:19)",
        "    at AwsInvokeLocal.tryCatcher (C:\\Users\\activated\\AppData\\Roaming\\npm\\node_modules\\serverless\\node_modules\\bluebird\\js\\release\\util.js:16:23)",
        "    at Promise._settlePromiseFromHandler (C:\\Users\\activated\\AppData\\Roaming\\npm\\node_modules\\serverless\\node_modules\\bluebird\\js\\release\\promise.js:517:31)",
        "    at Promise._settlePromise (C:\\Users\\activated\\AppData\\Roaming\\npm\\node_modules\\serverless\\node_modules\\bluebird\\js\\release\\promise.js:574:18)",
        "    at Promise._settlePromiseCtx (C:\\Users\\activated\\AppData\\Roaming\\npm\\node_modules\\serverless\\node_modules\\bluebird\\js\\release\\promise.js:611:10)",
        "    at _drainQueueStep (C:\\Users\\activated\\AppData\\Roaming\\npm\\node_modules\\serverless\\node_modules\\bluebird\\js\\release\\async.js:142:12)",
        "    at _drainQueue (C:\\Users\\activated\\AppData\\Roaming\\npm\\node_modules\\serverless\\node_modules\\bluebird\\js\\release\\async.js:131:9)",
        "    at Async._drainQueues (C:\\Users\\activated\\AppData\\Roaming\\npm\\node_modules\\serverless\\node_modules\\bluebird\\js\\release\\async.js:147:5)",
        "    at Immediate.Async.drainQueues (C:\\Users\\activated\\AppData\\Roaming\\npm\\node_modules\\serverless\\node_modules\\bluebird\\js\\release\\async.js:17:14)",
        "    at runCallback (timers.js:705:18)",
        "    at tryOnImmediate (timers.js:676:5)",
        "    at processImmediate (timers.js:658:5)",
        "    at process.topLevelDomainCallback (domain.js:126:23)"
    ]
}

C:\Users\activated\myfitnessbook-app-api>