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()
}
}