|
| 1 | +# FidelAPI Test Nicolas Notes |
| 2 | + |
| 3 | +- There will be some explanations about the project, how to setup, and some useful information. |
| 4 | + |
| 5 | +### Overview |
| 6 | +- I see in the main doc there's some questions to be answered, and it will be answered on this doc file. |
| 7 | + |
| 8 | +- The project was developed in **NodeJs**, I used the framework **Serverless** to build the Lambda Application on AWS, it was created a setup to build an API through **API Gateway** platform, with **DynamoDB** and **Lambda**. |
| 9 | + |
| 10 | +- I also used some libs to build the application that are, **dotenv** to provide the same environment variables used on serverless, to be reached on our tests, and also **Jest** a lib to provide a test environment and tools to test our API. |
| 11 | + |
| 12 | +--- |
| 13 | + |
| 14 | +### Setup |
| 15 | +- To reproduce this API in your AWS environment, you need to have AWS CLI installed on your OS, and the environment variables **AWS_ACCESS_KEY_ID** and **AWS_SECRET_ACCESS_KEY** with the respective values. |
| 16 | +- You also need **Serverless** framework installed in your OS, it can be done running `npm install -g serverless` ('How to' available on https://www.serverless.com/framework/docs/getting-started) |
| 17 | + |
| 18 | +- With all the requirements check, you can install the project running: |
| 19 | + |
| 20 | +``` |
| 21 | +npm install |
| 22 | +``` |
| 23 | +And then, deploy and create it in your AWS running: |
| 24 | +``` |
| 25 | +serverless deploy |
| 26 | +``` |
| 27 | + |
| 28 | +### Tests |
| 29 | + |
| 30 | +- The application has 100% tests coverage, you can see it running `npx jest --coverage` |
| 31 | + |
| 32 | +To run the tests, just run |
| 33 | +``` |
| 34 | +npm run test |
| 35 | +``` |
| 36 | +- There's many console logs on tests, to omit then you can run `npx jest --silent` |
| 37 | +--- |
| 38 | + |
| 39 | +### Informations |
| 40 | +- The project is protected under an API KEY setted on **serverless.yml** file, that are **fideltest-key**. That was based on the same protection used on FidelAPI (Reference: https://reference.fidel.uk/reference#authentication), **fideltest-key** is supposed to be a unique key wranted for the customers of the application. |
| 41 | +Because of that API KEY, you must add the header **`x-api-key`** with value **`v3IPj3dPvT62rJYm3Ho7d2owPMxyYQ7x5kJNWcsH`** in all the requests that you would do to the API. |
| 42 | +- I shared my [Postman Collection](https://github.com/FidelLimited/be-techtest-nicolaslima/tree/master/Postman%20Collection) used to develop the application, it contains all endpoints, headers, and body properly filled, it can help to test my API. |
| 43 | +- My production API is available on https://6pkqjlxvu0.execute-api.us-east-1.amazonaws.com/dev/ |
| 44 | +- To simulate that offers creations always be made by the same publisher, i created an environment variable called DEFAULT_UUID, with an static UUID |
| 45 | +- I also created some endpoints that allow creation of offers, brands and locations |
| 46 | + |
| 47 | +### Endpoints |
| 48 | +The endpoints that have **{offerId}**, **{locationId}**, **{brandId}**, needs to be replaced to the current subject id at the url. |
| 49 | + |
| 50 | +- API Keys: |
| 51 | +``` |
| 52 | + fideltest-key (x-api-key): v3IPj3dPvT62rJYm3Ho7d2owPMxyYQ7x5kJNWcsH |
| 53 | +``` |
| 54 | + |
| 55 | +- Brands |
| 56 | +``` |
| 57 | +Creation |
| 58 | +
|
| 59 | +POST - https://6pkqjlxvu0.execute-api.us-east-1.amazonaws.com/dev/brand |
| 60 | +- Body example: |
| 61 | + { |
| 62 | + "name": "Starbucks" |
| 63 | + } |
| 64 | +``` |
| 65 | + |
| 66 | +``` |
| 67 | +Index |
| 68 | +
|
| 69 | +GET - https://6pkqjlxvu0.execute-api.us-east-1.amazonaws.com/dev/brand |
| 70 | +``` |
| 71 | + |
| 72 | +``` |
| 73 | +Show :ID |
| 74 | +
|
| 75 | +GET - https://6pkqjlxvu0.execute-api.us-east-1.amazonaws.com/dev/brand/{brandId} |
| 76 | +``` |
| 77 | + |
| 78 | +- Offers |
| 79 | +``` |
| 80 | +Creation |
| 81 | +
|
| 82 | +POST - https://6pkqjlxvu0.execute-api.us-east-1.amazonaws.com/dev/offer |
| 83 | +- Body example: |
| 84 | + { |
| 85 | + "name": "Super Duper Offer", |
| 86 | + "brandId": "692126c8-6e72-4ad7-8a73-25fc2f1f56e4" |
| 87 | + } |
| 88 | +``` |
| 89 | + |
| 90 | +``` |
| 91 | +Index |
| 92 | +
|
| 93 | +GET - https://6pkqjlxvu0.execute-api.us-east-1.amazonaws.com/dev/offer |
| 94 | +``` |
| 95 | + |
| 96 | +``` |
| 97 | +Show :ID |
| 98 | +
|
| 99 | +GET - https://6pkqjlxvu0.execute-api.us-east-1.amazonaws.com/dev/offer/{offerId} |
| 100 | +``` |
| 101 | + |
| 102 | +``` |
| 103 | +Link Offer to Locations |
| 104 | +
|
| 105 | +POST - https://6pkqjlxvu0.execute-api.us-east-1.amazonaws.com/dev/offer/{offerId}/link-location/{locationId} |
| 106 | +``` |
| 107 | + |
| 108 | +``` |
| 109 | +(BONUS) Link Offer to all locations from a brand |
| 110 | +
|
| 111 | +POST - https://6pkqjlxvu0.execute-api.us-east-1.amazonaws.com/dev/offer/{offerId}/link-all-brands-location/{brandId} |
| 112 | +``` |
| 113 | + |
| 114 | +- Location |
| 115 | + |
| 116 | +``` |
| 117 | +Creation |
| 118 | +
|
| 119 | +POST - https://6pkqjlxvu0.execute-api.us-east-1.amazonaws.com/dev/location |
| 120 | +- Body example: |
| 121 | + { |
| 122 | + "address": "Lorem Ipsum Address", |
| 123 | + "brandId": "692126c8-6e72-4ad7-8a73-25fc2f1f56e4" |
| 124 | + } |
| 125 | +``` |
| 126 | + |
| 127 | +``` |
| 128 | +Index |
| 129 | +
|
| 130 | +GET - https://6pkqjlxvu0.execute-api.us-east-1.amazonaws.com/dev/location |
| 131 | +``` |
| 132 | + |
| 133 | +``` |
| 134 | +Show :ID |
| 135 | +
|
| 136 | +GET - https://6pkqjlxvu0.execute-api.us-east-1.amazonaws.com/dev/location/{locationId} |
| 137 | +``` |
| 138 | + |
| 139 | +--- |
| 140 | + |
| 141 | +### Answers |
| 142 | + |
| 143 | +##### Part 1 |
| 144 | +1. Have you ever used DynamoDb before? If not, how did you prepare for this task? If yes, which patterns did you learn in the past that you used here? |
| 145 | +**Answer:** No, I never worked with DynamoDb before, just read about it, and learned some things. I prepared myself by learning through AWS documentations, and creating a little NodeJs project to test it. |
| 146 | + |
| 147 | +<br> |
| 148 | + |
| 149 | +2. How did you design your data model? |
| 150 | +**Answer:** I tried to follow the FidelAPI Offer purpose (https://fidel.uk/docs/offers) and saw that Offer creation requires a Brand, this Brand is also referred for Locations. |
| 151 | +Then I created 3 models, Locations and Offer, the two parts of the test didn't mention a need to create Brand model, but i created, and became possible to create new Brands if is wanted to. |
| 152 | +Offers and Locations are linked to Brand through brandId, all brandId fields are GlobalIndexes, to improve the search through DynamoDB |
| 153 | + |
| 154 | +<br> |
| 155 | + |
| 156 | +3. What are the pros and cons of Dynamodb for an API request? |
| 157 | +**Answer:** Cons: I thought the forms that queries are made is a little limited, it’s harder to perform queries if medium-high complexity; You have a limit of capacity write/read, that is defined on `ProvisionedThroughput` (in serverlerss.yml file), and even defining it to 'auto', it's not very predictable how much you can will for it. |
| 158 | +Pros: It’s very easy to install, configure; It’s a flexible database; The SDK integration is very good and easy to perform; |
| 159 | + |
| 160 | +--- |
| 161 | + |
| 162 | +##### Part 2 |
| 163 | +1. Have you used Functions as a Service (FaaS) like AWS Lambda in the past? If not, how did you prepare for this task? If yes, how did this task compare to what you did? |
| 164 | +**Answer:** No, I never worked with FaaS in the past, I only made a "Hello World" once, in lambda, and also learned some things about it. I prepared myself by learning through documentation, and creating a little NodeJs project, the same that I used to learn DynamoDB. |
| 165 | + |
| 166 | +<br> |
| 167 | + |
| 168 | +2. How do you write operations within a concurrent architecture (parallel requests, series of async actions, async mapReduce patterns, etc.)? |
| 169 | +**Answer:** In JavaScript, I handled series of async functions, parallelism, using Promises (reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise), basically handling individual promises/async actions, and a lot of promises with **`Promise.allSettled()`** or **`Promise.all()`** (According my need) |
| 170 | +In other languages, I've used parallel requests, jobs, processes. For example, I used in PHP, with Amazon SQS and Laravel (https://laravel.com/docs/8.x/queues), and also for Elixir with Phoenix (https://hexdocs.pm/elixir/1.12/Kernel.ParallelCompiler.html#async/1). |
| 171 | + |
| 172 | +--- |
| 173 | + |
| 174 | +#### Bonus |
| 175 | +Bonus implementation is available on the follow endpoint: |
| 176 | +``` |
| 177 | +(BONUS) Link Offer to all locations from a brand |
| 178 | +
|
| 179 | +POST - https://6pkqjlxvu0.execute-api.us-east-1.amazonaws.com/dev/offer/{offerId}/link-all-brands-location/{brandId} |
| 180 | +``` |
| 181 | + |
| 182 | +It notify the user at response when some of the links could not be performed. |
0 commit comments