0% found this document useful (0 votes)
4 views7 pages

Creating A Simple Restful Api Assignment

The document outlines the implementation of a simple RESTful API using Node.js and Express for managing items, including CRUD operations (GET, POST, PUT, DELETE). It provides source code, setup instructions, API documentation, testing examples, and a report detailing the implementation process, challenges, and key learnings. The API supports JSON requests and responses, with basic validation and error handling in place.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4 views7 pages

Creating A Simple Restful Api Assignment

The document outlines the implementation of a simple RESTful API using Node.js and Express for managing items, including CRUD operations (GET, POST, PUT, DELETE). It provides source code, setup instructions, API documentation, testing examples, and a report detailing the implementation process, challenges, and key learnings. The API supports JSON requests and responses, with basic validation and error handling in place.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd

1. Source code (app.

js)
// [Link]
const express = require('express');
const app = express();

[Link]([Link]()); // parse JSON bodies

// Simple in-memory store


let items = [
{ id: 1, title: 'The Matrix', director: 'Lana Wachowski', year: 1999 },
{ id: 2, title: 'Inception', director: 'Christopher Nolan', year: 2010 }
];

// Next id generator (simple)


let nextId = [Link] ? [Link](...[Link](i => [Link])) + 1 : 1;

/*
GET /items
- Return array of all items
*/
[Link]('/items', (req, res) => {
[Link](200).json(items);
});

