| [ Web Proxy ] |
| Viewing: https://developers.cloudflare.com/durable-objects/api/base/ | [Back] [Original] |
The DurableObject base class is an abstract class which all Durable Objects inherit from. This base class provides a set of optional methods, frequently referred to as handler methods, which can respond to events, for example a webSocketMessage when using the WebSocket Hibernation API. To provide a concrete example, here is a Durable Object MyDurableObject which extends DurableObject and implements the fetch handler to return "Hello, World!" to the calling Worker.
export class MyDurableObject extends DurableObject {
constructor(ctx, env) {
super(ctx, env);
}
async fetch(request) {
return new Response("Hello, World!");
}
}export class MyDurableObject extends DurableObject {
constructor(ctx: DurableObjectState, env: Env) {
super(ctx, env);
}
async fetch(request: Request) {
return new Response("Hello, World!");
}
}from workers import DurableObject, Response
class MyDurableObject(DurableObject):
def __init__(self, ctx, env):
super().__init__(ctx, env)
async def fetch(self, request):
return Response("Hello, World!")fetch(request Request)
: Response | Promise<Response>- Takes an HTTP
Request and
returns an HTTP
Response .
This method allows the Durable Object to emulate an HTTP server where a Worker
with a binding to that object is the client. - This method can be async.
fetch() when your application does not follow HTTP request/response flow.request Request - the incoming HTTP request object.Response or Promise<Response>.export class MyDurableObject extends DurableObject {
async fetch(request) {
const url = new URL(request.url);
if (url.pathname === "/hello") {
return new Response("Hello, World!");
}
return new Response("Not found", { status: 404 });
}
}export class MyDurableObject extends DurableObject<Env> {
async fetch(request: Request): Promise<Response> {
const url = new URL(request.url);
if (url.pathname === "/hello") {
return new Response("Hello, World!");
}
return new Response("Not found", { status: 404 });
}
}from workers import DurableObject, Response
from urllib.parse import urlparse
class MyDurableObject(DurableObject):
async def fetch(self, request):
path = urlparse(request.url).path
if path == "/hello":
return Response("Hello, World!")
return Response("Not found", status=404)alarm(alarmInfo? AlarmInvocationInfo)
: void | Promise<void>
alarm() handler has guaranteed at-least-once execution and will be retried upon failure using exponential backoff, starting at two second delays for up to six retries. Retries will be performed if the method fails with an uncaught exception.async.alarmInfo AlarmInvocationInfo (optional) - an object containing retry information:
retryCount number - the number of times this alarm event has been retried.isRetry boolean - true if this alarm event is a retry, false otherwise.export class MyDurableObject extends DurableObject {
async alarm(alarmInfo) {
if (alarmInfo?.isRetry) {
console.log(`Alarm retry attempt ${alarmInfo.retryCount}`);
}
await this.processScheduledTask();
}
}export class MyDurableObject extends DurableObject<Env> {
async alarm(alarmInfo?: AlarmInvocationInfo): Promise<void> {
if (alarmInfo?.isRetry) {
console.log(`Alarm retry attempt ${alarmInfo.retryCount}`);
}
await this.processScheduledTask();
}
}from workers import DurableObject
class MyDurableObject(DurableObject):
async def alarm(self, alarm_info=None):
if alarm_info and alarm_info.isRetry:
print(f"Alarm retry attempt {alarm_info.retryCount}")
await self.process_scheduled_task()webSocketMessage(ws WebSocket, message string | ArrayBuffer)
: void | Promise<void>- Called by the system
when an accepted WebSocket receives a message. - This method is not called for
WebSocket control frames. The system will respond to an incoming WebSocket
protocol ping
automatically without interrupting hibernation.
async.ws WebSocket - the WebSocket that received the message. Use this reference to send responses or access serialized attachments.message string | ArrayBuffer - the message data. Text messages arrive as string, binary messages as ArrayBuffer.export class MyDurableObject extends DurableObject {
async webSocketMessage(ws, message) {
if (typeof message === "string") {
ws.send(`Received: ${message}`);
} else {
ws.send(`Received ${message.byteLength} bytes`);
}
}
}export class MyDurableObject extends DurableObject<Env> {
async webSocketMessage(ws: WebSocket, message: string | ArrayBuffer) {
if (typeof message === "string") {
ws.send(`Received: ${message}`);
} else {
ws.send(`Received ${message.byteLength} bytes`);
}
}
}from workers import DurableObject
class MyDurableObject(DurableObject):
async def webSocketMessage(self, ws, message):
if isinstance(message, str):
ws.send(f"Received: {message}")
else:
ws.send(f"Received {len(message)} bytes")webSocketClose(ws WebSocket, code number, reason string, wasClean boolean)
: void | Promise<void>- Called by the system
when a WebSocket connection is closed.
web_socket_auto_reply_to_close compatibility flag (enabled by default on compatibility dates on or after 2026-04-07), the runtime automatically sends a reciprocal Close frame and transitions readyState to CLOSED before this handler is called. You do not need to call ws.close() but doing so is safe (the call is silently ignored).2026-04-07), you must call ws.close(code, reason) inside this handler to complete the WebSocket close handshake. Failing to reciprocate the close will result in 1006 errors on the client, representing an abnormal closure per the WebSocket specification.async.ws WebSocket - the WebSocket that was closed.code number - the WebSocket close code sent by the peer (e.g., 1000 for normal closure, 1001 for going away).reason string - a string indicating why the connection was closed. May be empty.wasClean boolean - true if the connection closed cleanly with a proper closing handshake, false otherwise.export class MyDurableObject extends DurableObject {
async webSocketClose(ws, code, reason, wasClean) {
// With web_socket_auto_reply_to_close (compat date >= 2026-04-07),
// the runtime has already completed the close handshake.
// On older compat dates, call ws.close(code, reason) here.
ws.close(code, reason);
console.log(`WebSocket closed: code=${code}, reason=${reason}`);
}
}export class MyDurableObject extends DurableObject<Env> {
async webSocketClose(ws: WebSocket, code: number, reason: string, wasClean: boolean) {
// With web_socket_auto_reply_to_close (compat date >= 2026-04-07),
// the runtime has already completed the close handshake.
// On older compat dates, call ws.close(code, reason) here.
ws.close(code, reason);
console.log(`WebSocket closed: code=${code}, reason=${reason}`);
}
}from workers import DurableObject
class MyDurableObject(DurableObject):
async def webSocketClose(self, ws, code, reason, was_clean):
ws.close(code, reason)
print(f"WebSocket closed: code={code}, reason={reason}")webSocketError(ws WebSocket, error unknown)
: void | Promise<void>- Called by the system
when a non-disconnection error occurs on a WebSocket connection. - This method
can be async.ws WebSocket - the WebSocket that encountered an error.error unknown - the error that occurred. May be an Error object or another type depending on the error source.export class MyDurableObject extends DurableObject {
async webSocketError(ws, error) {
const message = error instanceof Error ? error.message : String(error);
console.error(`WebSocket error: ${message}`);
}
}export class MyDurableObject extends DurableObject<Env> {
async webSocketError(ws: WebSocket, error: unknown) {
const message = error instanceof Error ? error.message : String(error);
console.error(`WebSocket error: ${message}`);
}
}from workers import DurableObject
class MyDurableObject(DurableObject):
async def webSocketError(self, ws, error):
print(f"WebSocket error: {error}")ctx is a readonly property of type DurableObjectState providing access to storage, WebSocket management, and other instance-specific functionality.
env contains the environment bindings available to this Durable Object, as defined in your Wrangler configuration.
| Web Proxy Viewer | New URL | Original Page |