A blogging-API built in the fulfilment of the Altschool of Engineering focused in Backend Engineering (NodeJS) Second Semester Requirement
Requirements for the examination project
-
Users should have a first_name, last_name, email, password,
-
A user should be able to sign up and sign in into the blog app
-
Use JWT as authentication strategy and expire the token after 1 hour
-
A blog can be in two states; draft and published
-
Logged in and not logged in users should be able to get a list of published blogs created
-
Logged in and not logged in users should be able to to get a published blog
-
Logged in users should be able to create a blog.
-
When a blog is created, it is in draft state
-
The owner of the blog should be able to update the state of the blog to published
-
The owner of a blog should be able to edit the blog in draft or published state
-
The owner of the blog should be able to delete the blog in draft or published state
-
The owner of the blog should be able to get a list of their blogs.
-
The endpoint should be paginated
-
It should be filterable by state
-
Blogs created should have title, description, tags, author, timestamp, state, read_count, reading_time and body.
-
The list of blogs endpoint that can be accessed by both logged in and not logged in users should be paginated:
-
default it to 20 blogs per page.
-
It should also be searchable by author, title and tags.
-
It should also be orderable by read_count, reading_time and timestamp
-
When a single blog is requested, the api should return the user information (the author) with the blog. The read_count of the blog too should be updated by 1
-
Come up with any algorithm for calculating the reading_time of the blog.
-
Write tests for all endpoints
- Nodejs
- Express
- Passport-JWT
- SuperTest
- Jest
- mongoDB
- mongoose
- Install NodeJS, mongodb
- pull this repo
- update env with example.env
- run
npm run start:dev
- Install NodeJS, mongodb
- pull this repo
- update env with example.env
- run
npm run start
npm install| field | data_type | constraints |
|---|---|---|
| username | string | required, unique |
| firstName | string | required |
| lastName | string | required |
| string | required, unique | |
| password | string | required |
| articles | ref - Article |
| field | data_type | constraints |
|---|---|---|
| title | string | required, unique |
| description | string | optional |
| author | ref - User | |
| owner | string | |
| state | string | required, default: 'draft', enum: ['draft', 'published'] |
| read_count | Number | default: 0 |
| reading_time | Number | |
| tags | array | optional |
| body | string | required |
- Route: /api/signup
- Method: POST
π Body
{
"firstname": "john",
"lastname": "doe",
"username": "johndoe",
"email": "johndoe@gmail.com",
"password": "Password0!"
}π Response
{
"status": "success",
"data": {
"firstname": "john",
"lastname": "doe",
"username": "johndoe",
"email": "johndoe@gmail.com",
"blog": [],
"_id": "6367c296ba7522bd8561e4f6"
}
}- Route: /auth/login
- Method: POST
π Body
{
"email": "johndoe@gmail.com",
"password": "Password0!"
}π Response
{
"token": { token },
"username": "johndoe",
"name": "john"
}- Route: /posts/create
- Method: POST
- Header
- Authorization: Bearer {token}
π Body
{
"title": "The Adventures of John",
"tags": ["memoirs", "expose", "fun"],
"description": "Fun times as Johnny",
"body": "A very fun article that is long enough to be fun, and short enough to be ..fun!"
}π Response
{
"status": "success",
"data": {
"title": "The Adventures of John",
"description": "Fun times as Johnny",
"author": "6367c296ba7522bd8561e4f6",
"state": "draft",
"read_count": 0,
"tags": ["memoirs", "expose", "fun"],
"body": "A very fun article that is long enough to be fun, and short enough to be ..fun!",
"_id": "6367cc2271c384885108032f",
"createdAt": "2022-11-06T15:00:50.202Z",
"updatedAt": "2022-11-06T15:00:50.202Z",
"reading_time": 1
}
}- Route: /posts/:articleId
- Method: PATCH
- Header
- Authorization: Bearer {token}
π Body
{
"state": "published"
}π Response
{
"status": "success",
"data": {
"_id": "6367cc2271c384885108032f",
"title": "The Adventures of John",
"description": "Fun times as Johnny",
"author": "6367c296ba7522bd8561e4f6",
"state": "published",
"read_count": 0,
"tags": ["memoirs", "expose", "fun"],
"body": "A very fun article that is long enough to be fun, and short enough to be ..fun!",
"createdAt": "2022-11-06T15:00:50.202Z",
"updatedAt": "2022-11-06T16:17:45.137Z",
"reading_time": 1
}
}- Route: /posts/update/:blogId
- Method: PUT
- Header
- Authorization: Bearer {token}
π Body
{
"tags": ["memoirs", "expose"],
"body": "A very fun article that is long enough to be fun, and short enough to be ..fun! A sailor went to sea to see what he could see but all that he could see was the bottom of the deep blue sea."
}π Response
{
"status": "success",
"data": {
"_id": "6367cc2271c384885108032f",
"title": "The Adventures of John",
"description": "Fun times as Johnny",
"author": "6367c296ba7522bd8561e4f6",
"state": "published",
"read_count": 0,
"tags": ["memoirs", "expose"],
"body": "A very fun article that is long enough to be fun, and short enough to be ..fun! A sailor went to sea to see what he could see but all that he could see was the bottom of the deep blue sea.",
"createdAt": "2022-11-06T15:00:50.202Z",
"updatedAt": "2022-11-06T16:22:29.326Z",
"reading_time": 1
}
}While building this project, I learned about:
- Test Driven Development
- Testing the backend
- Database Modelling
- Database Management
- Debugging
- User Authentication
- User Authorization
- Documentation
- NAME: Anthony Uzoho
- ALTSCHOOL EMAIL: anthonycuzoho@gmail.com
- TRACK: Backend Engineering (NodeJS)