我希望在我的应用程序中使用耐用对象。我选择它们而不是 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 提供客户支持,这很好......只是想确认一下。
谢谢!
你似乎大部分都是对的。
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。