Skip to content

Repository files navigation

hopper

Hopper

Enqueue a URL and a JSON body. Hopper stores the job in MongoDB, puts { "job_id" } on RabbitMQ, and POSTs until the target accepts — or the job is dead and you replay it. At-least-once HTTP only (a crash after 2xx and before Mongo success can duplicate). MVP type: http_post.

Quick start

docker compose -f deploy/compose.yaml up -d
go build -o hopper ./cmd/hopper
./hopper api     # ingress + outbox relay
./hopper worker  # claim, POST, relay

Config example: deploy/hopper.example.yaml.

API

Method Path
POST /v1/jobs
GET /v1/jobs/{id}
GET /v1/jobs?status=dead
POST /v1/jobs/{id}/replay
GET /healthz
POST /v1/jobs
Authorization: Bearer <token>
Idempotency-Key: order-42
Content-Type: application/json

{
  "type": "http_post",
  "target": "https://hooks.example.com/notify",
  "payload": { "order_id": 42 },
  "max_attempts": 8
}

Outbound: Idempotency-Key: hopper/{job_id}/{cycle}/{attempt}.

Stack

Role Package
Language Go 1.27
Router chi
DI fx
Config config
Log zap
Documents mongo-driver
Broker amqp091-go
Egress net/http

Flow

flowchart LR
  C[Client] -->|Bearer| A[hopper api]
  A -->|job doc| M[(MongoDB)]
  A -->|job_id| R[[RabbitMQ]]
  R --> W[hopper worker]
  W --> M
  W -->|HTTP POST| T[Target]
  W -->|delay / DLQ| R
Loading

License

MIT

About

Outgoing work delivery system.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Contributors

Languages