Write it up front
- Complete one using Node
todolist app
的server
End, which includes the basic TS configuration scheme and completes the Models and Controler layers. - Tip: You need to be familiar with Typescript, which is used on both the server and client sides
- It is already installed by default
yarn
ornpm
You can read them in order
- Full stack Todolist-server Node(Server) React(client) MongoDB(database) Typescript
- Todolist – database article (Cloud mongo)
- Todolist – client article (React Typescript)
NodeJS App (Server side)
1. Initialize (Source reference)
- New Folder
mkdir server
cd server
Copy the code
- Initialize the
yarn init
Copy the code
- Build file directory
├ ─ ─ dist ├ ─ ─ node_modules ├ ─ ─ the SRC ├ ─ ─ app. Ts ├ ─ ─ controllers | └ ─ ─ todos | └ ─ ─ but ts ├ ─ ─ models | └ ─ ─ todo. Ts ├ ─ ─ Routes | └ ─ ─ index. Ts └ ─ ─ types └ ─ ─ todo. Ts ├ ─ ─ nodemon. Json ├ ─ ─ package. The json ├ ─ ─ tsconfig. JsonCopy the code
App. ts is the entrance of our project, dist folder is mainly responsible for TS compilation output files, nodemon.json is the configuration item of the database, which will be mentioned later.
2, configuration,
- Let’s configure
ts.config
{
"compilerOptions": {
"target": "es6"."module": "commonjs"."outDir": "dist/js"."rootDir": "src"."strict": true."esModuleInterop": true."forceConsistentCasingInFileNames": true
},
"include": ["src/**/*"]."exclude": ["src/types/*.ts"."node_modules".".vscode"]}Copy the code
OutDir: tells the compiler to output the compiled JS file to the dist/ JS directory
RootDir: indicates the root directory for ts compilation
Include: Tells the compiler exactly where to compile.
Exclude: exclude articles that do not need to be compiled
- The installation
typescript
yarn add typescript -g
Copy the code
- The installation
express
和MongoDB
Dependencies and their @types
yarn add express cors mongoose
yarn add -D @types/node @types/express @types/mongoose @types/cors
Copy the code
- Install the compiler for compiling Typescript
concurrently
和nodemon
yarn add -D concurrently nodemon
Copy the code
- Finally, we add the build and start scripts
"scripts": {
"build": "tsc"."start": "concurrently \"tsc -w\" \"nodemon dist/js/app.js\""
}
Copy the code
Ps: TSC requires global installation of TS
concurrently
The main job is to help us compile Typescript and do hot updates.
3, code (Source reference)
3.1 Creating todolist@types
- types/todo.ts
import { Document } from "mongoose"
export interface ITodo extends Document {
name: string
description: string
status: boolean
}
Copy the code
The new @types created is Document from Mongoose, which is the basic text format.
3.2 Creating todolist Model
- models/todo.ts
import { ITodo } from ". /.. /types/todo"
import { model, Schema } from "mongoose"
const todoSchema: Schema = new Schema(
{
name: {
type: String.required: true,},description: {
type: String.required: true,},status: {
type: Boolean.required: true,}}, {timestamps: true})export default model<ITodo>("Todo", todoSchema)
Copy the code
Create a type library that defines the data types for Dotolist.
3.3 API controllers
Now let’s add a few Todolist-related methods to the controller.
getTodos
- controllers/todos/index.ts
import { Response, Request } from "express"
import { ITodo } from ". /.. /.. /types/todo"
import Todo from ".. /.. /models/todo"
const getTodos = async (req: Request, res: Response): Promise<void> = > {try {
const todos: ITodo[] = await Todo.find()
res.status(200).json({ todos })
} catch (error) {
throw error
}
}
Copy the code
We need to introduce Express to explicitly define our Response and Request types. To parse this, we use JSON to define our data. This function to initialize our todolist data that the page load will call.
addTodo
- controllers/todos/index.ts
const addTodo = async (req: Request, res: Response): Promise<void> = > {try {
const body = req.body as Pick<ITodo, "name" | "description" | "status">
const todo: ITodo = new Todo({
name: body.name,
description: body.description,
status: body.status,
})
const newTodo: ITodo = await todo.save()
const allTodos: ITodo[] = await Todo.find()
res
.status(201)
.json({ message: "Todo added".todo: newTodo, todos: allTodos })
} catch (error) {
throw error
}
}
Copy the code
The addTodo function is used to add a new list and update the total lists.
updateTodo
- controllers/todos/index.ts
const updateTodo = async (req: Request, res: Response): Promise<void> = > {try {
const {
params: { id },
body,
} = req
const updateTodo: ITodo | null = await Todo.findByIdAndUpdate(
{ _id: id },
body
)
const allTodos: ITodo[] = await Todo.find()
res.status(200).json({
message: "Todo updated".todo: updateTodo,
todos: allTodos,
})
} catch (error) {
throw error
}
}
Copy the code
Update a list to complete. We need to pass the relevant ids to determine the specific list.
deleteTodo
- controllers/todos/index.ts
const deleteTodo = async (req: Request, res: Response): Promise<void> = > {try {
const deletedTodo: ITodo | null = await Todo.findByIdAndRemove(
req.params.id
);
const allTodos: ITodo[] = await Todo.find();
res.status(200).json({
message: 'Todo deleted'.todo: deletedTodo,
todos: allTodos,
});
} catch (error) {
throwerror; }};Copy the code
Delete a message
4, API routes
- routes/index.ts
import { Router } from "express"
import { getTodos, addTodo, updateTodo, deleteTodo } from ".. /controllers/todos"
const router: Router = Router()
router.get("/todos", getTodos)
router.post("/add-todo", addTodo)
router.put("/edit-todo/:id", updateTodo)
router.delete("/delete-todo/:id", deleteTodo)
export default router
Copy the code
Now the route for the basic method has been constructed
5. MongoDB database configuration
- nodemon.json
{
"env": {
"MONGO_USER": "your-username"."MONGO_PASSWORD": "your-password"."MONGO_DB": "your-db-name"}}Copy the code
How to configure it? Check out my mongoDB Clound cloud database configuration article.
- app.ts
import express, { Express } from 'express';
import mongoose from 'mongoose';
import cors from 'cors';
import todoRoutes from './routes';
import bodyParser from 'body-parser';
const app: Express = express();
// The default port is 4000, which will be used by the client later. If you want to customize the port, keep the same
const PORT: string | number = 4000;
// const PORT: string | number = process.env.PORT || 4000;
console.log(process.env.PORT);
app.use(cors()); // cross-domain processing
app.use(bodyParser.json()); // Post request processing
app.use(bodyParser.urlencoded({ extended: false }));
app.use(todoRoutes); // We have API routing processing
const uri: string = `mongodb+srv://${process.env.MONGO_USER}:${process.env.MONGO_PASSWORD}@ cluster0.4qpw4.mongodb.net/${process.env.MONGO_DB}? retryWrites=true&w=majority`;
const options = { useNewUrlParser: true.useUnifiedTopology: true };
mongoose.set('useFindAndModify'.false);
mongoose
.connect(uri, options)
.then(() = >
app.listen(PORT, () = >
console.log(`Server running on http://localhost:${PORT}`)
)
)
.catch((error) = > {
throw error;
});
Copy the code
6, summary
- Ok, now that our server and Clound Database are complete, the next part will cover building the client side.
- If you need gitignore, see the source code below
7, the source code
- Source reference
- You can view them in the order of branch
Technology Stack Reference
- If you are not familiar with the above technology stack, please refer to the following documentation
- The react website
- The typescript’s official website
- The node’s official website
- Directing a website
Translation from
- freeCodeCamp