Skip to content

前面的章节,我们实现了一个简易的后端接口框架,并且用这个接口框架写了登录和注册 2 个接口,与前端进行了功能对接,将用户注册数据保存到数据库,成功实现了用户注册和登录功能。

那么接下来,我们实现博客文章的添加、删除、修改、查询功能。

与注册登录功能一样,在写接口,对接功能之前,我们需要先设计好博客文章的数据库字段。如果你已经忘记了数据库的相关操作,请查看前文,或者在问答群艾特笔者。

picture 0

如图,是 article(文章表) 及其字段,很简单,只有三个主要字段,分别是 标题作者内容

js
// /apis/articleInsert.js 文件
import { mysqlPool } from '../mysql.js';
export default async (req) => {
    try {
        // 参数去掉前后空格
        const title = req.body.title.trim();
        const content = req.body.content.trim();
        const author = req.body.author;
        // ------------------------------------------------------
        // 验证标题参数
        if (title.length < 1 || title.length > 100) {
            return {
                code: 1,
                msg: '文章标题长度不能小于1,不能大于100'
            };
        }

        // ------------------------------------------------------
        // 验证内容参数
        if (content.length < 1 || content.length > 60000) {
            return {
                code: 1,
                msg: '文章内容长度不能小于1,不能大于6000'
            };
        }

        // ------------------------------------------------------
        // 验证作者参数,必须为非0数字开头的整数
        if (/[1-9]\d*/.test(author) === false) {
            return {
                code: 1,
                msg: '文章作者必须传作者的数字ID'
            };
        }
        // ------------------------------------------------------
        // 从连接池中获取一个数据库连接
        const db = await mysqlPool.getConnection();
        // 查询数据库是否有对应的用户数据
        const [result] = await db.query({
            sql: 'INSERT INTO `article` (`title`,`content`,`author`,`created_at`) VALUES (:title,:content,:author,:created_at)',
            values: {
                title: title,
                content: content,
                author: Number(author),
                created_at: Date.now()
            }
        });
        // 释放数据库连接
        db.release();
        // 返回成功信息
        return {
            code: 0,
            msg: '添加文章成功',
            data: {
                insertId: result.insertId
            }
        };
    } catch (err) {
        console.log('🚀 ~ err:', err);
        return {
            code: 1,
            msg: '未知错误'
        };
    }
};

可以看到,接口开发,一如继往地简单,只要我们按照步骤,一个个来即可。

  1. 获取参数,做一些简单的处理,比如去掉前后空格。
  2. 验证参数,判断参数是否符合要求,比如不能为空,不能小于或大于某个长度等。
  3. 接口逻辑,这里就是我们业务代码了,添加数据,写业务逻辑,都在这里。
  4. 返回数据,返回码,提示信息,返回的数据等。

请大家一定要记住,后端接口开发,一定要做 验证参数 的步骤。

要确保,我们从前端,浏览器端拿到的数据,是合理的,合法的,符合我们要求的。

这样就能在我们进行业务代码之前,排除掉由于客户端传参错误而导致接口报错,服务崩溃。

切记切记,客户端可以不做验证,后端接口一定要做验证,养成这个良好的习惯,减少对接的麻烦,为公司,为项目负责!

html
<!doctype html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>文章管理</title>
        <link rel="stylesheet" type="text/css" href="./article.css" />
    </head>
    <body>
        <!-- 用于防止浏览器自动填充密码 -->
        <input type="password" clearable hidden autocomplete="new-password" style="display: none" />
        <div class="form">
            <div class="group">
                <div class="label">标题</div>
                <div class="value">
                    <input class="title" type="input" placeholder="请输入标题" />
                </div>
            </div>
            <div class="group">
                <div class="label">内容</div>
                <div class="value">
                    <input class="content" type="input" placeholder="请输入内容" />
                </div>
            </div>
            <div class="button insert">提交</div>
        </div>
        <script>
            // 点击添加文章按钮
            document.querySelector('.insert').addEventListener('click', () => {
                const title = document.querySelector('.title').value;
                const content = document.querySelector('.content').value;
                const result = fetch('/api/articleInsert', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json;charset=utf-8'
                    },
                    body: JSON.stringify({
                        title: title,
                        content: content
                    })
                });
            });
        </script>
    </body>
</html>

接着,我们照猫画虎,像画用户注册页面一样,来画博客文章的添加页面,文件名是 article.html

picture 1

文章管理页面效果如上图。

页面很简单,输入 标题,输入 内容,提交。

但是,注意到,作者 怎么办呢?

如果增加一个输入框,填写作者,可行吗?不行。

既然都已经写好了登录注册功能了,那么肯定是 谁登录并提交,谁就是作者

js
// 点击登录按钮
document.querySelector('.login').addEventListener('click', async () => {
    const username = document.querySelector('.username').value;
    const password = document.querySelector('.password').value;
    const result = await fetch('/api/userLogin', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json;charset=utf-8'
        },
        body: JSON.stringify({
            username: username,
            password: password
        })
    });
    const { code, data, msg } = await result.json();
    if (code === 0) {
        localStorage.setItem('user', JSON.stringify(data));
        console.log(msg);
    } else {
        console.log(msg);
    }
});

所以,这里我们需要把登录功能,小小地改造一下,把登录后的用户信息保存到本地。

js
// 点击添加文章按钮
document.querySelector('.insert').addEventListener('click', () => {
    const title = document.querySelector('.title').value;
    const content = document.querySelector('.content').value;
    // 获取登录时保存到本地的用户数据,并解析成对象结构
    const user = JSON.parse(localStorage.getItem('user')); 
    const result = fetch('/api/articleInsert', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json;charset=utf-8'
        },
        body: JSON.stringify({
            title: title,
            content: content,
            author: user.id
        })
    });
});

然后在发布文章的时候,获取登录的用户 ID,并自动获取,作为提交的作者。

picture 2

然后,我们点击提交按钮,如下图,接口返回添加文章成功。

picture 3

再来看看数据库,数据已入库,博客添加文章功能,成功实现!

相信到了这一步,大家会对 Web 前后端全栈开发有更深刻的认识,其实接口开发很简单。

实际的公司项目,企业项目,商业项目中的复杂,是逻辑复杂,他们的底层本质,就是这么简单。

这就好像一栋房子,各种外观,各种布局,但是所有的房子都有地基,都有骨架。

笔者分享给大家的,就是了解地基和骨架的基本实现原理,这样你们在后续建造高楼大厦的过程中,就会发现,其实也不难。

何以解忧,唯有代码。不忘初心,方得始终。