この記事の目次
Setting up the project
Run these commands:
mkdir book-api cd book-api npm init -y npm install express mongoose npm install --save-dev typescript @types/express @types/mongoose @types/node ts-node nodemon
Create a tsconfig.json file for TypeScript configuration:
{ "compilerOptions": { "target": "es6", "module": "commonjs", "outDir": "./dist", "strict": true, "esModuleInterop": true } }
Defining the Book Model
Create a new file src/models/book.ts
to define the structure of our book entries:
import mongoose, { Document, Schema } from 'mongoose'; interface IBook extends Document { title: string; author: string; publishedYear: number; genre: string; } const BookSchema = new Schema({ title: { type: String, required: true }, author: { type: String, required: true }, publishedYear: { type: Number, required: true }, genre: { type: String, required: true } }); export default mongoose.model<IBook>('Book', BookSchema);
This schema defines the attributes each book entry will have in our database.
Setting Up API Routes
Create a new file src/routes/books.ts
to define the CRUD operations:
import express, { Request, Response } from 'express'; import Book from '../models/book'; const router = express.Router(); // GET all books router.get('/', async (req: Request, res: Response) => { try { const books = await Book.find(); res.json(books); } catch (err) { res.status(500).json({ message: err.message }); } }); // POST a new book router.post('/', async (req: Request, res: Response) => { const book = new Book({ title: req.body.title, author: req.body.author, publishedYear: req.body.publishedYear, genre: req.body.genre }); try { const newBook = await book.save(); res.status(201).json(newBook); } catch (err) { res.status(400).json({ message: err.message }); } }); // Additional routes for GET, PATCH, and DELETE operations on individual books can be added here export default router;
Creating the Main Application File
Create src/index.ts to bring everything together:
import express from 'express'; import mongoose from 'mongoose'; import bookRoutes from './routes/books'; const app = express(); const PORT = 3000; app.use(express.json()); app.use('/books', bookRoutes); mongoose.connect('mongodb://localhost/bookstore', { useNewUrlParser: true, useUnifiedTopology: true }) .then(() => console.log('Connected to MongoDB')) .catch(err => console.error('Could not connect to MongoDB:', err)); app.listen(PORT, () => { console.log(`Server is running on port ${PORT}`); });
This file sets up the Express server, connects to MongoDB, and implements the book routes.
Running the Application
Add a start script to your package.json:
"scripts": { "start": "nodemon src/index.ts" }
To start the server, run:
npm start
Testing the API
With the server running, you can test the API using a tool like Postman. To add a new book, send a POST request to http://localhost:3000/books with a JSON body:
{ "title": "The Great Gatsby", "author": "F. Scott Fitzgerald", "publishedYear": 1925, "genre": "Novel" }
This should return the newly created book entry if successful.
Explanation
The code in this blog sets up a basic RESTful API for managing a book database using Node.js, Express, TypeScript, and MongoDB. It defines a Book model with properties like title, author, publishedYear, and genre using Mongoose. The API routes are created for CRUD operations, including getting all books and adding a new book. The main application file (src/index.ts) brings everything together by setting up the Express server, connecting to MongoDB, and implementing the book routes. The article also provides instructions for running the application and testing the API using tools like Postman. This setup serves as a foundation for building more complex book management systems and can be extended with additional features and functionalities.
Conclusion
What we did here is not very complex, but I hope it serves as a good starting point for someone interested. This barely covers the basics and there’s a lot more to learn, so once you’re confident you have a grasp over everything mentioned in this blog, it’s time to move forward!
カテゴリー: