Deno logoDeno

Origin RPC

The "Origin RPC" interface provides a mechanism for Deno Deploy Subhosting to interact with your system. This allows it to retrieve information required to handle your requests (such as source code), and to send diagnostic events to your system (such as logs or usage information).

You must implement this interface in order to use Deno Deploy Subhosting. The interface should be implemented as an HTTP API. The only mandatory endpoint that you must implement to be able to execute code is GET /boot. All other RPC endpoints are optional, but if left unimplemented will cause certain features to be unavailable.

Your Origin RPC service must be publicly accessible on the internet and must use HTTPS. The TLS certificate must be issued by a certificate authority trusted by the Mozilla PKI list.

Deno Deploy Subhosting supports both HTTP/1.1 and HTTP/2 origin RPC implementations. For best performance, you should use HTTP/2.

Request authentication

All requests from Deno Deploy subhosting to your origin service include a JWT token in the Authorization header:

GET /boot?deployment_id=helloworld HTTP/1.1
...
Authorization: Bearer <token>
...

This JWT is signed using the shared secret provided to you during onboarding, using the HS256 (HMAC SHA-256) algorithm.

You must verify the authenticity of incoming requests before processing them. To do this verify the JWT signature using the shared secret. Additionally, you must check that the JWT is not expired.

The JWT claims payload has the following form:

interface OriginRPCClaims {
  /** Unix timestamp of the time the token was issued. */
  iat: number;
  /** Unix timestamp of the time until this token is valid. */
  exp: number;
  /** The deployment that caused this RPC call to be performed.
   * NOTE: This field is not present for event reporting related RPC calls. */
  deployment_id?: string;
}

Caching & immutability

Deno Deploy Subhosting caches all GET RPC requests, regardless of cache-control headers. This is done to improve performance of the system, and to take load off your origin server.

Concretely this has the following notable effects for you:

  • All GET requests should be fully idempotent. This means that for the same inputs, you should always return the same result.
  • You can not modify the isolate configuration for a given deployment ID after it has been executed for the first time. If you need to run an isolate with a different configuration, use a different deployment ID.
  • You can not have the same layer ID return multiple different layers over time.

Compression

Deno Deploy Subhosting supports content compression for response bodies using both the Brotli and gzip algorithms. When compressing bodies returned from an RPC endpoint with one of these algorithms a content-encoding header must be specified.

Additionally Deno Deploy Subhosting can compress sent request bodies using gzip compression. This is currently only enabled for the /events RPC endpoint. This means that you must conditionally decompress the request body of an RPC call if the content-encoding header indicates that the body is compressed.

Endpoints

GET /boot

This boot RPC endpoint is used to retrieve the isolate boot configuration for a given deployment id. This is used when booting a new isolate.

Request

The call is issued with a deployment_id query parameter, containing the deployment ID that is requested.

The call contains no body.

Response

The origin must return a 200 OK response, or a redirect leading to such a response. Redirects are discouraged, because they can result in increased boot latency.

The response must contain an x-deno-config header containing a JSON object describing the isolate configuration. View the Isolate Config chapter for more details on the structure of this isolate configuration object.

If the isolate configuration uses an inline layer, the response body should be equal to the contents of this inline layer. If the inline layer is a JS bundle the content type should be set to content-type: application/javascript. For ESZIP layers, the content type should be set to content-type: application/vnd.denoland.eszip. If no inline layer is specified, the body should be empty.

Example

GET /boot?deployment_id=helloworld HTTP/1.1
Host: deno-origin.example.com
Authorization: Bearer <token>
HTTP/1.1 200 OK
Date: Wed, 11 Aug 2022 09:00:00 GMT
Content-Type: application/javascript
x-deno-config: {"entrypoint":"file:///src/main.js","layers":[{"kind":"bundle","id":"812a2873-7aa8-46a0-9b97-bbace05de91d","specifier":"file:///src/main.js"}],"inline_layer":"812a2873-7aa8-46a0-9b97-bbace05de91d"}

addEventListener("fetch", (e) => e.respondWith(new Response("Hello World!")));

GET /layer

The layer RPC endpoint is called to retrieve the contents of a boot layer that is not passed in as an inline layer in the boot configuration. Layer IDs are globally unique.

Request

The call is issued with a layer_id query parameter, containing the layer ID that is requested. Layer IDs must be globally unique.

The call contains no body.

Response

The origin must return a 200 OK response, or a redirect leading to such a response. Redirects are discouraged, because they can result in increased boot latency.

The response body should be set to the contents of the requested layer. If the layer is a JS bundle, the content type should be set to content-type: application/javascript. For ESZIP layers, the content type should be set to content-type: application/vnd.denoland.eszip.

