使用 strapi 快速构建 API 和 CMS 管理系统
前言
作为一个合格的前端工程师,怎么能够不懂得自己写后端接口呢?会自己写后端API接口,能够在工作当中有效的提供工作竞争力,还能够帮我有效的提高工作效率。有的同学说,我会 Node.js,确实使用 Node.js 帮助前端工程师晋升为全栈 。
但是在一些普通的增删改查都要自己亲自动手去写,那效率着实是大打折扣的。strapi 就是一款能够快速上手,让一个懂一点 Node.js 的前端开发就能够快速的开发出增删改查的接口来,最近刚好有使用到 strapi 作为网站的后端,刚好在这里记录一下自己学习的过程。
快速上手
strapi 官网: https://strapi.io/ (opens new window)
在开始使用之前我们需要确保自己的 Node.js 版本为
v14
、
v16
或者
v18
,npm 的版本为
v6
,如果需要使用到 SQLite 作为数据库的话,还需要在自己的电脑上安装 Python。
安装 strapi
直接使用官方提供的快速开始的模版,这里我使用 TypeScript 的模版,命令如下:
npx create-strapi-app@latest my-api --quickstart --ts
如果一切顺利,创建好工程之后,将会自动进行依赖的安装,并且安装之后会自动运行,我们可以在终端当中看到如下的提示:
自动打开浏览器之后,可以看到下面的页面,提示我们创建一个超级管理员的身份,输入自己的账号和密码,目前界面显示的是英文,稍后我们进行配置接口让其显示中文界面。
注册输入一个账号、邮箱、密码,点击
Let's start
,进入到即可进入到 CMS 系统当中。
修改 strapi 管理界面为中文
接下来我们进行项目代码的配置,将界面设置为中文,使用自己熟悉的开发工具打开工程,这里我使用 VSCode,项目的结构如下图所示:
这里我使用了文件折叠的插件,才让下面那些配置文件显示成层级结构的,不用管,将
src/admin/app.example.tsx
修改为
src/admin/app.tsx
,并将代码修改成如下:
export default {
config: {
locales: [
'zh-Hans',
'zh',
bootstrap(app) {
console.log(app);
};
保存代码,项目会自动重启,打开管理系统,找到
Settings -> internationalization -> Add new locale
,添加一个中文的语言设置,如下图所示:
点击
save
保存语言配置项,然后重启一下项目,再次登录到管理系统当中。点击左下角的头像,选择
Profile
,跳转到个人信息设置页面,可以看到有设置中文的选项了,我们选中
中文(简体)
,然后点击
save
,即可看到界面切换到中文。
如果你阅读到这里,恭喜你马上就能够发现原来开发一个接口这么容易。
快速开发一套 CRUD 接口
创建模型
这里我就拿项目当中最常用的用户管理来说,首先我们需要一个用户表,点击
模型构建器
,可以看到已经有一个 User 的集合类型,这个是 strapi 自己提供的,我们当前登录的用户的数据就存储在这个模型当中,但是这个不是我们所需要的,新增一个集合类型
UserProfile
,注意
高级设置
当中的
Draft & publish
根据实际需要进行勾选,勾选之后新增加的数据需要手动进行发布才能生效,这里我就取消勾选了。
创建完模型之后,点击
添加一个字段
,选择
文本
,设置名称为
username
,选择
较短的文本
,高级设置当中的类型选择
必须
和
唯一
的,其他的我们暂时用不到,实际中可以根据需要选择。
然后依次创建
password
、
sex
、
nickName
、
phone
、
email
等等,根据实际需要自己添加。然后点击
保存
,项目将自动重启。
名称 |
类型 |
---|---|
username |
文本、必填、唯一 |
password |
密码框 |
sex |
枚举 |
nickName |
文本 |
phone |
文本 |
|
电子邮箱 |
重启完毕,就可以在内容管理当中看到
集合类型
当中看到
UserProfile
,然后我们创建几条记录。
对外暴露接口
接下来我们对外暴露接口,让我们自己编写的前端用户使用,找到
设置 -> 角色列表 -> Public
,进行编辑,将
find
和
findOne
接口勾选,然后点击
保存
,进行勾选的时候,旁边的
绑定路由到 api::user-profile.user-profile
下面的
/api/user-profiles
就是 strapi 为我们自动生成的接口。
我们复制到浏览器上使用一下,拼接上域名和端口
http://localhost:1337/api/user-profiles
可以看到接口已经返回了 json 数据,我们添加到 CMS 当中的内容已经成功返回。
strapi 也提供了各种各样的筛选条件,比如使用
filters[username]=xxx
可以筛选出 username 为 xxx 的数据,更多筛选条件可以查看官方文档,文档地址:
https://docs.strapi.io/dev-docs/api/rest (opens new window)
http://localhost:1337/api/user-profiles?filters[username]=xiao
strapi 也提供非常丰富的插件,比如要使用 GraphQL,直接安装 GraphQL 插件即可。
自定义 API 接口
有了前面的编写经验,相信能够阅读到这里的你,应该已经迫不接待想要自己使用 strapi 编写自己的接口了吧。
strapi 是在 koa 的基础上开发来的,我们可以通过设置,实现自己的业务逻辑,下面就用一个用户注册的接口来介绍一下使用 strapi 编写自定义业务逻辑的接口。
实战用户注册接口
通过 strapi 我们已经得到了
user-profile
相关的增删改查 API 接口,但是在实际业务开发当中,不可能只有这种简单的增删改查接口,这里我带领大家实现一个用户注册的接口。
1、制定前后端接口交换的数据格式
直接采用最简单的方式,我们规定前端请求我们的接口的参数如下:
{
"username": "test-admin",
"password": "12345",
"nickName": "dimples",
"phone": "15555555555",
"email": "2890841438@qq.com"
}
包含了2个字段,
username
和
password
,规定后端接口的地址为
/api/user-reg
,请求后端接口之后返回我们需要的登录态,这里的登录态我们是用
jwt
。
2、编码
已经明白了我们需要开发的接口之后,下面直接进入编码阶段,在
user-profile
的
routes
下面新增一个
register.ts
文件,方便将用户的请求映射到我们自己的
controller
上。
register.ts
当中的代码如下所示,直接导出一个包含
routes
数组默认对象,数组当中指定了注册的请求路径和相应的
handler
,这里的
handler
指示的是工程目录下的
controller
,当中的
user-profile.ts
当中的
index
方法:
// register.ts
export default {
routes: [
method: 'POST',
path: '/user-reg',
handler: 'user-profile.register',
}
在开发实际业务接口之前,因为使用到
md5
对用户的密码进行加密,我们需要先安装几个需要用到的包,命令如下:
npm install md5
npm install @types/md5 -D
加下来编写我们的业务代码,
user-profile.ts
当中的代码如下所示, 在
strapi
为我们创建好的
controller
之上增加我们自己的 :
/**
* user-profile controller
import { factories } from "@strapi/strapi";
import md5 from "md5";
export default factories.createCoreController(
"api::user-profile.user-profile",
({ strapi }) => ({
async register(ctx) {
const UserProfileModel = strapi.db.query(
"api::user-profile.user-profile"
const { username, password, nickName, phone, email } = ctx.request.body;
const user = await UserProfileModel.findOne({
where: {
$or: [
username,
phone,
email,
// 如果用户已经存在了就提示已经注册
if (user) {
return {
msg: "用户已经注册过了",
code: 4000,
data: null,
// 注册
const result = await UserProfileModel.create({
select: ["username", "nickName", "phone", "email"],
data: {
username,
password: md5(password),
nickName,
phone,
email,
return {
msg: "注册成功",