b.title.toLowerCase() === title.toLowerCase()); if (!book) throw new Error(`Book "${title}" not found`); return book; } // Asynchronous: add a new book function addBookAsync(newBook, callback) { setTimeout(() => { books.push(newBook); callback(null, newBook); // null = no error }, 1000); // simulate database delay } // Asynchronous: search book function searchBookAsync(title, callback) { setTimeout(() => { const book = books.find(b => b.title.toLowerCase() === title.toLowerCase()); if (!book) { callback(`Book "${title}" not found`); } else { callback(null, book); } }, 1000); } module.exports = { viewBooks, se"> b.title.toLowerCase() === title.toLowerCase()); if (!book) throw new Error(`Book "${title}" not found`); return book; } // Asynchronous: add a new book function addBookAsync(newBook, callback) { setTimeout(() => { books.push(newBook); callback(null, newBook); // null = no error }, 1000); // simulate database delay } // Asynchronous: search book function searchBookAsync(title, callback) { setTimeout(() => { const book = books.find(b => b.title.toLowerCase() === title.toLowerCase()); if (!book) { callback(`Book "${title}" not found`); } else { callback(null, book); } }, 1000); } module.exports = { viewBooks, se"> b.title.toLowerCase() === title.toLowerCase()); if (!book) throw new Error(`Book "${title}" not found`); return book; } // Asynchronous: add a new book function addBookAsync(newBook, callback) { setTimeout(() => { books.push(newBook); callback(null, newBook); // null = no error }, 1000); // simulate database delay } // Asynchronous: search book function searchBookAsync(title, callback) { setTimeout(() => { const book = books.find(b => b.title.toLowerCase() === title.toLowerCase()); if (!book) { callback(`Book "${title}" not found`); } else { callback(null, book); } }, 1000); } module.exports = { viewBooks, se">

image.png

// library.js

let books = [
  { id: 1, title: "Harry Potter", author: "J.K. Rowling" },
  { id: 2, title: "The Hobbit", author: "J.R.R. Tolkien" },
];

// Synchronous: view all books
function viewBooks() {
  return books;
}

// Synchronous: search for a book by title
function searchBook(title) {
  const book = books.find(b => b.title.toLowerCase() === title.toLowerCase());
  if (!book) throw new Error(`Book "${title}" not found`);
  return book;
}

// Asynchronous: add a new book
function addBookAsync(newBook, callback) {
  setTimeout(() => {
    books.push(newBook);
    callback(null, newBook); // null = no error
  }, 1000); // simulate database delay
}

// Asynchronous: search book
function searchBookAsync(title, callback) {
  setTimeout(() => {
    const book = books.find(b => b.title.toLowerCase() === title.toLowerCase());
    if (!book) {
      callback(`Book "${title}" not found`);
    } else {
      callback(null, book);
    }
  }, 1000);
}

module.exports = {
  viewBooks,
  searchBook,
  addBookAsync,
  searchBookAsync
};

// index.js
const express = require('express');
const library = require('./library');

const app = express();
const PORT = 3000;

app.use(express.json()); // for parsing JSON request bodies

// GET all books (synchronous)
app.get('/books', (req, res) => {
  res.json(library.viewBooks());
});

// GET book by title (synchronous)
app.get('/books/search', (req, res) => {
  const title = req.query.title;
  try {
    const book = library.searchBook(title);
    res.json(book);
  } catch (err) {
    res.status(404).json({ error: err.message });
  }
});

// POST add a new book (asynchronous)
app.post('/books', (req, res) => {
  const newBook = req.body;
  library.addBookAsync(newBook, (err, book) => {
    if (err) {
      return res.status(500).json({ error: err });
    }
    res.status(201).json(book);
  });
});

// GET book by title (asynchronous)
app.get('/books/async-search', (req, res) => {
  const title = req.query.title;
  library.searchBookAsync(title, (err, book) => {
    if (err) {
      return res.status(404).json({ error: err });
    }
    res.json(book);
  });
});

app.listen(PORT, () => {
  console.log(`Library API running at <http://localhost>:${PORT}`);
});

image.png