A cloud-native workflow service built with Temporal and Spring Boot. Start durable workflows via REST; a background worker executes multi-step flows with activities, timeouts, and automatic retries.
Features • Architecture • Quick Start • API • Project Structure
| Feature | Description |
|---|---|
| Durable workflows | Multi-step workflows with Temporal; survive restarts and retries |
| REST API | Start workflows with POST and get a workflowId immediately (async) |
| Activities | Deterministic workflow orchestration + non-deterministic work in activities (DB, HTTP, etc.) |
| Activity timeouts | StartToCloseTimeout per activity; configurable retry behavior |
| Single JVM | One app: HTTP server + Temporal worker in a dedicated thread |
| External Temporal | Connects to a Temporal server (local dev or cluster) via gRPC |
| Spring Boot | Actuator health & info; config via application.yml |
flowchart LR
subgraph Client
C[curl / Postman]
end
subgraph App["temporal-workflow-engine"]
API[REST Controller]
WC[WorkflowClient]
W[Worker Thread]
WF[MyWorkflowImpl]
A[MyActivitiesImpl]
end
subgraph Temporal["Temporal Server"]
FS[Frontend :7233]
H[History]
end
C -->|"POST /api/workflows/my-workflow/start"| API
API --> WC
WC -->|"Start workflow"| FS
FS --> H
W -->|"Poll tasks"| FS
W --> WF
WF -->|"Invoke"| A
A -->|"step1 / step2"| WF
- REST → starts a workflow and returns
workflowId(202 Accepted). - WorkflowClient → talks to Temporal Frontend (gRPC) to schedule workflow runs.
- Worker → polls the same task queue, runs workflow code + activities in process.
- Workflow → calls activities with timeouts; Temporal records history for replay and retries.
- JDK 21
- Temporal server on
localhost:7233(see below) - Gradle (or use the wrapper:
./gradlew)
Option A — Temporal CLI (simplest)
# Install: https://docs.temporal.io/cli#install
temporal server start-devOption B — Docker Compose
git clone https://github.com/temporalio/docker-compose.git temporal-docker
cd temporal-docker
docker compose up -d
# Wait ~30s for services to be readygit clone https://github.com/NullPoint3rDev/temporal-workflow-engine.git
cd temporal-workflow-engine
./gradlew bootRunThe app starts on port 8081 (configurable in application.yml). The worker connects to localhost:7233 and subscribes to the my-task-queue task queue.
curl -X POST http://localhost:8081/api/workflows/my-workflow/start \
-H "Content-Type: application/json" \
-d '{"userId": "user-123"}'Response (202 Accepted):
{"workflowId":"my-workflow-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"}The workflow runs in the background: step1 → step2 (activities). You can inspect runs in the Temporal Web UI if available (e.g. CLI dev server on port 8233).
| Method | Path | Description |
|---|---|---|
POST |
/api/workflows/my-workflow/start |
Start a workflow. Body: {"userId": "string"}. Returns workflowId. |
Example
curl -X POST http://localhost:8081/api/workflows/my-workflow/start \
-H "Content-Type: application/json" \
-d '{"userId": "alice"}'src/main/java/workflow/
├── WorkflowApplication.java # Spring Boot entry point
├── MyWorkflow.java # Workflow interface (@WorkflowMethod)
├── MyWorkflowImpl.java # Workflow implementation (calls activities)
├── dto/
│ └── MyInput.java # Request DTO (e.g. userId)
├── activities/
│ ├── MyActivities.java # Activity interface
│ └── MyActivitiesImpl.java # Activity implementation (Spring @Component)
├── configuration/
│ └── TemporalConfig.java # WorkflowClient & WorkflowServiceStubs beans
├── controller/
│ ├── WorkflowController.java # REST: start workflow
│ └── StartWorkflowResponse.java # Response DTO (workflowId)
└── runner/
└── TemporalWorkerRunner.java # Starts Temporal worker in a background thread
| Property | Default | Description |
|---|---|---|
server.port |
8081 |
HTTP server port |
temporal.target |
localhost:7233 |
Temporal frontend gRPC address |
temporal.namespace |
default |
Temporal namespace |
temporal.task-queue |
my-task-queue |
Task queue for workflows and worker |
Override via application.yml or environment variables.
This project is licensed under the MIT License — see the LICENSE file for details.