This is an API that allows to handle articles, creating, listing, searching and updating them, also, get articles according to the author, reading articles from exernal dataset and updates the local database according an external API.
- TypeScript
- Express
- Cors
- Class Validator
- Eslit
- Prettier
- PM2
- Jest
Installing the packages dependencies
npm install
Throughout the development process you can run the application using ts-node-dev
which will respawn and compile TypeScript files, so you can execute:
npm run start:dev
Tests are built with Jest, to execute them you can do:
npm run test
To generate the coverage you can run:
npm run test:coverage
The coverage result will be place on test\coverage\index.html
after running the test:coverage
command
It's possible to generate a JavaScript build from the compiled TypeScript source code, before that make sure to keep a good code quality so you can use some helpful tools to assure it:
Use lint:fix
to find possible broke compile rule:
npm run lint:fix
And format:fix
to fix the code style
npm run format:fix
After that you can build the production version:
npm run build
After compiling with npm run build
you can easily execute the application with node:
npm run start:prod
Also, it's possible to execute the application with PM2 which is a solutin to make sure the local dataset will be always up to date when fetching data from an external dataset endpoint, so you execute it:
npm run pm2:start
You can see the pm2 processes using:
npm run pm2:list
Tracking and monitoring the current API instance:
npm run pm2:monit
And stop / terminate the current API execution:
npm run pm2:stop
Method | Endpoint | Capability |
---|---|---|
GET | http://localhost:3000/article | Returns a list of articles |
GET | http://localhost:3000/article/:id | Returns an article according to the id |
GET | http://localhost:3000/article/search | Returns an article according to the search query params |
POST | http://localhost:3000/article | Creates an article |
PUT | http://localhost:3000/article/:id | Updates an article according to the id |
GET | http://localhost:3000/author/:id | Returns an article according to the author id |
GET | http://localhost:3000/data/external | Returns a list of articles from an external resource |
GET | http://localhost:3000/data/fetch | Fetchs a list of articles from an external resource and save on current database |
Getting a list of articles
GET /article
curl --request GET \
--url http://localhost:3000/article
Response
{
"success": true,
"data": [
{
"id": 1,
"title": "New item",
"intro": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam a finibus turpis, sit amet eleifend massa. Mauris quis neque justo. Vestibulum mattis venenatis tellus vel varius.",
"content": "In hac habitasse platea dictumst. Morbi vestibulum, velit id pretium iaculis, diam erat fermentum justo, nec condimentum neque sapien placerat ante. Nulla justo.\n\nAliquam quis turpis eget elit sodales scelerisque. Mauris sit amet eros. Suspendisse accumsan tortor quis turpis.",
"author_id": 2,
"created_at": "2023-03-03T11:05:06Z"
},
{...}
]
}
Getting an article by id
GET /article/:id
curl --request GET \
--url http://localhost:3000/article/1
Response
{
"success": true,
"data": {
"id": 1,
"title": "New item",
"intro": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam a finibus turpis, sit amet eleifend massa. Mauris quis neque justo. Vestibulum mattis venenatis tellus vel varius.",
"content": "In hac habitasse platea dictumst. Morbi vestibulum, velit id pretium iaculis, diam erat fermentum justo, nec condimentum neque sapien placerat ante. Nulla justo.\n\nAliquam quis turpis eget elit sodales scelerisque. Mauris sit amet eros. Suspendisse accumsan tortor quis turpis.",
"author_id": 2,
"created_at": "2023-03-03T11:05:06Z"
}
}
Searching and getting an article
GET /article/search?title=the&page=1&limit=20&date_from=2023-03-01T10:53:29Z&date_to=2023-03-31T10:53:29Z
curl --request GET \
--url 'http://localhost:3000/article/search?title=the&page=1&limit=20&date_from=2023-03-01T10%3A53%3A29Z&date_to=2023-03-31T10%3A53%3A29Z'
Query params
{
page: 1, //number
limit: 5, //number
title: 'the', //string
date_from: '2023-03-01T10:53:29Z', // Date as ISO string
date_to: '2023-03-31T10:53:29Z', // Date as ISO string
}
Response
{
"success": true,
"data": [
{
"id": 2,
"title": "Merry Jail, The (Das fidele Gefängnis)",
"intro": "Duis aliquam convallis nunc. Proin at turpis a pede posuere nonummy. Integer non velit.",
"content": "Cras non velit nec nisi vulputate nonummy. Maecenas tincidunt lacus at velit. Vivamus vel nulla eget eros elementum pellentesque.\n\nQuisque porta volutpat erat. Quisque erat eros, viverra eget, congue eget, semper rutrum, nulla. Nunc purus.\n\nPhasellus in felis. Donec semper sapien a libero. Nam dui.",
"author_id": 5,
"created_at": "2023-03-18T15:03:16Z"
},
{...}
]
}
Creating a new article
POST /article
curl --request POST \
--url http://localhost:3000/article \
--header 'Content-Type: application/json' \
--data '{
"author_id": 99,
"content": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam a finibus turpis, sit amet eleifend massa. Mauris quis neque justo. Vestibulum mattis venenatis tellus vel varius. Etiam in facilisis tortor, commodo scelerisque nisi. Nullam auctor, nunc ac molestie cursus, tortor mauris fringilla augue, ac pulvinar orci nunc nec orci. Aenean eget quam arcu. Morbi tristique libero ante, non rutrum nisl egestas ac. Suspendisse condimentum dictum metus, nec cursus quam venenatis eu.",
"intro": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam a finibus turpis, sit amet eleifend massa. Mauris quis neque justo. Vestibulum mattis venenatis tellus vel varius.",
"title": "Cool title over here"
}'
Response
{
"success": true,
"data": {
"id": 102,
"author_id": 99,
"content": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam a finibus turpis, sit amet eleifend massa. Mauris quis neque justo. Vestibulum mattis venenatis tellus vel varius. Etiam in facilisis tortor, commodo scelerisque nisi. Nullam auctor, nunc ac molestie cursus, tortor mauris fringilla augue, ac pulvinar orci nunc nec orci. Aenean eget quam arcu. Morbi tristique libero ante, non rutrum nisl egestas ac. Suspendisse condimentum dictum metus, nec cursus quam venenatis eu.",
"intro": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam a finibus turpis, sit amet eleifend massa. Mauris quis neque justo. Vestibulum mattis venenatis tellus vel varius.",
"title": "Cool title over here",
"created_at": "2023-03-19T15:53:37.149Z"
}
}
Updating an article by id
PUT /article/:id
curl --request PUT \
--url http://localhost:3000/article/1 \
--header 'Content-Type: application/json' \
--data '{
"intro": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam a finibus turpis, sit amet eleifend massa. Mauris quis neque justo. Vestibulum mattis venenatis tellus vel varius.",
"title": "Cool title over here"
}'
Response
{
"success": true,
"data": {
"id": 1,
"title": "Cool title over here",
"intro": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam a finibus turpis, sit amet eleifend massa. Mauris quis neque justo. Vestibulum mattis venenatis tellus vel varius.",
"content": "In hac habitasse platea dictumst. Morbi vestibulum, velit id pretium iaculis, diam erat fermentum justo, nec condimentum neque sapien placerat ante. Nulla justo.\n\nAliquam quis turpis eget elit sodales scelerisque. Mauris sit amet eros. Suspendisse accumsan tortor quis turpis.",
"author_id": 2,
"created_at": "2023-03-03T11:05:06Z"
}
}
Getting a list of articles from an external resource
GET /data/external
curl --request GET \
--url http://localhost:3000/data/external
Response
{
"success": true,
"data": [
{
"id": 1,
"title": "All Together, The",
"intro": "Nulla ut erat id mauris vulputate elementum. Nullam varius. Nulla facilisi.",
"content": "In congue. Etiam justo. Etiam pretium iaculis justo.\n\nIn hac habitasse platea dictumst. Etiam faucibus cursus urna. Ut tellus.\n\nNulla ut erat id mauris vulputate elementum. Nullam varius. Nulla facilisi.",
"author_id": 3,
"created_at": "2023-03-25T16:51:00Z"
},
{...}
]
}
Fetching a list of articles from an external resource and saving on local dataset
GET /data/fetch
curl --request GET \
--url http://localhost:3000/data/fetch
Response
{
"success": true
}
The provided link (http://simple-api.herokuapp.com/api/v1/articles) wasn't available so I took the liberty to create a dataset following the data types according to the challenge description.
I'm using Mockaroo to generate the dataset which you can see here: https://www.mockaroo.com/b9d41960, the same tool provides a mock API based on this dataset, also available here: https://my.api.mockaroo.com/article_database.json?key=69f9a560