/*
POST /items
- Create a new item. Required fields: title, director.
- Optional: year (integer)
- Expects Content-Type: application/json
*/
[Link]('/items', (req, res) => {
const { title, director, year } = [Link];

// Basic validation
if (!title || typeof title !== 'string' || ![Link]()) {
return [Link](400).json({ error: "Field 'title' is required and must
be a string." });
}
if (!director || typeof director !== 'string' || ![Link]()) {
return [Link](400).json({ error: "Field 'director' is required and
must be a string." });
}
if (year !== undefined && ![Link](year)) {
// allow string numbers by parsing? Here we enforce integer
return [Link](400).json({ error: "Field 'year' must be an integer if
provided." });
}

const newItem = {
id: nextId++,
title: [Link](),
director: [Link]()
};
if (year !== undefined) [Link] = year;
[Link](newItem);
return [Link](201).json(newItem);
});

/*
PUT /items/:id
- Update an existing item by id
- Partial update allowed: accept any subset of fields (title, director,
year)
*/
[Link]('/items/:id', (req, res) => {
const id = parseInt([Link], 10);
if (![Link](id)) {
return [Link](400).json({ error: 'Invalid id parameter.' });
}

const item = [Link](i => [Link] === id);


if (!item) return [Link](404).json({ error: 'Item not found.' });

const { title, director, year } = [Link];

if (title !== undefined) {


if (typeof title !== 'string' || ![Link]()) return
[Link](400).json({ error: "Field 'title' must be a non-empty string." });
[Link] = [Link]();
}
if (director !== undefined) {
if (typeof director !== 'string' || ![Link]()) return
[Link](400).json({ error: "Field 'director' must be a non-empty
string." });
[Link] = [Link]();
}
if (year !== undefined) {
if (![Link](year)) return [Link](400).json({ error: "Field
'year' must be an integer." });
[Link] = year;
}

return [Link](200).json(item);
});

/*
DELETE /items/:id
- Delete item by id
*/
[Link]('/items/:id', (req, res) => {
const id = parseInt([Link], 10);
if (![Link](id)) {
return [Link](400).json({ error: 'Invalid id parameter.' });
}

const idx = [Link](i => [Link] === id);


if (idx === -1) return [Link](404).json({ error: 'Item not found.' });

[Link](idx, 1);
return [Link](200).json({ message: 'Item deleted.' });
});
// Generic 404 for other routes
[Link]((req, res) => {
[Link](404).json({ error: 'Not found' });
});

// Error handler (simple)


[Link]((err, req, res, next) => {
[Link](err);
[Link](500).json({ error: 'Internal server error' });
});

// Start server
const PORT = [Link] || 3000;
[Link](PORT, () => {
[Link](`Server running on [Link]
});

2. Configuration files
[Link]

{
"name": "express-items-api",
"version": "1.0.0",
"description": "Simple RESTful API for items (Express)",
"main": "[Link]",
"scripts": {
"start": "node [Link]",
"dev": "nodemon [Link]"
},
"dependencies": {
"express": "^4.18.2"
},
"devDependencies": {
"nodemon": "^2.0.22"
},
"author": "",
"license": "MIT"
}

.gitignore

node_modules/
.env

3. Setup & run instructions


1. Node & npm: Ensure [Link] (v14+) and npm are installed.
2. Create project folder and place [Link], [Link], .gitignore.
3. Install dependencies:
4. npm install
5. npm install --save-dev nodemon # optional for dev
6. Run:
o Development (auto-restart):
o npm run dev
o Production:
o npm start
7. API will be reachable at [Link]

4. API Documentation (clear & detailed)


Base URL: [Link]

4.1 GET /items

 Description: Retrieve all items.


 Request: GET /items
 Response: 200 OK

[
{ "id": 1, "title": "The Matrix", "director": "Lana Wachowski", "year": 1999
},
{ "id": 2, "title": "Inception", "director": "Christopher Nolan", "year":
2010 }
]

4.2 POST /items

 Description: Add a new item.


 Request: POST /items
o Headers: Content-Type: application/json
o Body (JSON):
o { "title": "Interstellar", "director": "Christopher Nolan",
"year": 2014 }
 Validations:
o title (string) required
o director (string) required
o year (integer) optional
 Responses:
o 201 Created with created object
o 400 Bad Request when missing/invalid fields

Example response (201):


{ "id": 3, "title": "Interstellar", "director": "Christopher Nolan", "year":
2014 }

4.3 PUT /items/{id}

 Description: Update existing item (partial updates allowed).


 Request: PUT /items/3
o Headers: Content-Type: application/json
o Body: any subset of { title, director, year }
 Responses:
o 200 OK with updated object
o 400 Bad Request invalid payload
o 404 Not Found if id doesn't exist

Example request body

{ "title": "Interstellar (Extended)", "year": 2015 }

4.4 DELETE /items/{id}

 Description: Delete item by id.


 Request: DELETE /items/3
 Responses:
o 200 OK { "message": "Item deleted." }
o 404 Not Found if id doesn't exist

5. Testing (Postman & curl examples)


Using curl

GET all

curl -i [Link]

POST create

curl -i -X POST [Link] \


-H "Content-Type: application/json" \
-d '{"title":"Interstellar","director":"Christopher Nolan","year":2014}'

PUT update

curl -i -X PUT [Link] \


-H "Content-Type: application/json" \
-d '{"title":"Interstellar (Remastered)"}'
DELETE

curl -i -X DELETE [Link]

Using Postman

1. Create a new Collection Items API.


2. Add requests for each endpoint:
o GET [Link]
o POST [Link] (Body → raw → JSON)
o PUT [Link]
o DELETE [Link]
3. For POST/PUT set header Content-Type: application/json.
4. Send and verify response codes & body match documentation.

Suggested tests to include:

 Create item with missing title → expect 400.


 Update non-existent id → expect 404.
 Delete existing item → follow by GET to ensure removed.

6. Report (Implementation process, challenges, key


learnings)
Implementation process

1. Choice of tech: [Link] with Express for minimal boilerplate and wide familiarity.
2. Data store: Used in-memory items array to keep the assignment simple and easily
testable.
3. Routes: Implemented the required CRUD endpoints (GET, POST, PUT, DELETE).
4. Validation: Added basic server-side validation for required fields and types.
5. Error handling: Return appropriate HTTP status codes and JSON error messages.
6. Testing: Manual testing with curl and Postman to cover success and error cases.

Challenges faced

 Validation choices: Deciding how strict to be (e.g., should year accept string digits?). I
enforced integer year to keep parsing predictable.
 Persistence: In-memory storage is volatile; for persistence, a DB (SQLite/Postgres) is
required.
 Edge cases: Ensuring update requests can be partial and still validated for types.

Key learnings
 REST design requires clear mapping of HTTP verbs and status codes.
 Input validation prevents malformed data entering the system and provides clearer
feedback to clients.
 Even a basic API benefits from a concise documentation and consistent error responses.

7. Submission checklist (what to hand in)


 [Link] — source code (required)
 [Link] — dependencies and scripts (required)
 [Link] — Setup/run/testing instructions (include content above in your README)
 Report (can be the "Report" section above copied into a document)
 API documentation (copy section 4 into docs)
 Optional: Postman collection export JSON (recommended)

You might also like