dapr / dapr/js-sdk

feat(jobs): Supports Jobs API Alpha1

Open
#805 0 comments 0 reactions 1 assignee Claimed by @atrauzzi View on GitHub
area/jobs enhancement sdk-parity
Dominant language
JavaScript
Stars
217
Forks
104
PR merge metrics
No merged PRs in 30d

Description

## Summary
The Dapr runtime provides a Jobs API that lets applications schedule, inspect, and manage recurring or one-time jobs. When a job fires, the Dapr sidecar invokes a callback on the application so it can run the relevant logic.

The JS SDK does not yet expose any user-facing API for Jobs. While the generated ConnectRPC bindings and proto definitions are already present, there is no high-level `DaprClient` or `DaprServer` surface for applications to use.

## What the user should be able to do
### Schedule a job (client-side)
```ts
import { DaprClient } from "@dapr/dapr";

const client = new DaprClient();

await client.jobs.schedule({
job: {
name: "send-report",
schedule: "0 0 9 * * *", // cron — every day at 9 AM
data: { reportType: "weekly", recipients: ["team@acme.co"] },
failurePolicy: { type: "constant", interval: "30s", maxRetries: 3 },
},
overwrite: true,
});
```
### Manage jobs (client-side)
```ts
const job = await client.jobs.get("send-report");
const allJobs = await client.jobs.list();

await client.jobs.delete("send-report");
await client.jobs.deleteByPrefix("send-");
```

### Handle triggered jobs (server-side)
```ts
import { DaprServer } from "@dapr/dapr";

const server = new DaprServer();

server.jobs.on("send-report", async (event) => {
const { reportType, recipients } = event.data;
await generateAndSendReport(reportType, recipients);
});

await server.start();
```

## Proposed types
```ts
export interface DaprJob {
name: string;
schedule?: string; // cron expression or @every/@daily/etc.
repeats?: number; // run N times; omit = indefinite
dueTime?: string; // RFC3339 or Go-style duration
ttl?: string; // time-to-live / expiration
data?: unknown; // arbitrary payload (serialized via google.protobuf.Any)
failurePolicy?: JobFailurePolicy;
}

export type JobFailurePolicy =
| { type: "drop" }
| { type: "constant"; interval: string; maxRetries?: number };

export interface ScheduleJobOptions {
job: DaprJob;
overwrite?: boolean;
}
```

## Proposed client interface
```ts
export interface IClientJobs {
schedule(options: ScheduleJobOptions): Promise;
get(name: string): Promise;
delete(name: string): Promise;
deleteByPrefix(namePrefix?: string): Promise;
list(): Promise;
}
```

## Implementation Plan
1. Types — Add `src/types/jobs/` with `DaprJob`, `JobFailurePolicy`, `ScheduleJobOptions`, and `JobEvent`.
2. Client interface — Add `IClientJobs` under `src/interfaces/Client/`.
3. gRPC implementation — Wire up ConnectRPC calls (`scheduleJobAlpha1`, `getJobAlpha1`, `deleteJobAlpha1`, `deleteJobsByPrefixAlpha1`, `listJobsAlpha1`) with `google.protobuf.Any` serialization for the data field.
4. HTTP implementation — Map to the alpha1 REST endpoints (`POST/GET/DELETE /v1.0-alpha1/jobs/`).
5. DaprClient integration — Expose `client.jobs` property.
6. Server handler registration — Add `server.jobs.on(name, handler)` API.
7. `onJobEventAlpha1` routing — Replace the no-op in `GRPCServerImpl.ts` with dispatch to registered handlers by job name.
8. Exports — Re-export new types/interfaces from `src/index.ts`.
9. Tests — Unit tests for type↔proto mapping; E2E with a scheduler component if feasible.

## Acceptance Criteria
- [ ] `DaprClient` exposes client.jobs with `schedule()`, `get()`, `delete()`, `deleteByPrefix()`, `list()`
- [ ] Both gRPC and HTTP transports are implemented
- [ ] `DaprServer` supports registering job event handlers by name
- [ ] `onJobEventAlpha1` in GRPCServerImpl routes events to registered handlers
- [ ] All job fields are represented in user-facing types (including `failurePolicy`, `overwrite`, `data`)
- [ ] `google.protobuf.Any` payload is serialized/deserialized transparently
- [ ] Unit tests cover type mapping between user types and proto schemas
- [ ] New types and interfaces are exported from the package index

## References
| Resources | Location |
| --- | --- |
| Proto messages | `src/proto/dapr/proto/runtime/v1/jobs.proto` |
| Proto RPCs | `src/proto/dapr/proto/runtime/v1/dapr.proto` |
| App callback | `src/proto/dapr/proto/runtime/v1/appcallback.proto` |
| Failure policy | `src/proto/dapr/proto/common/v1/common.proto` |
| ConnectRPC bindings | `src/proto/dapr/proto/runtime/v1/dapr_connect.{js,d.ts}` |
| Existing server stub | `src/implementation/Server/GRPCServer/GRPCServerImpl.ts` |
| Dapr docs | [https://docs.dapr.io/reference/api/jobs_api/](https://docs.dapr.io/reference/api/jobs_api/) |

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.