Skip to content

Express-API Base on Node.JS

  • 最近很喜欢的一个后端开发框架,基于node.js的环境进行后端开发。
  • 因为我写的服务基本就是给到客户端去测试一些小功能,类似于分页、响应数据等等功能。
  • 最多用的是套一层壳给到客户端去响应第三方的API,所以node.js的这个开发环境,对于我来说,是非常友好的。

使用这个的目的

  • 在开发Android这种前端页面,需要与后端交互的时候。我是经常觉得自己的Mockk代码不够使用的,因为你很多页面是实时变化的。

比如说,我现在做一个会员场景,用户的会员权益可能在这一个瞬间发生变化,怎么样去做鉴权?以一个const值,每一种页面都去运行一遍然后验证一下吗?这样太浪费时间了。

我还不如操纵API直接发生变化,找到我在终端设定的重新请求时机去向API重新获取数据来得更加快。

Backend For Frontend

不需要涉及数据库那一块的内容,Node.JS本身作为一个轻量级别的框架,它的部署性非常轻量,如果使用它来进行多接口的数据拼装,比直接在Mobile、Web等前端去做数据拼装,容易太多了。

每一个前端(iOS、Android、HarmonyOS、Web)都去做一次的数据拼装,这是一个有问题的设计方案,我在实际的团队开发工程中,遇到过两次这个问题。

第一次的时候,是我在做TheBump项目的Android开发的时候,后端的人说,这个事情无法使用一个接口去返回所需要的Restful-Response,因为涉及到了多个数据库之下的数据存放问题(这个和微服务等等问题有关了)。

于是我们当时三端(Web、iOS、Android)都要进行一次数据拼装。

typescript
import express, { Request, Response } from "express";

const app = express();
const PORT = process.env.PORT || 3000;

app.get("/", (req: Request, res: Response) => {
  res.send("Hello, Express with TypeScript!");
});

app.get("/api/fetchDataA", async (req: Request, res: Response) => {
    await setTimeout(() => { 
        res.json({
            "data": "dataA"
        })
    }, 2000)
});

app.get("/api/fetchDataB", async (req: Request, res: Response) => {
    await setTimeout(() => {  
        res.json({
            "data": "dataB"
        })
     }, 5000)

});

app.listen(PORT, () => {
  console.log(`Server is running at http://localhost:${PORT}`);
});

在Android上面的代码拼装方式:

kotlin
interface XXXModuleAPIService {
  /**
   * 服务器端存在2秒耗时
   **/
  @GET("/xxx/xxx/fetchDataA")
  suspend fun fetchDataA(): String
  
  /**
   * 服务器端存在5秒耗时
   **/
  @GET("/xxx/xxx/fetchDataB")
  suspend fun fetchDataB(): String
}

class XXXModuleRepository(
	private val _xxxModuleApiService: XXXModuleAPIService = XXXModuleAPIService()
) {
  suspend fun fetchData(): String = withContext(Dispatchers.IO) {
    val dataA = async {
      _xxxModuleApiService.fetchDataA()
    }
    
    val dataB = async {
      _xxxModuleApiService.fetchDataB()
    }
    
    return@withContext (dataA.await() + dataB.await())
  }
}

使用ExpressAPI 新增聚合接口

typescript
// ...... 续接上文的Express-TS-API 信息

export interface Data {
    data: string
}

app.get('/api/fetchData', async (req: Request, res: Response) => {
    const start = Date.now();
    const [dataA, dataB] = await Promise.all([
        fetch("http://localhost:3000/api/fetchDataA"),
        fetch("http://localhost:3000/api/fetchDataB"),
    ])

    const [dataABean, dataBBean]: [Data, Data] = await Promise.all([
        dataA.json(),
        dataB.json(),
    ]);

    res.status(200).json(
        {
            "data": dataABean.data + dataBBean.data,
            "time": Date.now() - start
        }
    )
});

对应Android的代码:

kotlin
interface XXXModuleAPIService {
  /**
   * 服务器端存在5秒耗时
   **/
  @GET("/xxx/xxx/fetchData")
  suspend fun fetchDataB(): String
}

class XXXModuleRepository(
	private val _xxxModuleApiService: XXXModuleAPIService = XXXModuleAPIService()
) {
  suspend fun fetchData(): String = withContext(Dispatchers.IO) {
    return@withContext _xxxModuleApiService.fetchData()
  }
}
DIPENG-XU

DIPENG-XU

Creator

随便写写的,喜欢就好。 使用VitePress构建