The goal of this exercise is to see if you're confortable with JavaScript and/or TypeScript and are used to writing functional, well tested and documented API endpoints.
We'll be working on a micro service, called users-service
, which is responsible for all CRUD operations on the Users
table in the Exercise
database. We'll use sqlite in this exercise as it requires no setup.
The exercise is divided in steps. Each step will be reviewed independently using pull requests.
- Fork the repo
- Clone the repo on your computer
- Install the dependencies
Click here to expand
- Create the Users table
Users
- userId PRIMARY KEY
- firstName
- lastName
- fullName
- email
- birthdate
- street
- city
- country
- zip
- status ENUM (ACTIVE/LOCKED/CLOSED)
- createdAt
- updatedAt
- Write the CRUD endpoints
- Add an authentication layer using JWT. We'll assume that an another service is responsible for generating valid JWTs.
- Write a script to insert a bunch of test data
- Add a second table named UserSettings following the following schema:
UserSettings
- userSettingId PRIMARY KEY
- userId FOREIGN KEY
- hasSubscribedToNewsletter
- defaultCurrency
- Write the CRUD endpoints for this new table
- Allow the user's GET endpoint to return the userSettings alongside the user object
- All endpoints must be tested
- All endpoints must be documented
- All endpoints should validate their inputs
sqlite3
is a wrapper around SQLite but doesn't provide a promise based API. Therefore, we use another wrapper which is sqlite
which offers a Promise API around sqlite3
.
- Run mutations
// INSERT, CREATE TABLE, UPDATE etc.
await db.run(sqlMutation)
- Run queries
// Get one item
await db.get(sqlQuery)
// Get several items
await db.all(sqlQuery)
- Auth with jwt + session
- Full testing features: Unit test, integration tests, end to end tests
- Only raw query & mutation with sqlite3
- CI-CD with Github actions
- Dependency injection with tsyringe
- Clean architecture with Model-Service-Controller pattern