This is a Node.js API for recommending friends of friends based on a given person's CPF (Cadastro de Pessoas Físicas). The API allows creating persons, establishing relationships between them, and retrieving friend recommendations.
AWS Lambda, API Gateway, DynamoDB, Serverless Framework
To run the API locally, follow these steps:
git clone https://github.com/luanlcampos/recomendar-amigos.git
cd recomendador-de-amigos
npm install
npm instal -g serverless
More details to set up the AWS credentials at: Serverless Doc
Note: I am using docker to create a local instance of DynamoDB. SLS offers a plugin for running DynamoDB local, but the library is outdated. To make it work, you would have to manually change the DynamoDB image download URL in the node_modules. Click here to check the GitHub Issue on that
The following command will run the following actions:
- Start the DynamoDB container by running the
docker-compose.yml
withdocker compose up -d
- Start the server by using the serverless-offline plugin running
sls offline start
- API will be running on http://localhost:3000/dev
npm run dev:local
Note: this method requires AWS configuration as it is using the actual AWS DynamoDB table. This is a good way to test the functions before deploying.
serverless invoke local --function getRecommendationsByCpf --data '{"pathParameters": {"cpf":"11111111111"}}
The project structure is organized as follows:
├── README.md
├── package-lock.json
├── package.json
├── serverless.yml
└── src
├── api
│ ├── person
│ │ ├── get.js
│ │ └── post.js
│ ├── recommendations
│ │ └── get.js
│ └── relationship
│ └── post.js
├── models
│ ├── data
│ │ ├── aws
│ │ │ └── ddbClient.js
│ │ └── index.js
│ └── jsonSchemas
│ ├── createPersonModel.json
│ └── createRelationshipModel.json
└── services
├── checkIfUserExists.js
├── createRelationship.js
├── getPersonByCpf.js
├── getRecommendationsByCpf.js
├── index.js
└── writePerson.js
File/Directory | Description |
---|---|
serverless.yml | This is a configuration file for the serverless framework. It defines the serverless application's infrastructure, functions, events, and other resources. It specifies the AWS Lambda functions, their triggers, and any necessary configurations. |
src/ | This is a folder that contains the source code of the serverless application. |
src/api/ | This folder contains the API-related code. |
- person/ | This folder contains the code related to the "person" API endpoint. |
- recommendations/ | This folder contains the code related to the "recommendations" API endpoint. |
- relationship/ | This folder contains the code related to the "relationship" API endpoint. |
src/models/ | This folder contains the data models and related code. |
- data/aws | This folder contains the code for interacting with AWS services, specifically the DynamoDB database |
- jsonSchemas/ | This folder contains JSON schemas that define the structure and validation rules for the data models. |
services/ | This folder contains the code for various services or business logic for handling data requests to the database |
Method | Description | Endpoint |
---|---|---|
POST | Create a new person | /person |
Request
Using curl
curl --location '{awsURL}/person' \
--header 'Content-Type: application/json' \
--data '{ "cpf": "77777777777", "name": "Giba" }'
Using serverless CLI
serverless invoke local --function createPerson --data '{ "cpf": "77777777777", "name": "Giba" }'
HTTP 200: Successful Response
{
"status": "ok",
"cpf": "77777777777",
"name": "Giba"
}
Error Responses
{
"status": "error",
"error": {
"code": 400,
"message": "Usuário já cadastrado"
}
}
{
"status": "error",
"error": {
"code": 400,
"message": "CPF Inválido"
}
}
Method | Description | Endpoint |
---|---|---|
GET | Retrieve a person by CPF | /person/:cpf |
Request
Using curl
curl --location '{awsUrl}/person/77777777777'
Using serverless CLI
serverless invoke local --function getPersonByCpf --data '{"pathParameters": {"cpf":"11111111111"}}'
HTTP 200: Successful Response
{
"status": "ok",
"cpf": "77777777777",
"name": "Giba"
}
Error Reponses
{
"status": "error",
"error": {
"code": 404,
"message": "Usuário não encontrado"
}
}
Method | Description | Endpoint |
---|---|---|
POST | Create a new relationship | /relationship |
Request
Using curl
curl --location '{awsUrl}/relationship' \
--header 'Content-Type: application/json' \
--data '{ "cpf1": "11111111111", "cpf2": "22222222222" }'
Using serverless CLI
serverless invoke local --function createRelationship --data '{ "cpf1": "11111111111", "cpf2": "22222222222" }'
HTTP 200: Successful Response
{
"status": "ok",
"cpf": "77777777777",
"name": "Giba"
}
Error Responses
{
"status": "error",
"error": {
"code": 404,
"message": "Usuário não encontrado"
}
}
{
"status": "error",
"error": {
"code": 400,
"message": "CPF Inválido"
}
}
Method | Description | Endpoint |
---|---|---|
GET | Get friend recommendations for a person | /recommendations/:cpf |
Request
Using curl
curl --location '{awsUrl}/recommendations/11111111111'
Using serverless CLI
serverless invoke local --function getRecommendationsByCpf --data '{"pathParameters": {"cpf":"11111111111"}}'
HTTP 200: Successful Response
{
"status": "ok",
"data": ["44444444444", "55555555555"]
}
Error Responses
{
"status": "error",
"error": {
"code": 404,
"message": "Usuário não encontrado"
}
}
{
"status": "error",
"error": {
"code": 400,
"message": "CPF Inválido"
}
}
To deploy our applicaiton, Serverless will use the configuration written in the serverless.yml file to create/update the CloudFormation stack with your code. To deploy, you have to execute:
sls deploy
You can find more information and options of deploy here.
TODO: Create a pipeline on GitHub to deploy everytime a new code is merged/pushed into main.