Example

GET /layer?layer_id=812a2873-7aa8-46a0-9b97-bbace05de91d HTTP/1.1
Host: deno-origin.example.com
Authorization: Bearer <token>
HTTP/1.1 200 OK
Date: Wed, 11 Aug 2022 09:00:00 GMT
Content-Type: application/javascript

addEventListener("fetch", (e) => e.respondWith(new Response("Hello World!")));

POST /events

The events RPC endpoint is used to report various system events to you. The full list of events can be found in the Events chapter.

Request

This endpoint is not deployment specific. Data for multiple deployments can be sent in the same RPC call.

The request body of this RPC call is a newline delimited JSON stream of event objects. This format is sometimes called ndjson.

The structure of an event object is described in the Events chapter.

Response

The origin must return a 200 OK response on success. If a 4xx or 5xx class error is returned, or the connection to the origin fails, event delivery is retried once.

Example

Be aware that the request body may be compressed with gzip compression, in which case content-encoding: gzip will be set in the request headers.

POST /events HTTP/1.1
Host: deno-origin.example.com
Authorization: Bearer <token>
Content-Type: application/json

{"deployment_id":"my-deployment","timestamp":"2022-01-01T00:00:00Z","event_type":"log","event":{"msg":"Hello, world!","level":"info"},"isolate_id":"d3ec60fc-e58e-4298-bb96-71f0bc4a9abe"}
{"deployment_id":"my-deployment","timestamp":"2022-01-01T00:00:01Z","event_type":"log","event":{"msg":"Hello, world!","level":"info"},"isolate_id":"d3ec60fc-e58e-4298-bb96-71f0bc4a9abe"}
{"deployment_id":"my-deployment","timestamp":"2022-01-01T00:00:02Z","event_type":"log","event":{"msg":"Hello, world!","level":"info"},"isolate_id":"d3ec60fc-e58e-4298-bb96-71f0bc4a9abe"}
HTTP/1.1 200 OK
Date: Wed, 11 Aug 2022 09:00:00 GMT
Content-Length: 0

GET /fs/manifest

The file system manifest RPC endpoint is used to retrieve the file system manifest for a given deployment.

Request

The call is issued with a deployment_id query parameter, containing the deployment ID for the isolate that is performing a file system operation.

The call contains no body.

Response

The origin must return a 200 OK response, or a redirect leading to such a response. Redirects are discouraged, because they can result in increased latency.

The response body must contain the JSON serialized file system manifest for the requested deployment.

Example

GET /fs/manifest?deployment_id=helloworld HTTP/1.1
Host: deno-origin.example.com
Authorization: Bearer <token>
HTTP/1.1 200 OK
Date: Wed, 11 Aug 2022 09:00:00 GMT
Content-Type: application/json
Content-Length: ...

{"entries":{"":{"kind":"directory"},"/hello.txt":{"kind":"file","size":5,"hash":"2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824"},"/goodbye.txt":{"kind":"file","size":7,"hash":"82e35a63ceba37e9646434c5dd412ea577147f1e4a41ccde1614253187e3dbf9"}}}

GET /fs/blob

The blob RPC endpoint is used to retrieve the contents of a file system blob.

Request

The call is issued with a deployment_id query parameter containing the deployment ID for the isolate that is performing a file system operation, and a hash query parameter containing the hash of the blob that is requested.

An offset query parameter may be included to request a specific range of the blob. If omitted, the entire blob is requested. The offset is measured in bytes from the start of the blob. An offset of 1 should return the blob starting at the second byte.

The call contains no body.

Response

The origin must return a 200 OK response, or a redirect leading to such a response. Redirects are discouraged, because they can result in increased latency.

The content type of the response body must be set to application/octet-stream.

Example

Full blob

GET /fs/blob?deployment_id=helloworld&hash=2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824 HTTP/1.1
Host: deno-origin.example.com
Authorization: Bearer <token>
HTTP/1.1 200 OK
Date: Wed, 11 Aug 2022 09:00:00 GMT
Content-Type: application/octet-stream
Content-Length: 13
Transfer-Encoding: chunked

6
Hello,
7
 World!
0

Partial blob

GET /fs/blob?deployment_id=helloworld&hash=2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824&offset=7 HTTP/1.1
Host: deno-origin.example.com
Authorization: Bearer <token>
HTTP/1.1 200 OK
Date: Wed, 11 Aug 2022 09:00:00 GMT
Content-Type: application/octet-stream
Content-Length: 6
Transfer-Encoding: chunked

6
World!
0