Implementing a Expense Tracking App for Capstone project of https://www.udacity.com/course/cloud-developer-nanodegree--nd9990
This application will allow creating/removing/updating/fetching (CRUD) Expenses.
The application stores Expense items, and each Expense item contains the following fields:
expenseId
(string) - a unique id for an itemuserId
(string) - a unique id for the user who created itdate
(string) - date and time when an item was created or updatedname
(string) - name of a Expense item (e.g. "Shopping Mall bill")description
(string) - description of the bill (e.g. "shirts for friends")amount
(float) - amount of the bill
In this project, auth is configured in serverless.yml
file:
-
Auth
- this function implements a custom authorizer for API Gateway and all lambda functions use it. -
GetExpenses
- returns all Expenses for a current user. A user id can be extracted from a JWT token that is sent by the postman
It returns data that looks like this:
{
"expense": [
{
"amount": 190,
"date": "2021-02-28T08:08:27.802Z",
"description": "test expense2 - description- 1st account-1",
"name": "test expense2 - 1st account1",
"userId": "google-oauth2|115387772605073873555",
"expenseId": "1c84526b-28c0-4f0c-ad6a-2ec7e3b9a7db"
},
{
"amount": 45500.9,
"date": "2021-02-28T08:09:15.341Z",
"description": "test expense4 - description- 1st account-1",
"name": "test expense4 - 1st account1",
"userId": "google-oauth2|115387772605073873555",
"expenseId": "29cdba07-8c7e-444f-8e34-0a5dc4bc8535"
},
{
"amount": 90,
"date": "2021-02-28T08:09:56.728Z",
"description": "test expense - modified",
"name": "test expense -- modified ",
"userId": "google-oauth2|115387772605073873555",
"expenseId": "3e90561d-d636-486c-8d6d-d43d32196608"
}
]
}
CreateExpense
- creates a new Expense for a current user. A shape of data send by a client application to this function can be found in theCreateExpenseRequest.ts
file
{
"name" : "test expense4 - 1st account1",
"description" : "test expense4 - description- 1st account-1",
"amount": 45500.90
}
It should return a new Expense item that looks like this:
{
"expense": {
"userId": "google-oauth2|115387772605073873555",
"expenseId": "29cdba07-8c7e-444f-8e34-0a5dc4bc8535",
"name": "test expense4 - 1st account1",
"description": "test expense4 - description- 1st account-1",
"date": "2021-02-28T08:09:15.341Z",
"amount": 45500.9
}
}
UpdateExpense
- should update a Expense item created by a current user. A shape of data send by a client application to this function can be found in theUpdateExpenseRequest.ts
file
It receives an object that contains three fields that can be updated in a TODO item:
{
"name" : "test expense -- modified ",
"description" : "test expense - modified",
"amount" : 90
}
The id of an item that should be updated is passed as a URL parameter.
It should return the updated Expense item that looks like this:
{
"expense": {
"userId": "google-oauth2|115387772605073873555",
"expenseId": "29cdba07-8c7e-444f-8e34-0a5dc4bc8535",
"name": "test expense -- modified ",
"description": "test expense - modified",
"date": "2021-02-28T08:09:15.341Z",
"amount": 90
}
}
DeleteExpense
- should delete a Expense item created by a current user. Expects an id of a Expense item to remove.
It should return an empty body.
All functions are connected to appropriate events from API Gateway.
An id of a user can be extracted from a JWT token passed by a client.
To implement authentication, an Auth0 application was created and symmetrically encrypted JWT token is used
ExpensesTable:
Type: AWS::DynamoDB::Table
Properties:
AttributeDefinitions:
- AttributeName: userId
AttributeType: S
- AttributeName: expenseId
AttributeType: S
- AttributeName: createdAt
AttributeType: S
KeySchema:
- AttributeName: userId
KeyType: HASH
- AttributeName: expenseId
KeyType: RANGE
BillingMode: PAY_PER_REQUEST
TableName: ${self:provider.environment.EXPENSES_TABLE}
LocalSecondaryIndexes:
- IndexName: ${self:provider.environment.INDEX_NAME}
KeySchema:
- AttributeName: userId
KeyType: HASH
- AttributeName: createdAt
KeyType: RANGE
Projection:
ProjectionType: ALL # What attributes will be copied to an index
You can use the Postman collection that contains sample requests. You can find a Postman collection in this project. To import this collection, do the following.
Click on the import button:
Click on the "Choose Files":
Select a file to import:
Edit the Collection, and go to Authorization tab, click Get New Access Token
Your Brower, will open, Login using Google, and click Open Postman (You might have to turn on Allow Popups)
Postman will show Authentication Complete Window, Click Proceed, or wait 5 sec
Click Update
If your authentication is not successful, API will show "Unauthorized Error, with 401 code"
If your authentication is successful, you will get empty response on GetALLExpenses, until you create an Expense
Go to CreateExpense request, and send some request with data
Successful getExpense call, will show the expense you have added
Successful getExpense call, will show the all the expense you have added, after multiple create requests
You have to follow Same steps to get a new token, this time you can login with a different account in your browser window.