Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 53 additions & 4 deletions pages/api/tracks/[id].ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,29 @@
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import { NextApiRequest, NextApiResponse } from "next";
import db from "../../../server/db.json";
import { readDb, writeDb } from "../../../server/db";
import { APITrack } from "../../../utils/api";

export default (req: NextApiRequest, res: NextApiResponse) => {
type Methods = {
[method: string]: (req: NextApiRequest, res: NextApiResponse) => void;
};
const methods: Methods = {
GET: handleGet,
PATCH: handlePatch,
DELETE: handleDelete,
};
export default async (req: NextApiRequest, res: NextApiResponse) => {
const method = methods[req.method];
if (!method) {
return res.status(405).json({
status: 405,
error: "Method not allowed",
});
}
await method(req, res);
};

async function handleGet(req: NextApiRequest, res: NextApiResponse) {
const { id } = req.query;
const db = await readDb();
const track = db.tracks.find((track) => track.id === id);
if (!track) {
return res.status(404).json({
Expand All @@ -12,4 +32,33 @@ export default (req: NextApiRequest, res: NextApiResponse) => {
});
}
res.status(200).json(track);
};
}

async function handlePatch(req: NextApiRequest, res: NextApiResponse) {
const { id } = req.query;
const partialTrack: APITrack = req.body;

const db = await readDb();
const track = db.tracks.find((track) => track.id === id);
if (!track) {
return res.status(404).json({
status: 404,
error: "Track not found",
});
}
Object.assign(track, partialTrack);
await writeDb(db);
res.status(200).json(track);
}

async function handleDelete(req: NextApiRequest, res: NextApiResponse) {
const { id } = req.query;

const db = await readDb();
db.tracks = db.tracks.filter((track) => track.id !== id);
await writeDb(db);
res.status(202).json({
status: 202,
message: "Track deleted",
});
}
42 changes: 38 additions & 4 deletions pages/api/tracks/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,41 @@
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import { NextApiRequest, NextApiResponse } from "next";
import db from "../../../server/db.json";
import { readDb, writeDb } from "../../../server/db";
import { APITrack } from "../../../utils/api";

export default (_req: NextApiRequest, res: NextApiResponse) => {
res.status(200).json(db.tracks);
type Methods = {
[method: string]: (req: NextApiRequest, res: NextApiResponse) => void;
};
const methods: Methods = {
GET: handleGet,
POST: handlePost,
};
export default async (req: NextApiRequest, res: NextApiResponse) => {
const method = methods[req.method];
if (!method) {
return res.status(405).json({
status: 405,
error: "Method not allowed",
});
}
await method(req, res);
};

async function handleGet(req: NextApiRequest, res: NextApiResponse) {
const db = await readDb();
res.status(200).json(db.tracks);
}

async function handlePost(req: NextApiRequest, res: NextApiResponse) {
const newTrack: APITrack = req.body;
const db = await readDb();
const trackExists = db.tracks.some((track) => track.id === newTrack.id);
if (trackExists) {
return res.status(409).json({
status: 409,
error: "Track already exists",
});
}
db.tracks.push(newTrack);
await writeDb(db);
res.status(201).json(newTrack);
}
7 changes: 7 additions & 0 deletions server/db.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@
"title": "The Unforgiven",
"artist": "Metallica",
"audioSrc": "https://files.freemusicarchive.org/storage-freemusicarchive-org/music/KBOO/The_Underscore_Orkestra/No_Money_No_Honey_All_We_Got_Is_Us/The_Underscore_Orkestra_-_04_-_Magdalena.mp3"
},
{
"id": "test",
"imgSrc": "https://images.unsplash.com/photo-1613473060226-dd81153a63db?ixid=MXwxMjA3fDB8MHxlZGl0b3JpYWwtZmVlZHwyfHx8ZW58MHx8fA%3D%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=60",
"title": "Paul is Alive",
"artist": "Scooter",
"audioSrc": "https://files.freemusicarchive.org/storage-freemusicarchive-org/music/KBOO/The_Underscore_Orkestra/No_Money_No_Honey_All_We_Got_Is_Us/The_Underscore_Orkestra_-_02_-_Blue_Draggish.mp3"
}
]
}
19 changes: 19 additions & 0 deletions server/db.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import fs from "fs/promises";
import type { APITrack } from "../utils/api";

type DB = {
tracks: APITrack[];
};

const DB_FILE = "./server/db.json"; // Relative to entry point

export async function readDb() {
const dbJson = await fs.readFile(DB_FILE, "utf-8");
const db: DB = JSON.parse(dbJson);
return db;
}

export async function writeDb(newDb: DB) {
const dbJson = JSON.stringify(newDb, null, 2);
await fs.writeFile(DB_FILE, dbJson);
}
32 changes: 32 additions & 0 deletions server/samples.http
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
### GET all tracks
http://localhost:3000/api/tracks

### GET a single track

http://localhost:3000/api/tracks/scooter_paul-is-dead

### POST a new track

POST http://localhost:3000/api/tracks HTTP/1.1
content-type: application/json

{
"id": "test",
"imgSrc": "https://images.unsplash.com/photo-1613473060226-dd81153a63db?ixid=MXwxMjA3fDB8MHxlZGl0b3JpYWwtZmVlZHwyfHx8ZW58MHx8fA%3D%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=60",
"title": "Paul is Dead",
"artist": "Scooter",
"audioSrc": "https://files.freemusicarchive.org/storage-freemusicarchive-org/music/KBOO/The_Underscore_Orkestra/No_Money_No_Honey_All_We_Got_Is_Us/The_Underscore_Orkestra_-_02_-_Blue_Draggish.mp3"
}

### PATCH an existing track

PATCH http://localhost:3000/api/tracks/test HTTP/1.1
content-type: application/json

{
"title": "Paul is Alive"
}

### DELETE a track

DELETE http://localhost:3000/api/tracks/test HTTP/1.1