正确使用 Cloudflare Durable 对象

问题描述 投票:0回答:1

我希望在我的应用程序中使用耐用对象。我选择它们而不是 KV,因为我需要进行一系列写入,并且我发现 KV 不足以满足我的需求。 DO 文档中的模式(获取语法和等待类属性)对我来说很陌生。有人愿意对我的课程设计提供建议/反馈吗?

一切似乎都正常......但我想就我的模式获得一些第二意见。

// siteData.ts
import { Env } from 'hono';
import { SiteInfo } from './types';
import { DurableObject } from 'cloudflare:workers';

export class SiteData extends DurableObject {
    constructor(state: DurableObjectState, env: Env) {
        super(state, env);
    }

    async initialize(siteId: string, credits = 15, isPro = false, access_token: string) {
        if (!siteId) {
            throw new Error('siteId is required');
        }
        if (!access_token) {
            throw new Error('access_token is required');
        }
        if (isPro) {
            credits = 100;
        }
        const createdAt = new Date().toISOString();

        // This feels wrong for some reason :)
        await this.ctx.storage.put('siteId', siteId);
        await this.ctx.storage.put('access_token', access_token);
        await this.ctx.storage.put('credits', credits);
        await this.ctx.storage.put('isPro', isPro);
        await this.ctx.storage.put('createdAt', createdAt);

        const siteInfo: SiteInfo = {
            siteId,
            access_token,
            credits,
            isPro,
            createdAt,
        };

        return siteInfo;
    }

    async setSiteId(siteId: string) {
        await this.ctx.storage.put('siteId', siteId);
    }

    async getSiteId() {
        let siteId: string | undefined = (await this.ctx.storage.get('siteId')) || undefined;
        return siteId;
    }

    async getCredits() {
        let credits: number = (await this.ctx.storage.get('credits')) || 0;
        return credits;
    }

// hono API index.ts
// imports and middleware removed

app.get('/register', async (c) => {
    const { siteId, access_token } = c.req.query();
    if (!siteId || !access_token) {
        c.status(400);
        return c.json({ message: 'No siteId or access token provided.' });
    }

    const siteInfoDO = c.env.SITE_DATA_DO.idFromName(siteId);
    const stub = c.env.SITE_DATA_DO.get(siteInfoDO);

    const siteInfo = await stub.initialize(siteId, 15, false, access_token);

    return c.json({ message: 'Success!', siteInfo });
});

有趣的是,TS 告诉我

stub.initialize()
返回的 siteInfo 对象是
never
类型。我想知道我是否误解了文档?我应该在持久对象中定义
fetch
并调用它吗?

我的另一个担忧是使用持久对象长期维护我的应用程序状态。有了Workers KV,我们就有了一个基本的UI来在Workers仪表板中执行基本的CRUD操作,并且我们可以通过wrangler与KV进行交互。 Durable Objects 没有任何此类功能,因此我必须通过自己的 API 提供客户支持,这很好......只是想确认一下。

谢谢!

cloudflare-workers
1个回答
0
投票

你似乎大部分都是对的。

TypeScript 错误可能是因为您尚未完全指定

SITE_DATA_DO
绑定的类型。这不是您粘贴的代码的一部分,但我假设您已将其类型定义为
DurableObjectNamespace
。要进行 RPC 的类型检查,您需要将其设为
DurableObjectNamespace<SiteData>
,即指定您的服务器端类(或其实现的接口)作为类型参数。 更多信息请点击这里。

关于这个:

// This feels wrong for some reason :)

我建议,您可以将整个

SiteInfo
对象写为单个值,而不是将站点信息写为 5 个不同的键/值。值可以是任何结构化可克隆类型,因此您可以一次存储整个对象,无需将其分解。

这确实意味着在

setSiteId()
中,您需要读取/修改/写入,但这可能没问题,特别是考虑到系统会自动进行内存缓存。

使用 Workers KV,我们有一个基本的 UI 来在 Workers 仪表板中执行基本的 CRUD 操作,并且我们可以通过 wrangler 与 KV 进行交互。 Durable Objects 没有任何此类功能,因此我必须通过自己的 API 提供客户支持,这很好......只是想确认一下。

是的,与 KV 相比,耐用对象更多的是作为低级构建块,并且“包含电池”较少。也就是说,我们 (Cloudflare) 很可能会在某个时候构建一个存储浏览器 UI。

© www.soinside.com 2019 - 2024. All rights reserved.