Menu
CoddyTech

Belgeleri Silme

Coddy'nin Node.js Journey'sinin MongoDB ile Veritabanları bölümünün bir parçası. Ders 16 / 29.

Bir kitabı silmek tek bir çağrı gerektirir, ancak sunucunun yine de istemciye silinecek bir kitap olup olmadığını bildirmesi gerekir.

deleteOne(filter), eşleşen ilk belgeyi siler ve { deletedCount } yanıtını verir: bir belge sildiyse 1, hiçbir eşleşme yoksa 0. Başarılı bir silme işlemi, gövdesi olmayan bir durum kodu olan 204 No Content yanıtını verir; bu yanıt res.status(204).end() ile gönderilir.

const result = await sessions.deleteOne({ token });
if (result.deletedCount === 0) {
    // hiçbir oturumda o token yoktu
}

Aynı kimliği iki kez silmek iki kez başarılı olmamalıdır. İkinci seferde silinecek hiçbir şey kalmaz ve istemci 404 yanıtını almalıdır.

challenge icon

Görev

Kolay

İstemciler bir kitabı silebilir ve silinecek bir kitap olup olmadığını bilmeleri gerekir.

  1. server.js dosyasına DELETE /books/:id rotasını ekle. Geçersiz bir kimlik için 400 yanıtı veren parseId işlevini kullan.
  2. Rota bir kitabı sildiğinde, 204 durum koduyla ve hiç gövde göndermeden yanıt ver. JSON göndermeden yanıtı sonlandır.
  3. Bu _id değerine sahip bir kitap yoksa, örneğin { "error": "No such book" } gibi bir hata ile 404 durum koduyla yanıt ver. Yani aynı kitabı ikinci kez silmeye çalışmak da 404 yanıtı verir, çünkü kitap zaten silinmiştir. Şunu dene: GET /books isteğini gönder ve Emma'nın _id değerini kopyala. DELETE /books/<Emma's _id> isteğini gönder: 204 yanıtı ve boş bir gövde alırsın. Aynı isteği tekrar gönder: 404 yanıtı alırsın. GET /books/<Emma's _id> isteğini gönder: yine 404 yanıtı alırsın. GET /books isteğini gönder: yalnızca Dune ve Kindred kitaplarını alırsın ve Data sekmesinde iki kitap görünür. Emma'yı geri getirmek için Run düğmesine bas.

Kendin dene

import express from 'express';
import { MongoClient, ObjectId } from 'mongodb';

const client = new MongoClient('mongodb://localhost:27017');
const db = client.db('shelf');
const books = db.collection('books');

await books.insertMany([
    { title: 'Dune', author: 'Frank Herbert', year: 1965, isbn: '9780441013593', genre: 'scifi' },
    { title: 'Kindred', author: 'Octavia E. Butler', year: 1979, isbn: '9780807083697', genre: 'scifi' },
    { title: 'Emma', author: 'Jane Austen', year: 1815, isbn: '9780141439587', genre: 'classic' },
]);

const app = express();
app.use(express.json());

// Her hata { error: message } biçiminde yanıt döndürür.
function sendError(res, status, message) {
    res.status(status).json({ error: message });
}

// Geçerli bir :id için ObjectId döndürür; geçersiz bir id için 400 yanıtı verdikten sonra null döndürür.
function parseId(req, res) {
    if (ObjectId.isValid(req.params.id)) {
        return new ObjectId(req.params.id);
    }
    sendError(res, 400, 'Not a valid id');
    return null;
}

app.get('/', (req, res) => {
    res.send('Bookshelf API');
});

app.get('/books', async (req, res) => {
    const filter = {};
    if (req.query.author) {
        filter.author = req.query.author;
    }
    if (req.query.from || req.query.to) {
        filter.year = {};
        if (req.query.from) {
            filter.year.$gte = Number(req.query.from);
        }
        if (req.query.to) {
            filter.year.$lte = Number(req.query.to);
        }
    }
    const list = await books.find(filter).toArray();
    res.json(list);
});

app.post('/books', async (req, res) => {
    const book = req.body;
    await books.insertOne(book);
    res.status(201).json(book);
});

app.get('/books/newest', async (req, res) => {
    const n = Number(req.query.n) || 3;
    const list = await books
        .find({}, { projection: { title: 1, year: 1, _id: 0 } })
        .sort({ year: -1 })
        .limit(n)
        .toArray();
    res.json(list);
});

app.get('/books/:id', async (req, res) => {
    const id = parseId(req, res);
    if (!id) return;
    const book = await books.findOne({ _id: id });
    if (!book) {
        return sendError(res, 404, 'No such book');
    }
    res.json(book);
});

app.patch('/books/:id', async (req, res) => {
    const id = parseId(req, res);
    if (!id) return;
    const result = await books.updateOne({ _id: id }, { $set: req.body });
    if (result.matchedCount === 0) {
        return sendError(res, 404, 'No such book');
    }
    res.json(await books.findOne({ _id: id }));
});

app.post('/books/:id/copies', async (req, res) => {
    const id = parseId(req, res);
    if (!id) return;
    const result = await books.updateOne({ _id: id }, { $inc: { copies: 1 } });
    if (result.matchedCount === 0) {
        return sendError(res, 404, 'No such book');
    }
    res.json(await books.findOne({ _id: id }));
});

app.post('/books/:id/tags', async (req, res) => {
    const id = parseId(req, res);
    if (!id) return;
    const result = await books.updateOne({ _id: id }, { $push: { tags: req.body.tag } });
    if (result.matchedCount === 0) {
        return sendError(res, 404, 'No such book');
    }
    res.json(await books.findOne({ _id: id }));
});

app.listen(3000, () => {
    console.log('Bookshelf is running on port 3000');
});

MongoDB ile Veritabanları bölümündeki tüm dersler

Kendi başına pratik yap: Express playground