Files
asepharyana-hub/docs/add-dapr-service.md
T

163 lines
3.7 KiB
Markdown
Raw Normal View History

# Menambahkan Dapr ke Service Baru
Panduan integrasi Dapr runtime sidecar untuk service di `asepharyana-hub`.
## Prasyarat
- NATS server berjalan (`infra/compose/nats.yml`)
- Dapr placement service berjalan (`infra/compose/dapr.yml`)
## 1. Compose File
Setiap service butuh sidecar container Dapr. Contoh:
```yaml
services:
app:
container_name: app
image: ghcr.io/asepharyana/asepharyana-hub/app:latest
restart: always
depends_on:
dapr-placement:
condition: service_healthy
nats:
condition: service_healthy
networks:
app-shared-net:
aliases:
- app
env_file:
- ../../.env
app-dapr:
container_name: app-dapr
image: daprio/daprd:latest
restart: always
depends_on:
dapr-placement:
condition: service_healthy
nats:
condition: service_healthy
networks:
- app-shared-net
depends_on:
dapr-placement:
condition: service_healthy
nats:
condition: service_healthy
otel-collector:
condition: service_started
networks:
- app-shared-net
command:
- './daprd'
- '--app-id=app'
- '--app-port=3000'
- '--dapr-http-port=3500'
- '--dapr-grpc-port=50001'
- '--placement-host-address=dapr-placement:50005'
- '--config=/dapr/config.yaml'
- '--resources-path=/dapr/components'
volumes:
- ../../infra/dapr:/dapr:ro
networks:
app-shared-net:
name: app-shared-net
external: true
```
## 2. Mengakses Dapr dari Service
### Via HTTP API (semua bahasa)
Sidecar listen di `localhost:3500`:
```bash
# Publish event
curl -X POST http://localhost:3500/v1.0/publish/pubsub/hub.event.type \
-H "Content-Type: application/json" \
-d '{"key": "value"}'
# Service invocation
curl http://localhost:3500/v1.0/invoke/app/method/endpoint
# State store
curl -X POST http://localhost:3500/v1.0/state/statestore \
-H "Content-Type: application/json" \
-d '[{"key": "mykey", "value": "myvalue"}]'
```
### Via Dapr SDK (Rust)
Tambah ke `Cargo.toml`:
```toml
dapr-sdk = { version = "0.15", features = ["pubsub", "http"] }
tokio-stream = "0.1"
```
Contoh publish event:
```rust
use dapr_sdk::client::{Client, Event};
use dapr_sdk::DaprClient;
let client = DaprClient::new("127.0.0.1", 3500).await?;
client.publish_event("pubsub", "hub.image.cached", serde_json::json!({
"original_url": url,
"cdn_url": cdn_url,
})).await?;
```
Contoh subscribe event:
```rust
let mut stream = client.subscribe_events("pubsub", "hub.image.cached").await?;
while let Some(event) = stream.next().await {
let data: MyEvent = serde_json::from_slice(&event.data)?;
// handle event
}
```
## 3. Event Topics Convention
Gunakan prefix `hub.` untuk semua event:
| Topic | Payload | Description |
|-------|---------|-------------|
| `hub.image.cached` | `{original_url, cdn_url, source}` | Image selesai di-cache |
| `hub.image.repaired` | `{old_url, new_url}` | CNAME image diperbaiki |
| `hub.scrape.anime.done` | `{source, slug, duration}` | Scrape anime selesai |
| `hub.system.alert` | `{service, level, message}` | Error/alert dari service |
## 4. Local Development
Untuk development tanpa Docker:
```bash
# 1. Install Dapr CLI
# 2. Init Dapr local
dapr init
# 3. Run service dengan sidecar
dapr run --app-id app --app-port 3000 --dapr-http-port 3500 \
--resources-path ./infra/dapr/components \
-- cargo run
```
## 5. Verifikasi
```bash
# Sidecar health
curl http://localhost:3500/v1.0/healthz
# Publish test event
curl -X POST http://localhost:3500/v1.0/publish/pubsub/hub.test \
-H "Content-Type: application/json" \
-d '{"test": true}'
# NATS stream stats
curl http://localhost:8222/jszetstream
```