Add a List All the Notes API

From @jayair on Mon Apr 10 2017 01:00:02 GMT+0000 (UTC)

Link to chapter - http://serverless-stack.com/chapters/add-a-list-all-the-notes-api.html

Copied from original issue: https://github.com/AnomalyInnovations/serverless-stack-com/issues/25

From @SherpaPsy on Thu Apr 20 2017 12:21:12 GMT+0000 (UTC)

One suggestion - why not name the event.json files after the function they are testing, that way a library of them can be maintained in case of further testing? eg:
serverless webpack invoke --function list --path -list-event.json

From @jayair on Thu Apr 20 2017 18:16:58 GMT+0000 (UTC)

Ah yeah that’s not a bad idea. In the case of the tutorial, we just use it for one off testing cases and don’t commit it to the repo - https://github.com/AnomalyInnovations/serverless-stack-demo-api/blob/master/.gitignore#L40

From @ryanjcruz on Sat May 13 2017 07:48:02 GMT+0000 (UTC)

Created a PR for this. Updated instructions to test functions coming from a mocks/ directory for cleaner structure.

From @bimbo1989 on Mon Nov 27 2017 16:11:45 GMT+0000 (UTC)

I’m following the serverless tutorial, and when it comes to this function I get a “Cannot read property ‘id’ of undefined” error.
The previous tests ran just fine.
I tried to look for a solution but I found nothing. Do I need to open a new issue?

From @bimbo1989 on Tue Nov 28 2017 08:44:03 GMT+0000 (UTC)

Nevermind. Tried again today without changing anything and works flawlessly. Stranger things, season 3 :slight_smile:

From @jayair on Tue Nov 28 2017 20:34:44 GMT+0000 (UTC)

@bimbo1989 Thanks for reporting back.

From @omairhamid on Fri Jan 26 2018 00:24:50 GMT+0000 (UTC)

Hi, apologies if this doesn’t belong here because of the modification I made, but I’m trying to write the “list all notes” API with a minor modification and running into an issue:

In list.js, I have this:
const params = { TableName: "notes", IndexName: "teacher-index", KeyConditionExpression: "teacher = :teacher", ExpressionAttributeValues: { ":teacher": event.pathParameters.teacher } };

I am trying to retrieve all the notes that are assigned to a specific teacher (instead of the user), and the teacher field is NOT part of the key (partition or sort). So, I created an index (teacher-index) and referenced it above.

This works, with the list-event.json below:
{ "pathParameters": { "teacher": "Bill" } }
It successfully returns all the notes that have the teacher field set to “Bill”.

However, this does NOT work:
{ "pathParameters": { "teacher": "Omair Hamid" } }
It returns an empty set, even though there are several notes that have the teacher field set to “Omair Hamid”.

Are spaces something that I cannot have? Do I need to escape them? Am I building the list-event.json incorrectly or the list.js file?

From @jayair on Sat Jan 27 2018 23:56:09 GMT+0000 (UTC)

@omairhamid That looks okay and it should work. Can you just make sure that that it is stored and queried with a space in the middle and not a tab or something? Since Bill is working, it should be fine.

When I run the query an log the exception I get “Query condition missed key schema element: noteId”. It seems that a query requires the partition key. Should this be a “scan” instead of a query?

That’s because I reversed the noteId and userId. The table should have the userId as the partition key and the noteId as the sort key

2 Likes

Thanks for reporting back!

How would you go about creating requesting something not owned by the requester?

Use Cases:

  • A manager of some kind needs to see her employee’s profile
  • A teacher needs to view her student’s grades
  • A supervisor needs to review his employee’s notes

If you have access to the user id for the user you are requesting then it should be pretty straightforward. Just use that instead of:

Hi and thanks so much for this amazing tutorial. I’m wondering what would be best practice when creating an API endpoint that has both public and private access. For example, I want GET /notes to list all notes that have been marked as “public” when a user is not logged in, but will list the user’s notes when they are logged in.

But: if I set authorizer: aws_iam then I get a 403 response when I access the endpoint without authenticating. However, if I don’t set an authorizer, then I don’t have access to the IAM user in Lambda when I have authenticated.

Is there a different way to do something like this? Do I need to set up a different set of endpoints for public consumption? I haven’t found much on the web so I’m just wondering if there’s a standard practice for this kind of use-case. Thanks!

1 Like

That’s a great question. So we don’t do this in the tutorial to keep things simple. While creating the Identity Pool you need to allow unauthenticated users to access things (https://serverless-stack.com/chapters/create-a-cognito-identity-pool.html). Then your API would be accessible if the user is not authenticated. You can then check if it is auth vs unauth in your Lambda and return accordingly.

On the frontend you need to specific that you allow unauthenticated users as well.

2 Likes

Right on. That makes a lot of sense - I just couldn’t figure out where to do it. Thanks a lot for the reply! And thanks again for this amazing tutorial.

1 Like

** Category: AppSync **

Hi hackers!

Context: Please suppose we use amplify js to create an Appsync endpoint using the @search directive.

I was wondering… what the differences are between using AWS.DynamoDB.DocumentClient() and AWS.HttpRequest(appsyncUrl, region) approaches. We would like to find out if both approaches are automatically using or not the Elasticsearch complement for reads and writes to the DynamoDB + Elasticsearch strategy?

new AWS.DynamoDB.DocumentClient()
new AWS.HttpRequest(appsyncUrl, region);