Attributes
Very Popular
Repository
Current version released
3 years ago
Versions
- 1.65.4Latest
- 1.65.3
- 1.65.2
- 1.65.1
- 1.65.0
- 1.64.2
- 1.64.1
- 1.64.0
- 1.63.19
- 1.63.18
- 1.63.17
- 1.63.15
- 1.63.14
- 1.63.13
- 1.63.12
- 1.63.11
- 1.63.10
- 1.63.9
- 1.63.8
- 1.63.6
- 1.63.5
- 1.63.4
- 1.63.3
- 1.63.2
- 1.63.1
- 1.63.0
- 1.62.3
- 1.62.2
- 1.62.0
- 1.61.5
- 1.61.4
- 1.61.3
- 0.36.7
- 1.61.2
- 1.61.1
- 1.61.0
- 1.60.27
- 1.60.26
- 1.60.25
- 1.60.24
- 1.60.23
- 1.60.22
- 1.60.21
- 1.60.20
- 1.60.19
- 1.60.18
- 1.60.17
- 1.60.16
- 1.60.15
- 1.60.14
- 1.60.13
- 1.60.12
- 1.60.11
- 1.60.10
- 1.60.9
- 1.60.8
- 1.60.7
- 1.60.6
- 1.60.5
- 1.60.4
- 1.60.3
- 1.60.2
- 1.60.1
- 1.60.0
- 1.59.10
- 1.59.9
- 1.59.8
- 1.59.7
- 1.59.6
- 1.59.5
- 1.59.4
- 1.59.3
- 1.59.2
- 1.59.1
- 1.59.0
- 1.58.0
- 1.57.32
- 1.57.31
- 1.57.30
- 1.57.29
- 1.57.28
- 1.57.27
- 1.57.26
- 1.57.25
- 1.57.24
- 1.57.23
- 1.57.22
- 1.57.21
- 1.57.20
- 1.57.19
- 1.57.18
- 1.57.17
- 1.57.16
- 1.57.15
- 1.57.14
- 1.57.13
- 1.57.12
- 1.57.11
- 1.57.10
- 1.57.9
- 1.57.8
- 1.57.7
- 1.57.6
- 1.57.5
- 1.57.4
- 1.57.3
- 1.57.2
- 1.57.1
- 1.57.0
- 1.56.2
- 1.56.1
- 1.56.0
- 1.55.1
- 1.55.0
- 1.54.2
- 1.54.0
- 1.53.10
- 1.53.9
- 1.53.8
- 1.53.7
- 1.53.6
- 1.53.5
- 1.53.4
- 1.53.3
- 1.53.2
- 1.53.1
- 1.53.0
- 1.52.20
- 1.52.19
- 1.52.18
- 1.52.17
- 1.52.16
- 1.52.15
- 1.52.14
- 1.52.13
- 1.52.12
- 1.52.11
- 1.52.10
- 1.52.9
- 1.52.8
- 1.52.7
- 1.52.6
- 1.52.5
- 1.52.4
- 1.52.3
- 1.52.2
- 1.52.1
- 1.52.0
- 1.51.5
- 1.51.4
- 1.51.3
- 1.51.2
- 1.51.1
- 1.51.0
- 1.50.5
- 1.50.4
- 1.50.3
- 1.50.2
- 1.50.1
- 1.50.0
- 1.49.0
- 1.48.7
- 1.48.6
- 1.48.5
- 1.48.4
- 1.48.3
- 1.48.2
- 1.48.1
- 1.48.0
- 1.47.6
- 1.47.5
- 1.47.4
- 1.47.3
- 1.47.2
- 1.47.1
- 1.47.0
- 1.46.7
- 1.46.6
- 1.46.5
- 1.46.4
- 1.46.3
- 1.46.2
- 1.46.1
- 1.46.0
- 1.45.11
- 1.45.10
- 1.45.9
- 1.45.8
- 1.45.7
- 1.45.6
- 1.45.5
- 1.45.4
- 1.45.3
- 1.45.2
- 1.45.1
- 1.45.0
- 1.44.8
- 1.44.7
- 1.44.6
- 1.44.5
- 1.44.4
- 1.44.3
- 1.44.2
- 1.44.1
- 1.44.0
- 1.43.0
- 1.42.0
- 1.41.11
- 1.41.10
- 1.41.9
- 1.41.8
- 1.41.7
- 1.41.6
- 1.41.5
- 1.41.4
- 1.41.3
- 1.41.2
- 1.41.1
- 1.41.0
- 1.40.2
- 1.40.1
- 1.40.0
- 1.39.8
- 1.39.7
- 1.39.6
- 1.39.5
- 1.39.4
- 1.39.3
- 1.39.2
- 1.39.1
- 1.39.0
- 1.38.2
- 1.38.1
- 1.38.0
- 1.37.6
- 1.37.5
- 1.37.4
- 1.37.3
- 1.37.2
- 1.37.1
- 1.37.0
- 1.36.20
- 1.36.19
- 1.36.18
- 1.36.17
- 1.36.16
- 1.36.15
- 1.36.14
- 1.36.13
- 1.36.12
- 1.36.11
- 1.36.10
- 1.36.9
- 1.36.8
- 1.36.7
- 1.36.6
- 1.36.5
- 1.36.4
- 1.36.3
- 1.36.2
- 1.36.1
- 1.36.0
- 1.35.12
- 1.35.11
- 1.35.10
- 1.35.9
- 1.35.8
- 1.35.7
- 1.35.6
- 1.35.5
- 1.35.4
- 1.35.3
- 1.35.2
- 1.35.1
- 1.35.0
- 1.34.6
- 1.34.5
- 1.34.4
- 1.34.3
- 1.34.2
- 1.34.1
- 1.33.7
- 1.33.6
- 1.33.5
- 1.33.4
- 1.33.3
- 1.33.2
- 1.33.1
- 1.33.0
- 1.32.2
- 1.32.1
- 1.32.0
- 1.31.13
- 1.31.12
- 1.31.11
- 1.31.10
- 1.31.9
- 1.31.4
- 1.31.6
- 1.31.8
- 1.31.7
- 1.31.5
- 1.31.3
- 1.31.2
- 1.31.1
- 1.31.0
- 1.30.12
- 1.30.11
- 1.30.10
- 1.30.9
- 1.30.8
- 1.30.7
- 1.30.6
- 1.30.5
- 1.30.4
- 1.30.3
- 1.30.2
- 1.30.1
- 1.30.0
- 1.29.10
- 1.29.9
- 1.29.8
- 1.29.7
- 1.29.6
- 1.29.5
- 1.29.4
- 1.29.3
- 1.29.2
- 1.29.1
- 1.29.0
- 1.28.1
- 1.28.0
- 1.28.0-beta.6
- 1.28.0-beta.5
- 1.28.0-beta.4
- 1.28.0-beta.3
- 1.28.0-beta.2
- 1.28.0-beta.1
- 1.27.10
- 1.27.9
- 1.27.8
- 1.27.7
- 1.27.6
- 1.27.5
- 1.27.4
- 1.27.3
- 1.27.2
- 1.27.1
- 1.27.0
- 1.26.5
- 1.26.4
- 1.26.3
- 1.26.2
- 1.26.1
- 1.26.0
- 1.25.7
- 1.25.6
- 1.25.5
- 1.25.4
- 1.25.3
- 1.25.2
- 1.25.1
- 1.25.0
- 1.24.7
- 1.24.6
- 1.24.5
- 1.24.4
- 1.24.3
- 1.24.2
- 1.24.1
- 1.24.0
- 1.23.9
- 1.23.8
- 1.23.7
- 1.23.6
- 1.23.5
- 1.23.4
- 1.23.3
- 1.23.2
- 1.23.1
- 1.23.0
- 0.3.39-als
- 1.22.14
- 1.22.13
- 1.22.12
- 1.22.11
- 1.22.10
- 1.22.9
- 1.22.8
- 1.22.7
- 1.22.6
- 1.22.5
- 1.22.4
- 1.22.3
- 1.22.2
- 1.22.1
- 1.22.0
- 1.21.9
- 1.21.8
- 1.21.7
- 1.21.6
- 1.21.5
- 1.21.4
- 1.21.3
- 1.21.2
- 1.21.1
- 1.21.0
- 1.20.1
- 1.20.0
- 1.19.9
- 1.19.8
- 1.19.7
- 1.19.6
- 1.19.5
- 1.19.4
- 1.19.3
- 1.19.2
- 1.19.1
- 1.19.0
- 1.18.1
- 1.18.0
- 1.17.6
- 1.17.5
- 1.17.4
- 1.17.3
- 1.17.2
- 1.17.1
- 1.17.0
- 1.16.3
- 1.16.2
- 1.16.1
- 1.16.0
- 1.15.0
- 1.14.7
- 1.14.6
- 1.14.5
- 1.14.4
- 1.14.3
- 1.14.2
- 1.14.1
- 0.10.3
- 0.10.2
- 0.10.1
- 0.10.0
- 0.9.7.1
- 0.9.7
- 0.9.6.4
- 0.9.6.3
- 0.9.6.2
- 0.9.6.1
- 0.9.6
- 0.9.5.6
- 0.9.5.5
- 0.9.5.4
- 0.9.5.3
- 0.9.5.2
- 0.9.5.1
- 0.9.5
- 0.9.4
- 0.9.3
- 0.9.2
- 0.9.1
- 0.9.0
- 0.9.0-rc5
- 0.9.0-rc4
- 0.9.0-rc3
- 0.9.0-rc2
- 0.9.0-rc1
- 0.8.1
- 0.8.0
- 0.7.2
- 0.7.1
- 0.7.0
- 0.6.5
- 0.6.4
- 0.6.3
- 0.6.2
- 0.6.1
- 0.6.0
- 0.5.5
- 0.5.4
- 0.5.3
- 0.5.2
- 0.5.1
- 0.4.9
- 0.4.8
- 0.4.7
- 0.4.6
- 0.4.5
- 0.4.4
- 0.4.3
- 0.4.2
- 0.4.1
- 0.4
- 0.3.1
- 0.3
- 0.2
- 0.1.1
- 0.1
Deno based web service developers
Deco is a toolbelt for- Fault tolerance helpers (@Timeout, @Retry, @Try, @Trace, @Debounce, @Throttle, @RateLimit, @Concurrecy, @Cache)
- REST @Http API helpers with OpenAPI and EventStream support
- @Dapr helpers (Service, PubSub, Bindings, State, Secrets, Actor) for resilient cloud native Deno microservices/actors
Minimal Http server example
@Http.ServerController()
class Server {
@Http.Get()
hello() {}
}
Http.serve({
controllers: [Server],
});
example
More complex// curl http://localhost:8080/api
// curl http://localhost:8080/api/1
// curl -v -X POST "http://localhost:8080/api?q=1" -d "test data" -H "x-access-token: eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoiZGVjbyJ9.ae9rDEkN3goWCuc1-Dsbm9lX7kVJPHC8dlnKMFI1Gs-Y26kvGGo0UyQkMih0-zicLgx1viGLSufwfOctC1nWLQ"
import { Http } from "../decorators/httpserver.decorator.ts";
import { sleep } from "../utils/utils.ts";
@Http.ServerController({ schema: { fileName: "api.yaml" } })
class ExampleOpenAPI {}
const cryptoKey = await crypto.subtle.importKey(
"jwk",
JSON.parse(Deno.readTextFileSync("key.jwk")),
{ name: "HMAC", hash: "SHA-512" },
true,
[
"sign",
"verify",
],
);
@Http.ServerController()
class ExampleCustomAPI {
counter = 0;
@Http.Get("/api/:id")
get({ id, url }: { id: string; url: URL }) {
return {
body: `[GET /api/:id] 😎 (got id: "${id}", query: "${
decodeURIComponent(url.searchParams.toString())
}")`,
};
}
@Http.Post()
@Http.Auth({ cryptoKey })
async api(
{ url, request, auth }: {
url: URL;
request: Request;
auth: Record<string, unknown>;
},
) {
const data = await request.text();
return {
body: `[POST /api] 😎 (got data: "${data}", auth data: "${
JSON.stringify(auth)
}", query: "${
decodeURIComponent(url.searchParams.toString())
}", counter="${++this.counter}")`,
};
}
@Http.Get("/static/*")
static({ "*": path }: { "*": string }) {
return {
body: `[GET /static/*] 😎 (got path: "${path}")`,
};
}
}
@Http.ServerController()
class ExampleStream {
@Http.EventStream()
async *stream() {
yield ": Hello from stream\n\n";
while (true) {
await sleep(1000);
yield `event: tick\ndata: ${new Date().toISOString()}\n\n\n`;
}
}
}
@Http.ServerController()
class ExampleLimits {
@Http.Get()
@Http.RateLimit({ rps: 50 })
rpsTest() {}
}
console.log("Server started...");
Http.serve({
controllers: [ExampleOpenAPI, ExampleCustomAPI, ExampleStream, ExampleLimits],
});
Dapr example
// Start Dapr sidecar in local environment:
// dapr run --app-id sidecar --dapr-http-port 3500 --components-path ./components
// Run the example:
// dapr --app-id deco-app --app-port 3000 --components-path ./components run -- deno run -A --unstable --watch example_dapr.ts
// Publish message to topic A:
// dapr publish --publish-app-id sidecar --pubsub pubsub --topic A --data '{"data": "message for topic A"}'
// Publish message to topic B and get Telegrom notification (needs TELEGRAM_TOKEN and TELEGRAM_CHATID exist in the secrets store):
// dapr publish --publish-app-id sidecar --pubsub pubsub --topic B --data '{"text": "Hello from Deco.Dapr!"}'
// Publish message to topic C to see raw message format:
// dapr publish --publish-app-id sidecar --pubsub pubsub --topic C --data '{"raw": "raw message for topic C"}'
// Invoke "test" service
// dapr invoke --app-id deco-app --verb GET --method test
// Send data to the actor
// curl -X POST "http://localhost:3500/v1.0/actors/TestActor1/1/method/testMethod1" -d "{test: 'data'}"
import {
Actor,
Bindings,
Dapr,
PubSub,
Secrets,
Service,
State,
} from "../../decorators/dapr.decorator.ts";
const { TELEGRAM_CHATID, TELEGRAM_TOKEN } = await Secrets.getBulk({
store: "example-secrets-store",
});
const pubSubName = "pubsub";
@Dapr.AppController({ pubSubName })
class PubSubExample1 {
private s = "private1";
@PubSub.subscribeTo()
A({ data }: { data: unknown }) {
console.log("topicA =>", data, this);
}
@PubSub.subscribeTo()
B({ data }: { data: Record<string, unknown> }) {
console.log("topicB =>", data, this);
if (data.text && TELEGRAM_CHATID && TELEGRAM_TOKEN) {
const { text } = data;
const path =
`/bot${TELEGRAM_TOKEN}/sendMessage?chat_id=${TELEGRAM_CHATID}&text=${text}`;
Bindings.invoke({
bindingName: "telegram",
operation: "GET",
metadata: { path },
});
}
}
}
@Dapr.AppController({ pubSubName })
class PubSubExample2 {
private s = "private2";
@PubSub.subscribeTo({ metadata: { rawPayload: "true" } })
C(raw: Record<string, unknown>) {
console.log("topicC =>", raw, this);
}
}
@Dapr.AppController()
class PubSubExample3 {
private s = "private3";
@PubSub.subscribeTo({ pubSubName })
D({ data }: { data: unknown }) {
console.log("topicD =>", data, this);
console.log("publishing to topic A");
PubSub.publish({
pubSubName,
topicName: "A",
data,
});
}
}
@Dapr.AppController()
class ServiceExample1 {
private counter = 0;
@Service.expose()
async test({ request }: { request: Request }) {
// deno-fmt-ignore
console.log(`test service called, counter: ${++this.counter}, data = "${await request.text()}"`);
return {
body: `test reply, counter: ${this.counter}`,
};
}
@Bindings.listenTo()
tweets({ text }: { text: Record<string, unknown> }) {
console.log(`🐦 => "${text}"`);
}
}
@Dapr.AppController()
class TestActor1 {
private counter = 0;
@Actor.event()
activate({ actorType, actorId }: { actorType: string; actorId: string }) {
console.log("TestActor1 activated", this);
this.counter = 0;
Actor.setReminder({
actorType,
actorId,
reminderName: "reminder",
period: "5s",
});
}
@Actor.event()
async deactivate({ actorType, actorId }: { actorType: string; actorId: string }) {
console.log("TestActor1 deactivation", this);
const reminder = await Actor.getReminder({actorType, actorId, reminderName: "reminder"});
console.log("reminder =>", reminder);
await Actor.deleteReminder({ actorType, actorId, reminderName: "reminder" });
}
@Actor.event()
reminder() {
console.log("TestActor1 reminder called");
}
@Actor.method()
async testMethod1({ request }: { request: Request }) {
const data = await request.text();
console.log(
"TestActor1/testMethod1() called, data =",
data,
", counter =",
++this.counter,
);
}
}
@Dapr.AppController()
class TestActor2 {
private readonly tag = "TestActor2";
@Actor.method()
testMethod1({ actorType, actorId }: { actorType: string; actorId: string }) {
console.log("TestActor2/testMethod1() called,", this);
Actor.setTimer({ actorType, actorId, timerName: "timer", dueTime: "10s" });
}
@Actor.event()
timer() {
console.log("TestActor2/timer fired");
}
}
// Setting and getting state
await State.set({
storename: "example-state-store",
data: [{ key: "key1", value: "value1" }, { key: "key3", value: "value3" }],
});
// deno-fmt-ignore
console.log("key1=", await State.get({ storename: "example-state-store", key: "key1" }));
// deno-fmt-ignore
console.log("missing=", await State.get({storename: "example-state-store", key: "missing" }));
// deno-fmt-ignore
console.log("bulk=", await State.getBulk({storename: "example-state-store", data: { keys: ["key1", "missing", "key3"] }}));
console.log("Dapr app started...");
Dapr.start({
appPort: 3000,
actorIdleTimeout: "5s",
controllers: [
PubSubExample1,
PubSubExample2,
PubSubExample3,
ServiceExample1,
TestActor1,
TestActor2,
],
});
Running tests
deno test --allow-net