{"id":32563038,"url":"https://github.com/blevs/webapi-ii-routing","last_synced_at":"2026-07-12T00:31:03.943Z","repository":{"id":47390511,"uuid":"206378610","full_name":"Blevs/webapi-ii-routing","owner":"Blevs","description":null,"archived":false,"fork":false,"pushed_at":"2023-01-11T01:39:11.000Z","size":722,"stargazers_count":0,"open_issues_count":10,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-29T02:56:32.489Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Blevs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-09-04T17:48:43.000Z","updated_at":"2019-09-04T19:50:05.000Z","dependencies_parsed_at":"2023-02-08T21:45:16.811Z","dependency_job_id":null,"html_url":"https://github.com/Blevs/webapi-ii-routing","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Blevs/webapi-ii-routing","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Blevs%2Fwebapi-ii-routing","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Blevs%2Fwebapi-ii-routing/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Blevs%2Fwebapi-ii-routing/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Blevs%2Fwebapi-ii-routing/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Blevs","download_url":"https://codeload.github.com/Blevs/webapi-ii-routing/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Blevs%2Fwebapi-ii-routing/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35378722,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-11T02:00:05.354Z","response_time":104,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-10-29T02:56:14.304Z","updated_at":"2026-07-12T00:31:03.928Z","avatar_url":"https://github.com/Blevs.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Building RESTful APIs with Express\n\n## Topics\n\n- Express Routing\n- Reading Request data from body and URL parameters\n- Sub-routes\n- API design and development.\n\n## Description\n\nUse `Node.js` and `Express` to build an API that performs _CRUD_ operations on `blog posts`.\n\n### Project Setup\n\n- **Fork** and **Clone** this repository.\n- **CD into the folder** where you cloned the repository.\n- Type `npm install` to download all dependencies.\n- 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.\n\n### Database Persistence Helpers\n\nThe `data` folder contains a database populated with test `posts`.\n\nDatabase access will be done using the `db.js` file included inside the `data` folder.\n\nThe `db.js` publishes the following methods:\n\n- `find()`: calling find returns a promise that resolves to an array of all the `posts` contained in the database.\n- `findById()`: this method expects an `id` as it's only parameter and returns the post corresponding to the `id` provided or an empty array if no post with that `id` is found.\n- `insert()`: calling insert passing it a `post` object will add it to the database and return an object with the `id` of the inserted post. The object looks like this: `{ id: 123 }`.\n- `update()`: accepts two arguments, the first is the `id` of the post to update and the second is an object with the `changes` to apply. It returns the count of updated records. If the count is 1 it means the record was updated correctly.\n- `remove()`: the remove method accepts an `id` as its first parameter and upon successfully deleting the post from the database it returns the number of records deleted.\n- `findPostComments()`: the findPostComments accepts a `postId` as its first parameter and returns all comments on the post associated with the post id.\n- `findCommentById()`: accepts an `id` and returns the comment associated with that id.\n- `insertComment()`: calling insertComment while passing it a `comment` object will add it to the database and return an object with the `id` of the inserted comment. The object looks like this: `{ id: 123 }`. This method will throw an error if the `post_id` field in the `comment` object does not match a valid post id in the database.\n\nNow that we have a way to add, update, remove and retrieve data from the provided database, it is time to work on the API.\n\n### Blog Post Schema\n\nA Blog Post in the database has the following structure:\n\n```js\n{\n  title: \"The post title\", // String, required\n  contents: \"The post contents\", // String, required\n  created_at: Mon Aug 14 2017 12:50:16 GMT-0700 (PDT) // Date, defaults to current date\n  updated_at: Mon Aug 14 2017 12:50:16 GMT-0700 (PDT) // Date, defaults to current date\n}\n```\n\n### Comment Schema\n\nA Comment in the database has the following structure:\n\n```js\n{\n  text: \"The text of the comment\", // String, required\n  post_id: \"The id of the associated post\", // Integer, required, must match the id of a post entry in the database\n  created_at: Mon Aug 14 2017 12:50:16 GMT-0700 (PDT) // Date, defaults to current date\n  updated_at: Mon Aug 14 2017 12:50:16 GMT-0700 (PDT) // Date, defaults to current date\n}\n```\n\n### Minimum Viable Product\n\n- Add the code necessary to implement the endpoints listed below.\n- Separate the endpoints that begin with `/api/posts` into a separate `Express Router`.\n\n### Endpoints\n\nConfigure the API to handle to the following routes:\n\n| Method | Endpoint                | Description                                                                                                                                                                 |\n| ------ | ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| POST   | /api/posts              | Creates a post using the information sent inside the `request body`.                                                                                                        |\n| POST   | /api/posts/:id/comments | Creates a comment for the post with the specified id using information sent inside of the `request body`.                                                                   |\n| GET    | /api/posts              | Returns an array of all the post objects contained in the database.                                                                                                         |\n| GET    | /api/posts/:id          | Returns the post object with the specified id.                                                                                                                              |\n| GET    | /api/posts/:id/comments | Returns an array of all the comment objects associated with the post with the specified id.                                                                                 |\n| 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. |\n| PUT    | /api/posts/:id          | Updates the post with the specified `id` using data from the `request body`. Returns the modified document, **NOT the original**.                                           |\n\n#### Endpoint Specifications\n\nWhen the client makes a `POST` request to `/api/posts`:\n\n- If the request body is missing the `title` or `contents` property:\n\n  - cancel the request.\n  - respond with HTTP status code `400` (Bad Request).\n  - return the following JSON response: `{ errorMessage: \"Please provide title and contents for the post.\" }`.\n\n- If the information about the _post_ is valid:\n\n  - save the new _post_ the the database.\n  - return HTTP status code `201` (Created).\n  - return the newly created _post_.\n\n- If there's an error while saving the _post_:\n  - cancel the request.\n  - respond with HTTP status code `500` (Server Error).\n  - return the following JSON object: `{ error: \"There was an error while saving the post to the database\" }`.\n\nWhen the client makes a `POST` request to `/api/posts/:id/comments`:\n\n- If the _post_ with the specified `id` is not found:\n\n  - return HTTP status code `404` (Not Found).\n  - return the following JSON object: `{ message: \"The post with the specified ID does not exist.\" }`.\n\n- If the request body is missing the `text` property:\n\n  - cancel the request.\n  - respond with HTTP status code `400` (Bad Request).\n  - return the following JSON response: `{ errorMessage: \"Please provide text for the comment.\" }`.\n\n- If the information about the _comment_ is valid:\n\n  - save the new _comment_ the the database.\n  - return HTTP status code `201` (Created).\n  - return the newly created _comment_.\n\n- If there's an error while saving the _comment_:\n  - cancel the request.\n  - respond with HTTP status code `500` (Server Error).\n  - return the following JSON object: `{ error: \"There was an error while saving the comment to the database\" }`.\n\nWhen the client makes a `GET` request to `/api/posts`:\n\n- If there's an error in retrieving the _posts_ from the database:\n  - cancel the request.\n  - respond with HTTP status code `500`.\n  - return the following JSON object: `{ error: \"The posts information could not be retrieved.\" }`.\n\nWhen the client makes a `GET` request to `/api/posts/:id`:\n\n- If the _post_ with the specified `id` is not found:\n\n  - return HTTP status code `404` (Not Found).\n  - return the following JSON object: `{ message: \"The post with the specified ID does not exist.\" }`.\n\n- If there's an error in retrieving the _post_ from the database:\n  - cancel the request.\n  - respond with HTTP status code `500`.\n  - return the following JSON object: `{ error: \"The post information could not be retrieved.\" }`.\n\nWhen the client makes a `GET` request to `/api/posts/:id/comments`:\n\n- If the _post_ with the specified `id` is not found:\n\n  - return HTTP status code `404` (Not Found).\n  - return the following JSON object: `{ message: \"The post with the specified ID does not exist.\" }`.\n\n- If there's an error in retrieving the _comments_ from the database:\n  - cancel the request.\n  - respond with HTTP status code `500`.\n  - return the following JSON object: `{ error: \"The comments information could not be retrieved.\" }`.\n\nWhen the client makes a `DELETE` request to `/api/posts/:id`:\n\n- If the _post_ with the specified `id` is not found:\n\n  - return HTTP status code `404` (Not Found).\n  - return the following JSON object: `{ message: \"The post with the specified ID does not exist.\" }`.\n\n- If there's an error in removing the _post_ from the database:\n  - cancel the request.\n  - respond with HTTP status code `500`.\n  - return the following JSON object: `{ error: \"The post could not be removed\" }`.\n\nWhen the client makes a `PUT` request to `/api/posts/:id`:\n\n- If the _post_ with the specified `id` is not found:\n\n  - return HTTP status code `404` (Not Found).\n  - return the following JSON object: `{ message: \"The post with the specified ID does not exist.\" }`.\n\n- If the request body is missing the `title` or `contents` property:\n\n  - cancel the request.\n  - respond with HTTP status code `400` (Bad Request).\n  - return the following JSON response: `{ errorMessage: \"Please provide title and contents for the post.\" }`.\n\n- If there's an error when updating the _post_:\n\n  - cancel the request.\n  - respond with HTTP status code `500`.\n  - return the following JSON object: `{ error: \"The post information could not be modified.\" }`.\n\n- If the post is found and the new information is valid:\n\n  - update the post document in the database using the new information sent in the `request body`.\n  - return HTTP status code `200` (OK).\n  - return the newly updated _post_.\n\n## Stretch Problems\n\nTo work on the stretch problems you'll need to enable the `cors` middleware. Follow these steps:\n\n- add the `cors` npm module: `npm i cors`.\n- add `server.use(cors())` after `server.use(express.json())`.\n\nCreate a new React application and connect it to your server:\n\n- Use `create-react-app` to create an application inside the root folder, name it `client`.\n- From the React application connect to the `/api/posts` endpoint in the API and show the list of posts.\n- Style the list of posts however you see fit.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fblevs%2Fwebapi-ii-routing","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fblevs%2Fwebapi-ii-routing","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fblevs%2Fwebapi-ii-routing/lists"}