自写API反向代理Github API
在2024年8月11日,我使用Fronti这个开源的Astro主题构建了你们正在浏览的网站。当时非常匆忙,有两篇博文要写,首页就先保持初始状态了。
8月18日,博文已经没有要写的了,就开始对首页进行大的整改,期间这几条Github统计数据可是花了我好多头发,但当时写的匆忙能跑不就行了,不知不觉明明知道给自己挖了一个坑
问题分析
我为了防止用户撞到Github API速率限制墙而无法加载我的Github统计数据,直接把我Github账号的PAT(Personal access tokens)令牌硬编码进请求头里让用户去请求数据,但这样就出现了几个大问题:
- 每位用户都要去找Github请求数据,访问的人多起来或遭到DDos攻击非常容易导致我的Github账号受到速率限制。
- 原因同上,有些用户无法访问Github,他们也就无法正常加载我的Github统计数据。
- 虽然公开的是毫无权限的令牌,但有心之人可以拿我的令牌去不断请求Github API,使我的Github账号受到速率限制,导致正常用户无法加载我的Github统计数据,我也会跟着遭殃。
如何实现
总的来说,我需要让服务端向Github请求数据,Github把数据返回给服务端,服务端做一个缓存,然后把请求到的数据返回给用户,缓存未失效之前再有人访问时服务端会直接把数据发送给客户端,无需再向Github请求数据。
这,听起来反向代理挺适合的,但我不能完全代理api.github.com,这样用户直接把我的反向代理当作镜像站来请求,这不就完犊子了!
那就给Astro加API端点吧!我这么想着,看了一会文档,开始尝试,构建失败7次,运行失败6次,我放弃了,开始寻找别的方法。
github-readme-stats的启示
在那几条Github统计数据完工前,我首页贴着的是两张github-readme-stats.vercel.app提供的卡片,这是一个开源项目,我便去他们的Github仓库翻了翻代码,找到了灵感。
最终的解决方案是使用Vercel的Serverless服务,实现一套带缓存的,只能访问特定的Github API地址的API端点。
实现过程
知道如何实现还不行,现在我对相关代码的编写还是一头雾水,还得寻找更多的资料。
首先,我在网络上搜集相关文档,翻到了Serverless functions with Vercel这篇文章,了解了基本语法,顺便写了个Hello, world!
。万事都从Hello, world!
开始
部署完后,使用curl
访问刚部署的API地址,得到了以下结果
接下来,就开始编写API吧!
获取项目信息的API
先把要用到的常量保存在src/consts.ts
文件中
再创建api/project.ts
文件,编写获取项目信息的API:
推送到Vercel上部署,使用curl
访问刚创建的API,得到结果:
解决跨域问题
好,看起来没问题,那就修改下我的网站的代码试试看:
果然没有那么简单,遇到了跨域问题,但难不倒我,经过一番搜索,寻找到了解决方法:
先向src/consts.ts
文件中添加下面这一行:
再修改api/project.ts
文件:
然后获取项目信息的API就完成了!
获取除了Commit数量外的其它信息的API
还是一样,先向src/consts.ts
文件中添加代码:
再创建api/stats/index.ts
文件:
获取Commit数量的API
创建api/stats/total-commit-count.ts
文件:
缓存功能
前面提到过,我不光要加快api.github.com的访问速度,还要做一个缓存,在一番寻找后,我选择了lru-cache
这个库来实现缓存:
安装这个库
修改相关代码 & 最终预览
src/consts.ts
api/project.ts
api/stats/index.ts
api/stats/total-commit-count.ts
全文完。