- Implement the REST API service's
Persons
that will receive full name via API and enrich it from open APIs answer with the most likely age, gender and nationality and save the data in database. Upon request, provide information about found people. The following must be implemented
- Implement CRUD methods: 1.1 Get persons with various filters and pagination; 1.2 Delete by ID; 1.3 Update by ID; 1.4 Create person;
{
"name": "Dmitriy",
"surname": "Ushakov",
"patronymic": "Vasilevich" // can be empty
}
- Enrich the correct message 2.1 By age - https://api.agify.io/?name=Dmitriy 2.2 Gender - https://api.genderize.io/?name=Dmitriy 2.3 Nationality - https://api.nationalize.io/?name=Dmitriy
- Place the enriched message in the PostrgeSQL (the database structure must be created
through
migrations
) - Cover the code with debug and info logs
- Place configuration data in
.env
*
git clone https://github.com/pintoter/persons.git
- Create .env file with filename ".env" in the project root and setting up environment your own variables:
# Database
DB_USER = "user"
DB_PASSWORD = "123456"
DB_HOST = "postgres"
DB_PORT = 5432
DB_NAME = "dbname"
DB_SSLMODE = "disable"
# Local database
LOCAL_DB_PORT = 5432
Hint: if you are running the project using Docker, set
DB_HOST
to "postgres" (as the service name of Postgres in the docker-compose).
- Compile and run the project:
make
-
To test the service's functionality, you can navigate to the address http://localhost:8080/swagger/index.html to access the Swagger documentation.
-
Service's structure
.
├── Dockerfile
├── Dockerfile.debug
├── Makefile
├── README.md
├── bin
├── cmd
│ └── app
│ └── main.go
├── configs
│ └── main.yml
├── cover.html
├── cover.out
├── docker-compose.debug.yml
├── docker-compose.yml
├── docs
│ ├── docs.go
│ ├── swagger.json
│ └── swagger.yaml
├── go.mod
├── go.sum
├── internal
│ ├── app
│ │ └── app.go
│ ├── client
│ │ └── client.go
│ ├── config
│ │ └── config.go
│ ├── database
│ │ └── migrations.go
│ ├── entity
│ │ ├── errors.go
│ │ └── person.go
│ ├── repository
│ │ └── db
│ │ ├── persons_create.go
│ │ ├── persons_create_test.go
│ │ ├── persons_delete.go
│ │ ├── persons_delete_test.go
│ │ ├── persons_get.go
│ │ ├── persons_get_test.go
│ │ ├── persons_update.go
│ │ ├── persons_update_test.go
│ │ └── repository.go
│ ├── server
│ │ └── server.go
│ ├── service
│ │ ├── mocks
│ │ │ └── mock.go
│ │ ├── persons.go
│ │ └── service.go
│ └── transport
│ ├── handler.go
│ ├── persons.go
│ ├── persons_test.go
│ ├── request.go
│ └── response.go
├── migrations
│ ├── 20240117070006_migration.down.sql
│ └── 20240117070006_migration.up.sql
└── pkg
├── database
│ └── postgres
│ └── postgres.go
└── logger
└── logger.go
"name": "any, unique",
"surname": "any",
"paytronic": "any",
"age": "any integer, not negative",
"gender": "male" / "female",
"nationalize": "any",
"limit": "any integer, not negative",
"page": "any integer, not negative"
- Request example:
curl -X 'POST' \
'http://localhost:8080/api/v1/persons' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"name": "Ivan",
"surname": "Ivanov",
"patronymic": "Ivanovich"
}'
- Response example:
{
"message": "created new person with ID: 1"
}
- Request example:
curl -X 'GET' \
'http://localhost:8080/api/v1/persons/30' \
-H 'accept: application/json'
- Response example:
{
"person": {
"id": 30,
"name": "Ivan",
"surname": "Sergeev",
"patronymic": "Petrovich",
"age": 55,
"gender": "male",
"nationalize": [
{
"country_id": "HR",
"probability": 0.112
},
{
"country_id": "RS",
"probability": 0.101
},
{
"country_id": "BG",
"probability": 0.073
},
{
"country_id": "SK",
"probability": 0.052
},
{
"country_id": "UA",
"probability": 0.048
}
]
}
}
- Request example:
curl -X 'PATCH' \
'http://localhost:8080/api/v1/persons/1' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"patronymic": "Ivanovich"
}'
- Response example:
{
"message": "person updated successfully"
}
Hint: You can update partially (not all fields).
- Request example:
curl -X 'DELETE' \
'http://localhost:8080/api/v1/person/1' \
-H 'accept: application/json'
- Response example:
{
"message": "person deleted succesfully"
}
- Request example:
curl -X 'GET' \
'http://localhost:8080/api/v1/persons?nationalize=RU&page=1&limit=5' \
-H 'accept: application/json'
- Response example:
{
"notes": [
{
"id": 1,
"name": "Ivan",
"surname": "Ivanov",
"patronymic": "Ivanovich",
"age": 18,
"gender": "male",
"nationalize": "RU"
},
{
"id": 2,
"name": "Ivan",
"surname": "Ivanov",
"patronymic": "Ivanovich",
"age": 19,
"gender": "male",
"nationalize": "RU"
},
{
"id": 3,
"name": "Ivan",
"surname": "Ivanov",
"patronymic": "Ivanovich",
"age": 20,
"gender": "male",
"nationalize": "RU"
},
]
}
Hint: Use query parameters (name, surname, patronymic, age, gender, nationalize, limit, page) for apply filters.
- Run tests
make test
- Create migration files
make migrate-create
- Migrations up / down
make migrate-up
make migrate-down
- Stop all running containers
make stop
- Run linter
make lint