Write it up front

  • Complete one using Nodetodolist appserverEnd, 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 defaultyarnornpm

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 configurets.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 installationtypescript
yarn add typescript -g
Copy the code
  • The installationexpressMongoDBDependencies 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 Typescriptconcurrentlynodemon
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

  • concurrentlyThe 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