单体架构前后端接口调用方案

在现代Web开发中,前后端分离的架构已成为一种趋势。但是在某些项目中,尤其是小型或中型应用,单体架构仍然是一种常见的选择。本文将探讨在单体架构中,前后端如何调用接口,并提供相应的代码示例。

项目背景

假设我们正在开发一个简单的待办事项(TODO)管理应用,该应用允许用户创建、查看、更新和删除待办事项。前端使用Vue.js框架,后端使用Node.js和Express框架。

系统架构

在此项目中,前后端将部署在同一个服务器上,使用相同的URL访问。这样的设计使得后端API和前端页面能够轻松进行交互。

流程图

使用Mermaid语法生成流程图如下:

flowchart TD
    A[用户请求] -->|HTTP请求| B[前端]
    B -->|调用API| C[后端]
    C -->|返回数据| B
    B -->|渲染页面| D[用户界面]

数据库设计

本项目将采用MongoDB作为数据库。下面是待办事项的ER图:

erDiagram
    TODO {
        ObjectId id PK "待办事项的唯一标识符"
        String title "待办事项的标题"
        Boolean completed "待办事项的完成状态"
        Date createdAt "待办事项的创建时间"
        Date updatedAt "待办事项的更新时间"
    }

接口设计

在后端,我们需要设计以下API接口:

  1. 获取所有待办事项

    • URL: /api/todos
    • 方法: GET
  2. 创建新的待办事项

    • URL: /api/todos
    • 方法: POST
  3. 更新待办事项

    • URL: /api/todos/:id
    • 方法: PUT
  4. 删除待办事项

    • URL: /api/todos/:id
    • 方法: DELETE

示例代码

以下是后端Node.js和Express的代码示例:

const express = require('express');
const mongoose = require('mongoose');

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

mongoose.connect('mongodb://localhost:27017/todo_app', { useNewUrlParser: true, useUnifiedTopology: true });

const todoSchema = new mongoose.Schema({
    title: String,
    completed: { type: Boolean, default: false },
    createdAt: { type: Date, default: Date.now },
    updatedAt: { type: Date, default: Date.now }
});

const Todo = mongoose.model('Todo', todoSchema);

// 获取所有待办事项
app.get('/api/todos', async (req, res) => {
    const todos = await Todo.find();
    res.json(todos);
});

// 创建新的待办事项
app.post('/api/todos', async (req, res) => {
    const newTodo = new Todo({
        title: req.body.title
    });
    await newTodo.save();
    res.status(201).json(newTodo);
});

// 更新待办事项
app.put('/api/todos/:id', async (req, res) => {
    const updatedTodo = await Todo.findByIdAndUpdate(req.params.id, req.body, { new: true });
    res.json(updatedTodo);
});

// 删除待办事项
app.delete('/api/todos/:id', async (req, res) => {
    await Todo.findByIdAndDelete(req.params.id);
    res.status(204).send();
});

app.listen(3000, () => console.log('Server running on http://localhost:3000'));

相应的Vue.js前端代码示例:

<template>
  <div>
    待办事项
    <input v-model="newTodo" @keyup.enter="addTodo" placeholder="添加新的待办事项" />
    <ul>
      <li v-for="todo in todos" :key="todo._id">
        {{ todo.title }}
        <button @click="removeTodo(todo._id)">删除</button>
      </li>
    </ul>
  </div>
</template>

<script>
export default {
  data() {
    return {
      todos: [],
      newTodo: ''
    };
  },
  methods: {
    async fetchTodos() {
      const response = await fetch('/api/todos');
      this.todos = await response.json();
    },
    async addTodo() {
      const response = await fetch('/api/todos', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ title: this.newTodo })
      });
      const newTodo = await response.json();
      this.todos.push(newTodo);
      this.newTodo = '';
    },
    async removeTodo(id) {
      await fetch(`/api/todos/${id}`, { method: 'DELETE' });
      this.todos = this.todos.filter(todo => todo._id !== id);
    }
  },
  created() {
    this.fetchTodos();
  }
};
</script>

结论

在单体架构中,前后端通过RESTful API进行交互,能够高效地管理待办事项,提供流畅的用户体验。上述方案展示了如何使用Node.js和Vue.js开发一个简单的待办事项管理应用。通过以上步骤,开发团队可简化开发流程,提升项目开发的效率。

未来的扩展可以考虑引入微服务架构或前后端分离的设计,以便于处理更复杂的需求和提高系统的可维护性。但在当前的项目需求下,单体架构无疑是一种合适的选择。