Çakışmalar
Coddy'nin Node.js Journey'sinin REST API'leri bölümünün bir parçası. Ders 9 / 18.
"Faturayı gönder" adlı ikinci bir görev listeyi kafa karıştırıcı hâle getiriyor, ancak gövdesi geçerli. Bu bir 409 Çakışma hatasıdır: istek, zaten kaydedilmiş olanlarla çelişir. 400, gövdenin kendisinin hatalı olduğu anlamına gelir.
const taken = users.some((u) => u.name.toLowerCase() === name.toLowerCase());
if (taken) {
return sendError(res, 409, 'conflict', 'That username is taken');
}İnsanlar "Ada" ve "ada" adlarını aynı kabul ettiğinden, küçük harfe dönüştürerek karşılaştırın. Bir istek bir şeyi yeniden adlandırdığında, arama sırasında öğenin kendisini atlayın. Aksi takdirde, adını değiştirmeden formu kaydeden bir kullanıcı kendisiyle çakışır.
Görev
Kolay- Büyük/küçük harf fark etmeksizin başka bir görevin zaten sahip olduğu bir başlık, POST isteklerinde ve PATCH ile PUT isteklerinde başlık ayarlandığında
conflictkoduyla 409 yanıtı verir. - Bir görev kendi başlığını koruyabilir.
{ "title": "book the meeting room" } ile POST isteği gönderin, ardından { "title": "Book the meeting room", "done": true } ile PUT /api/tasks/2 isteği gönderin.
Kendin dene
import { Router } from 'express';
import { z } from 'zod';
import { sendError, sendInvalid } from '../errors.js';
import { nextId, tasks } from '../store.js';
const router = Router();
// PUT tarafından gönderildiği biçimiyle eksiksiz bir görev. .strict(), listelemediği alanları reddeder.
const Task = z
.object({
title: z.string().trim().min(1).max(100),
done: z.boolean(),
})
.strict();
const NewTask = Task.partial({ done: true });
const TaskChanges = Task.partial();
router.get('/', (req, res) => {
res.json(tasks);
});
router.get('/:id', (req, res) => {
const task = tasks.find((t) => t.id === Number(req.params.id));
if (!task) {
return sendError(res, 404, 'not_found', 'Task not found');
}
res.json(task);
});
router.post('/', (req, res) => {
const result = NewTask.safeParse(req.body);
if (!result.success) {
return sendInvalid(res, result.error);
}
const { title, done = false } = result.data;
const task = { id: nextId(), title, done, createdAt: new Date().toISOString() };
tasks.push(task);
res.status(201).location(`/api/tasks/${task.id}`).json(task);
});
router.patch('/:id', (req, res) => {
const task = tasks.find((t) => t.id === Number(req.params.id));
if (!task) {
return sendError(res, 404, 'not_found', 'Task not found');
}
const result = TaskChanges.safeParse(req.body);
if (!result.success) {
return sendInvalid(res, result.error);
}
Object.assign(task, result.data);
res.json(task);
});
router.put('/:id', (req, res) => {
const index = tasks.findIndex((t) => t.id === Number(req.params.id));
if (index === -1) {
return sendError(res, 404, 'not_found', 'Task not found');
}
const result = Task.safeParse(req.body);
if (!result.success) {
return sendInvalid(res, result.error);
}
const { id, createdAt } = tasks[index];
tasks[index] = { id, ...result.data, createdAt };
res.json(tasks[index]);
});
router.delete('/:id', (req, res) => {
const index = tasks.findIndex((t) => t.id === Number(req.params.id));
if (index === -1) {
return sendError(res, 404, 'not_found', 'Task not found');
}
tasks.splice(index, 1);
res.status(204).end();
});
export default router;