eggjs 实现服务端请求教程文档-1

简介

该教程适合入门级小伙伴,使用 node eggjs 框架实现服务端开发,以及处理开发过程中遇到的问题。

教程中的每个章节会附上 demo(git 分支),小伙伴可以自行拉取代码查看。

教程和 demo 会使用基于 umi 二次封装的 alita 框架进行页面渲染,重点讲解 eggjs 的 node 服务端框架。

实现通过 get 请求获取的 user 列表,并通过 post 请求获取详细的 user 信息。

作为入门级的我们,首先不用太关注过多的 api,技术类的东西建议先掌握了用法,用多了就能慢慢理解其中的奥义。所有光看不实操的小伙伴都是耍流氓。

现在我们先来创建 egg 框架。

一、eggjs 框架搭建和讲解

eggjs 官网-快速入门

通过上面的链接,我们能够快速搭建 eggjs 的脚手架。

# 新建文件夹
mkdir eggDemo && cd eggDemo
# 搭建脚手架命令
npm init egg --type=simple

# 手动输入项目 pkg 信息
?project name egg
? project description
? project author
? cookie security keys 1620311360934_6251

# 进入项目安装依赖
cd init
yarn

在安装依赖的时间里,可以打开 package.json 文件看下 script 的标签。

"scripts": {
    "start": "egg-scripts start --daemon --title=egg-server-egg",
    "stop": "egg-scripts stop --title=egg-server-egg",
    "dev": "egg-bin dev",
    ...
},
  • yarn run start:启动 egg 服务
  • yarn run stop:停止 egg 服务
  • yarn run dev:启动开发模式,支持热部署

装好依赖后执行 yarn run dev 脚手架已经给我们写好了最简 demo。实现了一个最简单的接口。

在这里插入图片描述

eggjs 奉行『约定优于配置』,可以简单的理解为:以什么命名的文件和文件夹下就做什么事情(描述不准确,但是八九不离十)。

完整的目录结构请看官网讲解,看下脚手架为我们搭建的几个目录:

  • /config/config.default.js: 配置文件
  • /config/plugin.js: 配置插件

  • /app/router.js: 用于配置 URL 路由规则,即每个接口地址
  • /app/controller/**: 用于解析用户的输入,处理后返回相应的结果
  • /app/public/**: 用于放置静态资源

在真实的项目中会存在成百上千个接口,如果全部都挤在 app/router.js 里可能效果不佳。一般会分模块或者分后台中心来实现。

我们要实现的 demo 中有两个页面,分别为 用户列表页用户详情页。我们就按页面来区分,新建两个文件用来存放路由。

module.exports = app => {
  require('./router/list')(app);
  require('./router/detail')(app);
};

在这里插入图片描述

最后我们快速搭建一个 前端 web 框架。

# 在 eggDemo 的文件夹下键入 web 脚手架
yarn create alita eggWeb

cd eggWeb
yarn

初始化框架可以看下 demo 中的 /config/config.ts/src/app.ts 文件。

feat-frame-building 框架搭建分支

二、用户列表接口开发(get 请求)

egg

每个接口都有独一无二的路由(接口名),

所以我们先来实现路由的编写:

/router/list.js

'use strict';

module.exports = app => {
  const { router, controller } = app;
  router.get('/api/getUserList', controller.home.userList);
};
  • router.get 代表 get 请求。
  • controller.home.userListController: 代表 controller 文件夹下存在 home 文件,文件内有 userListController 的方法。

/app/controller/home.js

const Controller = require('egg').Controller;

class HomeController extends Controller {
  async userListController() {
    const { ctx } = this;
    const data = Array.from(new Array(9)).map((_val, i) => ({
      name: `name${i}`,
      id: i,
    }));
    ctx.body = {
      data,
      success: true,
    };
  }
}

module.exports = HomeController;
  • async: 可以理解为约定,代表了异步。

this 内参数说明:

参数说明
this.ctx当前请求的上下文 Context 对象的实例,通过它我们可以拿到框架封装好的处理当前请求的各种便捷属性和方法(能够更好的拿到请求上下文的数据)
this.app当前应用 Application 对象的实例,通过它我们可以拿到框架提供的全局对象和方法
this.service通过它我们可以访问到抽象出的业务层,等价于 this.ctx.service, service 用于服务端的底层封装
this.config应用运行时的配置项

写完服务端的 get 请求,启动服务,打开 http://127.0.0.1:7001/api/getUserList,能够看到请求的数据已经显示在界面上。

在这里插入图片描述

web

开发 web 端代码,请求 /api/getUserList 接口。

/src/pages/index/service.ts: 使用 useRequest 请求参数。

import { request } from 'alita';

export async function getUserList(): Promise<any> {
  return request('/api/getUserList', { method: 'get' });
}

/src/pages/index/index.tsx:

import React, { FC, Fragment } from 'react';
import { useRequest, history } from 'alita';
import { Button } from 'antd-mobile';
import { getUserList } from './service';
import styles from './index.less';

interface HomePageProps {}

const HomePage: FC<HomePageProps> = () => {
  const { data, run } = useRequest(getUserList, {
    manual: true,
  });
  return (
    <div className={styles.center}>
      {data && (
        <Fragment>
          <div>调用 getUserList 请求: 出参:</div>
          {data.map((item: any) => (
            <div
              onClick={() => {
                history.push({
                  pathname: '/userDetail',
                  query: {
                    id: item.id,
                  },
                });
              }}
              key={item?.id}
              style={{
                height: '1rem',
              }}
            >
              {item.name}
            </div>
          ))}
        </Fragment>
      )}
      <Button onClick={() => run()}>get 请求</Button>
    </div>
  );
};
export default HomePage;

跨域问题

启动 web 项目访问:http://localhost:8000/#/ 点击按钮调用接口发现数据并未展示出来,接口状态码 304 Not Modified

在这里插入图片描述

细看接口发现,服务接口和 web 并不同源,应该是存在跨域问题,我们需要增加代理来解决跨域问题:

/config/config.js

import { defineConfig } from 'alita';

const baseUrl = 'http://127.0.0.1:7001';

export default defineConfig({
  appType: 'h5',
  mobileLayout: true,
  proxy: {
    '/api': {
      target: baseUrl,
      changeOrigin: true,
    },
  },
});

在这里插入图片描述

至此,一个完整的 get 请求接口从开发,到 web 端界面渲染就完成了。

feat-user-list 分支

下一篇文章请小伙伴们移步至 eggjs 实现服务端请求教程文档-2

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值