Use Node.js
and Express
to build an API that performs CRUD operations on blog posts
.
- import this repository into your account
- clone your copy of this repository.
- CD into the folder where you cloned the repository.
- Type
npm install
to download all dependencies. - To start the server, type
npm run server
from the root folder (where the package.json file is). The server is configured to restart automatically as you make changes.
- Add the code necessary to implement the endpoints listed below.
- Separate the endpoints that begin with
/api/posts
into a separateExpress Router
.
Configure the API to handle to the following routes:
Method | Endpoint | Description |
---|---|---|
POST | /api/posts | Creates a post using the information sent inside the request body . |
POST | /api/posts/:id/comments | Creates a comment for the post with the specified id using information sent inside of the request body . |
GET | /api/posts | Returns an array of all the post objects contained in the database. |
GET | /api/posts/:id | Returns the post object with the specified id. |
GET | /api/posts/:id/comments | Returns an array of all the comment objects associated with the post with the specified id. |
DELETE | /api/posts/:id | Removes the post with the specified id and returns the deleted post object. You may need to make additional calls to the database in order to satisfy this requirement. |
PUT | /api/posts/:id | Updates the post with the specified id using data from the request body . Returns the modified document, NOT the original. |
When the client makes a POST
request to /api/posts
:
-
If the request body is missing the
title
orcontents
property:- cancel the request.
- respond with HTTP status code
400
(Bad Request). - return the following JSON response:
{ errorMessage: "Please provide title and contents for the post." }
.
-
If the information about the post is valid:
- save the new post the the database.
- return HTTP status code
201
(Created). - return the newly created post.
-
If there's an error while saving the post:
- cancel the request.
- respond with HTTP status code
500
(Server Error). - return the following JSON object:
{ error: "There was an error while saving the post to the database" }
.
When the client makes a POST
request to /api/posts/:id/comments
:
-
If the post with the specified
id
is not found:- return HTTP status code
404
(Not Found). - return the following JSON object:
{ message: "The post with the specified ID does not exist." }
.
- return HTTP status code
-
If the request body is missing the
text
property:- cancel the request.
- respond with HTTP status code
400
(Bad Request). - return the following JSON response:
{ errorMessage: "Please provide text for the comment." }
.
-
If the information about the comment is valid:
- save the new comment the the database.
- return HTTP status code
201
(Created). - return the newly created comment.
-
If there's an error while saving the comment:
- cancel the request.
- respond with HTTP status code
500
(Server Error). - return the following JSON object:
{ error: "There was an error while saving the comment to the database" }
.
When the client makes a GET
request to /api/posts
:
- If there's an error in retrieving the posts from the database:
- cancel the request.
- respond with HTTP status code
500
. - return the following JSON object:
{ error: "The posts information could not be retrieved." }
.
When the client makes a GET
request to /api/posts/:id
:
-
If the post with the specified
id
is not found:- return HTTP status code
404
(Not Found). - return the following JSON object:
{ message: "The post with the specified ID does not exist." }
.
- return HTTP status code
-
If there's an error in retrieving the post from the database:
- cancel the request.
- respond with HTTP status code
500
. - return the following JSON object:
{ error: "The post information could not be retrieved." }
.
When the client makes a GET
request to /api/posts/:id/comments
:
-
If the post with the specified
id
is not found:- return HTTP status code
404
(Not Found). - return the following JSON object:
{ message: "The post with the specified ID does not exist." }
.
- return HTTP status code
-
If there's an error in retrieving the comments from the database:
- cancel the request.
- respond with HTTP status code
500
. - return the following JSON object:
{ error: "The comments information could not be retrieved." }
.
When the client makes a DELETE
request to /api/posts/:id
:
-
If the post with the specified
id
is not found:- return HTTP status code
404
(Not Found). - return the following JSON object:
{ message: "The post with the specified ID does not exist." }
.
- return HTTP status code
-
If there's an error in removing the post from the database:
- cancel the request.
- respond with HTTP status code
500
. - return the following JSON object:
{ error: "The post could not be removed" }
.
When the client makes a PUT
request to /api/posts/:id
:
-
If the post with the specified
id
is not found:- return HTTP status code
404
(Not Found). - return the following JSON object:
{ message: "The post with the specified ID does not exist." }
.
- return HTTP status code
-
If the request body is missing the
title
orcontents
property:- cancel the request.
- respond with HTTP status code
400
(Bad Request). - return the following JSON response:
{ errorMessage: "Please provide title and contents for the post." }
.
-
If there's an error when updating the post:
- cancel the request.
- respond with HTTP status code
500
. - return the following JSON object:
{ error: "The post information could not be modified." }
.
-
If the post is found and the new information is valid:
- update the post document in the database using the new information sent in the
request body
. - return HTTP status code
200
(OK). - return the newly updated post.
- update the post document in the database using the new information sent in the
The data
folder contains a database populated with test posts
.
Database access will be done using the db.js
file included inside the data
folder.
The db.js
publishes the following methods.
find()
: calling find returns a promise that resolves to an array of all theposts
contained in the database.findById()
: this method expects anid
as it's only parameter and returns a promise that resolves to the post corresponding to theid
provided or an empty array if no post with thatid
is found.insert()
: calling insert passing it apost
object will add it to the database and return a promise that resolves to an object with theid
of the inserted post. The object looks like this:{ id: 123 }
.update()
: accepts two arguments, the first is theid
of the post to update and the second is an object with thechanges
to apply. It returns a promise that resolves to the count of updated records. If the count is 1 it means the record was updated correctly.remove()
: the remove method accepts anid
as its first parameter and upon successfully deleting the post from the database it returns a promise that resolves to the number of records deleted.findPostComments()
: the findPostComments accepts apostId
as its first parameter and returns a promise that resolves to an array of all comments on the post associated with the post id.findCommentById()
: accepts anid
and returns a promise that resolves to the comment associated with that id.insertComment()
: calling insertComment while passing it acomment
object will add it to the database and return a promise that resolves to an object with theid
of the inserted comment. The object looks like this:{ id: 123 }
. This method will throw an error if thepost_id
field in thecomment
object does not match a valid post id in the database.
Now that we have a way to add, update, remove and retrieve data from the provided database, it is time to work on the API.
A Blog Post in the database has the following structure:
{
title: "The post title", // String, required
contents: "The post contents", // String, required
created_at: Mon Aug 14 2017 12:50:16 GMT-0700 (PDT) // Date, defaults to current date
updated_at: Mon Aug 14 2017 12:50:16 GMT-0700 (PDT) // Date, defaults to current date
}
A Comment in the database has the following structure:
{
text: "The text of the comment", // String, required
post_id: "The id of the associated post", // Integer, required, must match the id of a post entry in the database
created_at: Mon Aug 14 2017 12:50:16 GMT-0700 (PDT) // Date, defaults to current date
updated_at: Mon Aug 14 2017 12:50:16 GMT-0700 (PDT) // Date, defaults to current date
}
To work on the stretch problems you'll need to enable the cors
middleware. Follow these steps:
- add the
cors
npm module:npm i cors
. - add
server.use(cors())
afterserver.use(express.json())
.
Create a new React application and connect it to your server:
- Use
create-react-app
to create an application inside the root folder, name itclient
. - From the React application connect to the
/api/posts
endpoint in the API and show the list of posts. - Style the list of posts however you see fit.
Follow these steps for completing your project.
- Submit a pull request to merge Branch into master (student's Repo). Please don't merge your own pull request