目 录CONTENT

文章目录

Memos API 提速

16Reverie
2025-04-10 / 0 评论 / 0 点赞 / 37 阅读 / 0 字

最近折腾要用到 Memos 的数据,通常,外部都是通过 Memos 提供的 API 获取数据,但是速度确实有点慢了,就像打开 Memos 的主页一样,加载时间有点长。

我的提速方法就是通过在中间加一个 API ,提前获取 Memos 的数据,存储在缓存中,这样通过访问”中间 API“来拿数据,速度就大大提升了。同时用到了 Memos 自带的 Webhook 功能,实现缓存自动更新。

这样做还有另一个好处,在这个中介处能够提前处理其他的数据,例如 Memos 的标签数据,也方便了数据获取。

代码

Memos API 数据是以分页形式获取的,需要指定一页数据的条数pageSize,翻页通过指定pageToken 参数

API 形式:http://memos.domain.com/api/v1/memos/api/v1/memos?pageSize=10&pageToken=

所以缓存以 pageSize 和 pageToken 为 key 进行存储。

const response = await axios.get(url, { timeout: 5000 });
const data = response.data;

if (!cachedPageSizes.includes(pageSize)) {
    ......
}
    ......
cache[pageSize][currentPageToken] = { ...data };
    ......

同时设置缓存容量,最多缓存三个 pageSize 的数据

if (!cachedPageSizes.includes(pageSize)) {
    // 若超过最大缓存数量,删除最旧的 pageSize 对应的缓存
    if (cachedPageSizes.length >= MAX_CACHED_PAGE_SIZES) {
        const oldestPageSize = cachedPageSizes.shift();
        console.log("超过最大缓存数量,删除旧缓存的 cache[pageSize: %s]", oldestPageSize);
        delete cache[oldestPageSize];
    }
    ......
}

每次获取,根据获取到的数据更新 pageToken,直到 pageToken 为空,代表已经获取完。

while (nextPageToken) {
      .....
    const nextResponse = await axios.get(nextUrl, { timeout: 5000 });
    const nextData = nextResponse.data;
      ......
    cache[pageSize][nextPageToken] = { ...nextData };   // 存入缓存
            
    nextPageToken = nextData.nextPageToken; // 更新 nextPageToken
}

收到 get 请求时,从缓存中查询,存在则直接返回,不存在则获取

app.get('/data', async (req, res) => {
    const { pageSize = 10, pageToken = 'init' } = req.query;
    
    const pageSizeCache = cache[pageSize];
    const cachedData = pageSizeCache && (pageSizeCache[pageToken] || (pageToken == "" && pageSizeCache["init"]));
    if (cachedData) {
        res.json(cachedData);
    } else {
        const targetUrl = `${baseUrl}?pageSize=${pageSize}${pageToken === "init" ? '' : `&pageToken=${pageToken}`}`;
        const newData = await updateCache(targetUrl);

        console.log(`pageSize:${pageSize} 缓存存储成功`);

        if (newData) {
            res.json(newData);
        } else {
            res.status(503).send('缓存数据不可用,请稍后再试');
        }
    }
});

就算不存在,也只是获取第一页数据时会比较慢,当需要获取第二页数据时,数据已经在缓存中了。

完整代码:https://github.com/ihavenoideaa/memos_cache_api

Webhook 缓存自动更新

代码中设置了定时器每隔一段时间自动更新缓存。

同时监听 POST 请求,当收到 POST 请求,且参数符合时也会更新缓存

app.post('/updates', async (req, res) => {
    const { update } = req.query;
    if (update === 'true') {
        refreshCache();
        console.log("/updates 刷新缓存")
        res.json({message: '更新成功'});
    } else {
        res.json({ message: '未提供有效的更新参数' });
    }
});

在 Memos 中设置 Webhook,关联到http://your_api_domain/update?updates=true

这样每次成功编辑 Memos(新增/修改/删除),Memos 就会向指定的 URL 发送一个包含有关该事件的 JSON 数据的 HTTP POST 请求,从而触发缓存更新。

链接

Memos 文档:https://thebestxt.cc/documents/memos/docs/advanced-settings/webhook.html

代码仓库:https://github.com/ihavenoideaa/memos_cache_api

0

评论区