Skip to content

Latest commit

 

History

History
146 lines (110 loc) · 4.85 KB

publish-to-a-queue-over-http.md

File metadata and controls

146 lines (110 loc) · 4.85 KB
title summary pcx_content_type weight layout meta
Publish to a Queue via HTTP
Publish to a Queue directly via HTTP and Workers.
configuration
30
example
title
Queues - Publish Directly via HTTP

The following example shows you how to publsh messages to a queue from any HTTP client, using a shared secret to securely authenticate the client.

This allows you to write to a Queue from any service or programming language that support HTTP, including Go, Rust, Python or even a Bash script.

Prerequisites

Configure your wrangler.toml file as follows:

---
filename: wrangler.toml
---
name = "my-worker"

[[queues.producers]]
  queue = "my-queue"
  binding = "YOUR_QUEUE"

1. Create a shared secret

Before you deploy the Worker, you need to create a secret that you can use as a shared secret. A shared secret is a secret that both the client uses to authenticate and the server (your Worker) matches against for authentication.

{{

}}

Do not commit secrets to source control. You should use wrangler secret to store API keys and authentication tokens securely.

{{

}}

To generate a cryptographically secure secret, you can use the openssl command-line tool and wrangler secret to create a hex-encoded string that can be used as the shared secret:

$ openssl rand -hex 32
# This will output a 65 character long hex string

Copy this string and paste it into the prompt for wrangler secret:

$ npx wrangler secret put QUEUE_AUTH_SECRET

# Outputs:
✨ Success! Uploaded secret QUEUE_AUTH_SECRET

This secret will also need to be used by the client application writing to the queue: ensure you store it securely.

2. Create the Worker

The following Worker script:

  1. Authenticates the client using a shared secret.
  2. Validates that the payload uses JSON.
  3. Publishes the payload to the queue.
---
filename: src/index.ts
---
interface Env {
	YOUR_QUEUE: Queue;
	QUEUE_AUTH_SECRET: string;
}

export default {
	async fetch(req, env): Promise<Response> {
		// Authenticate that the client has the correct auth key
		if (env.QUEUE_AUTH_SECRET == "") {
			return Response.json({ err: "application not configured" }, { status: 500 });
		}

		// Return a HTTP 403 (Forbidden) if the auth key is invalid/incorrect/misconfigured
		let authToken = req.headers.get("Authorization") || "";
		let encoder = new TextEncoder();
		// Securely compare our secret with the auth token provided by the client
		try {
			if (!crypto.subtle.timingSafeEqual(encoder.encode(env.QUEUE_AUTH_SECRET), encoder.encode(authToken))) {
				return Response.json({ err: "invalid auth token provided" }, { status: 403 });
			}
		} catch (e) {
			return Response.json({ err: "invalid auth token provided" }, { status: 403 });
		}

		// Optional: Validate the payload is JSON
		// In a production application, we may more robustly validate the payload
		// against a schema using a library like 'zod'
		let messages;
		try {
			messages = await req.json();
		} catch (e) {
			// Return a HTTP 400 (Bad Request) if the payload isn't JSON
			return Response.json({ err: "payload not valid JSON" }, { status: 500 });
		}

		// Publish to the Queue
		try {
			await env.YOUR_QUEUE.send(messages);
		} catch (e: any) {
			console.log(`failed to send to the queue: ${e}`);
			// Return a HTTP 500 (Internal Error) if our publish operation fails
			return Response.json({ error: e.message }, { status: 500 });
		}

		// Return a HTTP 200 if the send succeeded!
		return Response.json({ success: true });
	},
} satisfies ExportedHandler<Env>;

To deploy this Worker:

$ npx wrangler deploy

3. Send a test message

To make sure you successfully authenticate and write a message to your queue, use curl on the command line:

# Make sure to replace the placeholder with your shared secret
$ curl -H "Authorization: pasteyourkeyhere" "https://YOUR_WORKER.YOUR_ACCOUNT.workers.dev" --data '{"messages": [{"msg":"hello world"}]}'
# Outputs:
{"success":true}

This will issue a HTTP POST request, and if successful, return a HTTP 200 with a success: true response body.

  • If you receive a HTTP 403, this is because the Authorization header is invalid, or you did not configure a secret.
  • If you receive a HTTP 500, this is either because you did not correctly create a shared secret to your Worker, or you attempted to send an invalid message to your queue.

You can use wrangler tail to debug the output of console.log.