This is a Dockerized Rails 7 app that provides an interface to manage and retrieve Clerk
data. The application uses the RandomUser.com API to populate the database with Clerk
entries (initialized with random user attributes) and provides endpoints to fetch and filter the data.
Clerks API was built using:
- Ruby:
3.2.1
- Rails:
7.0.6
- PostgreSQL:
15.3
- Docker:
20.10.5
& Docker-compose:1.25.0
The purpose of this project is to showcase best practices, coding principles, and structuring of a Rails API application.
Ensure you have Docker and Docker Compose installed on your machine.
-
To install Docker, follow the instructions here: https://docs.docker.com/engine/install/
-
To install Docker Compose, follow the instructions here: https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker-compose-on-ubuntu-20-04#step-1-installing-docker-compose (as it is tested using the
docker-compose
v1. Alternatively, you could try v2 version from here: https://docs.docker.com/compose but I am not sure about thedocker-compose.yml
compatibility)
All the actual application dependencies are handled by Docker. Check Dockerfile
and docker-compose.yml
files for more info on that.
-
Clone the repository:
git clone git@github.com:christospi/clerks-api.git
-
Navigate to the application directory:
cd clerks-api
-
Environment configuration: The application uses environment variables for configuration. A
.env.sample
file is provided in the repository as a template.-
Copy the
.env.sample
file to create a new.env
file:cp .env.sample .env
-
Open the
.env
file in a text editor and replace the placeholder values with your actual values... OR -
Use mine... π€«π«πͺ
# Database config POSTGRES_DB=clerks_api_development POSTGRES_HOST=localhost POSTGRES_USER=master_clerk POSTGRES_PASSWORD=youshallnotpass # Rails config RAILS_ENV=development RAILS_MASTER_KEY=df3fb452496d94ca83cf44ae77f829d6
-
-
Build and start the Docker containers:
docker-compose up --build
The database will be prepared automatically during the startup process.
Once the Docker containers are up and running, Clerks-API will be available at http://localhost:3000
To run the test suite, execute the following command:
docker-compose -f docker-compose.test.yml up --build
This will build and start the Docker containers and run all the rspec
tests.
The API exposes the following endpoints:
-
POST /populate
: Populates the database with 5K users from RandomUser API, creating aClerk
record for each one. It createsClerk
records synchronously but downloads and attaches images asynchronously (hopefully, for performance optimization). -
GET /clerks
: Returns a list ofClerk
records sorted by registration date, with the most recent users appearing first. Supports optional parameters for filtering and pagination. Currently supported optional parameters:limit
: A limit on the number of Clerks to be returned, ranging between 1 and 100.starting_after
: A cursor for use in pagination.starting_after
is a Clerk ID that defines your place in the list. For instance, if you make a list request and receive 100 objects, ending withID=obj_foo
, your subsequent call can includestarting_after=obj_foo
in order to fetch the next page of the list.ending_before
: A cursor for use in pagination.ending_before
is a Clerk ID that defines your place in the list. For instance, if you make a list request and receive 100 objects,starting with ID=obj_bar
, your subsequent call can includeending_before=obj_bar
in order to fetch the previous page of the list.email
: A case-insensitive filter on the list based on Clerk's email field.
For a few samples, check the following section (Sample Requests and Responses).
This section provides examples of how to call the supported endpoints and what kind of responses you can expect.
Request:
curl -X POST -H "Accept: application/json" http://localhost:3000/populate
Response:
Upon successful completion, this endpoint will return a status of 200 and a message indicating the operation was successful.
{
"success_count": 5,
"total_count": 5,
"message": "All 5 users were created successfully.",
"status": "success"
}
Request:
curl -X GET -H "Accept: application/json" http://localhost:3000/clerks
Response:
This endpoint returns a list of clerks. The response contains an array of Clerk objects. Each Clerk object includes id
, firstname
, lastname
, email
, phone
, picture
, and registration_date
fields.
[
{
"id": 5,
"first_name": "Annabelle",
"last_name": "Wilson",
"email": "annabelle.wilson@example.com",
"phone": "(307)-178-1138",
"registration_date": "2022-05-03T07:26:23.952Z",
"created_at": "2023-07-29T13:34:21.247Z",
"updated_at": "2023-07-29T13:34:21.253Z"
},
// ... more records
]
You can also use query parameters to filter and paginate the results. Here's an example that fetches Clerks with a limit of 20, starting after Clerk with ID 100:
Request:
curl -X GET -H "Accept: application/json" "http://localhost:3000/clerks?limit=20&starting_after=100"
This will return up to 20 clerks whose ID comes after 100, sorted by registration date in descending order.
The project follows a typical Rails application structure with models, controllers, and services with a few additions. Apart from the expected classes/modules supporting our main model (Clerk
), it includes the following:
- Services: Located in
lib/services
directory, these files encapsulate business logic that doesn't belong in models or controllers of our app. This includes theRandomUser
module used to fetch user data from the RandomUser.com API. It fetches user data in batches to avoid overwhelming the API with a single large request. - Utilities: General purpose helpers that may be used across different models, services, or other parts of the application (DRY is our motto here!). These utilities can be found under
lib/utils
. Currently, we only haveDownloader
module, which abstracts the process of a file download (used to fetch user pictures from RandomUser.com). - Serializers: Located in the
app/serializers
directory, these files handle the conversion of data for application models. It containsRandomUserSerializer
which is responsible for transforming data from the Random User API into a format that can be used by theClerk
model. - Jobs: Background job classes that handle async tasks, located under
app/jobs
directory. It includesClerkPictureDownloadJob
, which supports downloading and attaching a picture to the passedClerk
record in the background.ClerkPictureDownloadJob
current implementation is based onActiveJob
framework, without a persisted queueing system in backend (sorry, only RAM for now, be sure not to unplug your system). - Specs: Test coverage is provided by RSpec. Located in the
spec
directory, these files contain the test suite for our application, including unit tests for models and controller actions, along with a few request tests. - Dockerfile and docker-compose.yml: These files define the Docker configuration for setting up and running the application in a Docker container. It handles both our database (Postgres) and the Rails app.
- .env.sample: Sample configuration files for the required environment variables. Following the instructructions in Setup section, you should create a new local file named
.env
in application root directory with the appropriate values.
If you encounter issues while setting up the application, you may need to rebuild your Docker images:
docker-compose down
docker-compose up --build
You may also need to check the container logs to debug any issues:
docker-compose logs