This an api for a Blog App built as an exam project by dannyrae, a Backend Engineering student at AltSchool Africa School of Engineering 2022/23.
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
git clone https://github.com/dannyrae/blog-app.git
npm install
npm run dev
field | data_type | constraints |
---|---|---|
username | string | required, unique |
firstname | string | required |
lastname | string | required |
string | required, unique | |
password | string | required |
blogs | ref - Blog |
field | data_type | constraints |
---|---|---|
title | string | required, unique |
description | string | |
author | ref - User | |
owner | string | |
state | string | default: 'draft', enum: ['draft', 'published'] |
read_count | Number | default: 0 |
reading_time | Number | |
tags | array | optional |
body | string | required |
- Route: /signup
- Method: POST
π Body
{
"firstname": "John",
"lastname": "Doe",
"username": "mightyjoe",
"email": "joe@mail.com",
"password": "Password0!"
}
π Response
{
"status": "success",
"data": {
"firstName": "John",
"lastName": "Doe",
"username": "mightyjoe",
"email": "joe@mail.com",
"blogs": [],
"_id": "6367c296ba7522bd8561e4f6"
}
}
- Route: /login
- Method: POST
π Body
{
"username": "mightyjoe",
"password": "Password0!"
}
π Response
{
"token": { token },
"username": "mightyjoe",
"firstname": "John"
}
- Route: /api/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": true,
"data": {
"title": "The Adventures of John",
"description": "Fun times as Johnny",
"author": "6366ffdbb47b721083375dc2",
"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": "636810c3e7aaaa457745b150",
"createdAt": "2022-11-06T19:50:40.705Z",
"updatedAt": "2022-11-06T19:50:40.705Z",
"reading_time": 1
}
}
-
Route: /api/
-
Method: GET
-
Header
- Authorization: Bearer {token}
- None (Accessible to unauthenticated users)
-
Query params:
-
page (default: 1)
-
size (default: 20)
-
Filters: Limit returned response by passing values to any of the following parameters:
- author
/api/blog?author=Author
- title
/api/blog?title=Title
- tags: Separate multiple values with a comma
/api/blog?tags=sql,database
-
-
Route: /api/user/
-
Method: GET
-
Header
- Authorization: Bearer {token}
-
Query params:
-
page (default: 1)
-
size (default: 20)
-
Filters: Limit returned response by passing values to any of the following parameters:
- state
/api/blog?state=draft
/api/blog?state=published
- title
/api/blog?title=Title
- tags: Separate multiple values with a comma
/api/blog?tags=sql,database
-
- Route: /api/:blogId
- 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: /api/:blogId
- Method: PATCH
- 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:
- Testing the backend
- Database Modelling
- Database Management
- Debugging
- User Authentication
- User Authorization
- Mongoose populate & ref
Distributed under the MIT License. See LICENSE for more information.
- Twitter - @_emmanueldan
- email - emmanueldan0920@gmail.com
Project Repo Link: Blog App
This project was made possible by:
- AltSchool Africa School of Engineering
- Full Stack open 2022
- Othneil Drew's README Template
- Ileriayo's Markdown Badges
- Daniel's pizza app Readme Template
- Emmanuel Asuquo