mirror of https://github.com/dapr/docs.git
* Tweaking the example to match what was demoed during the 9/21/2021 community call
* Added example CEL expressions * Added link to 9/21/2021 community call youtube video * Added section headers for the right nav
This commit is contained in:
parent
ccc6ebd819
commit
a927dd1028
|
@ -42,14 +42,14 @@ metadata:
|
||||||
name: myevent-subscription
|
name: myevent-subscription
|
||||||
spec:
|
spec:
|
||||||
pubsubname: pubsub
|
pubsubname: pubsub
|
||||||
topic: transactions
|
topic: inventory
|
||||||
routes:
|
routes:
|
||||||
rules:
|
rules:
|
||||||
- match: event.type == "withdraw.v3"
|
- match: event.type == "widget"
|
||||||
path: /withdraw.v3
|
path: /widgets
|
||||||
- match: event.type == "withdraw.v2"
|
- match: event.type == "gadget"
|
||||||
path: /withdraw.v2
|
path: /gadgets
|
||||||
default: /withdraw
|
default: /products
|
||||||
scopes:
|
scopes:
|
||||||
- app1
|
- app1
|
||||||
- app2
|
- app2
|
||||||
|
@ -77,24 +77,24 @@ def subscribe():
|
||||||
subscriptions = [
|
subscriptions = [
|
||||||
{
|
{
|
||||||
'pubsubname': 'pubsub',
|
'pubsubname': 'pubsub',
|
||||||
'topic': 'transactions',
|
'topic': 'inventory',
|
||||||
'routes': {
|
'routes': {
|
||||||
'rules': [
|
'rules': [
|
||||||
{
|
{
|
||||||
'match': 'event.type == "withdraw.v3"',
|
'match': 'event.type == "widget"',
|
||||||
'path': '/withdraw.v3'
|
'path': '/widgets'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'match': 'event.type == "withdraw.v2"',
|
'match': 'event.type == "gadget"',
|
||||||
'path': '/withdraw.v2'
|
'path': '/gadgets'
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
'default': '/withdraw'
|
'default': '/products'
|
||||||
}
|
}
|
||||||
}]
|
}]
|
||||||
return jsonify(subscriptions)
|
return jsonify(subscriptions)
|
||||||
|
|
||||||
@app.route('/withdraw', methods=['POST'])
|
@app.route('/products', methods=['POST'])
|
||||||
def ds_subscriber():
|
def ds_subscriber():
|
||||||
print(request.json, flush=True)
|
print(request.json, flush=True)
|
||||||
return json.dumps({'success':True}), 200, {'ContentType':'application/json'}
|
return json.dumps({'success':True}), 200, {'ContentType':'application/json'}
|
||||||
|
@ -113,30 +113,30 @@ app.use(bodyParser.json({ type: 'application/*+json' }));
|
||||||
const port = 3000
|
const port = 3000
|
||||||
|
|
||||||
app.get('/dapr/subscribe', (req, res) => {
|
app.get('/dapr/subscribe', (req, res) => {
|
||||||
res.json([
|
res.json([
|
||||||
{
|
{
|
||||||
pubsubname: "pubsub",
|
pubsubname: "pubsub",
|
||||||
topic: "transactions",
|
topic: "inventory",
|
||||||
routes: {
|
routes: {
|
||||||
rules: [
|
rules: [
|
||||||
{
|
{
|
||||||
match: 'event.type == "withdraw.v3"',
|
match: 'event.type == "widget"',
|
||||||
path: '/withdraw.v3'
|
path: '/widgets'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
match: 'event.type == "withdraw.v2"',
|
match: 'event.type == "gadget"',
|
||||||
path: '/withdraw.v2'
|
path: '/gadgets'
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
default: '/withdraw'
|
default: '/products'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
})
|
})
|
||||||
|
|
||||||
app.post('/withdraw', (req, res) => {
|
app.post('/products', (req, res) => {
|
||||||
console.log(req.body);
|
console.log(req.body);
|
||||||
res.sendStatus(200);
|
res.sendStatus(200);
|
||||||
});
|
});
|
||||||
|
|
||||||
app.listen(port, () => console.log(`consumer app listening on port ${port}!`))
|
app.listen(port, () => console.log(`consumer app listening on port ${port}!`))
|
||||||
|
@ -145,25 +145,25 @@ app.listen(port, () => console.log(`consumer app listening on port ${port}!`))
|
||||||
|
|
||||||
{{% codetab %}}
|
{{% codetab %}}
|
||||||
```csharp
|
```csharp
|
||||||
[Topic("pubsub", "transactions", "event.type ==\"withdraw.v3\"", 1)]
|
[Topic("pubsub", "inventory", "event.type ==\"widget\"", 1)]
|
||||||
[HttpPost("withdraw.v3")]
|
[HttpPost("widgets")]
|
||||||
public async Task<ActionResult<Account>> WithdrawV3(TransactionV3 transaction, [FromServices] DaprClient daprClient)
|
public async Task<ActionResult<Account>> HandleWidget(Widget transaction, [FromServices] DaprClient daprClient)
|
||||||
{
|
{
|
||||||
// Logic
|
// Logic
|
||||||
return account;
|
return account;
|
||||||
}
|
}
|
||||||
|
|
||||||
[Topic("pubsub", "transactions", "event.type ==\"withdraw.v2\"", 2)]
|
[Topic("pubsub", "inventory", "event.type ==\"gadget\"", 2)]
|
||||||
[HttpPost("withdraw.v2")]
|
[HttpPost("gadgets")]
|
||||||
public async Task<ActionResult<Account>> WithdrawV2(TransactionV2 transaction, [FromServices] DaprClient daprClient)
|
public async Task<ActionResult<Account>> HandleGadget(Gadget transaction, [FromServices] DaprClient daprClient)
|
||||||
{
|
{
|
||||||
// Logic
|
// Logic
|
||||||
return account;
|
return account;
|
||||||
}
|
}
|
||||||
|
|
||||||
[Topic("pubsub", "transactions")]
|
[Topic("pubsub", "inventory")]
|
||||||
[HttpPost("withdraw")]
|
[HttpPost("products")]
|
||||||
public async Task<ActionResult<Account>> Withdraw(Transaction transaction, [FromServices] DaprClient daprClient)
|
public async Task<ActionResult<Account>> HandleProduct(Product transaction, [FromServices] DaprClient daprClient)
|
||||||
{
|
{
|
||||||
// Logic
|
// Logic
|
||||||
return account;
|
return account;
|
||||||
|
@ -208,19 +208,19 @@ func configureSubscribeHandler(w http.ResponseWriter, _ *http.Request) {
|
||||||
t := []subscription{
|
t := []subscription{
|
||||||
{
|
{
|
||||||
PubsubName: "pubsub",
|
PubsubName: "pubsub",
|
||||||
Topic: "transactions",
|
Topic: "inventory",
|
||||||
Routes: routes{
|
Routes: routes{
|
||||||
Rules: []rule{
|
Rules: []rule{
|
||||||
{
|
{
|
||||||
Match: `event.type == "withdraw.v3"`,
|
Match: `event.type == "widget"`,
|
||||||
Path: "/withdraw.v3",
|
Path: "/widgets",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Match: `event.type == "withdraw.v2"`,
|
Match: `event.type == "gadget"`,
|
||||||
Path: "/withdraw.v2",
|
Path: "/gadgets",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Default: "/withdraw",
|
Default: "/products",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -244,14 +244,14 @@ func main() {
|
||||||
require_once __DIR__.'/vendor/autoload.php';
|
require_once __DIR__.'/vendor/autoload.php';
|
||||||
|
|
||||||
$app = \Dapr\App::create(configure: fn(\DI\ContainerBuilder $builder) => $builder->addDefinitions(['dapr.subscriptions' => [
|
$app = \Dapr\App::create(configure: fn(\DI\ContainerBuilder $builder) => $builder->addDefinitions(['dapr.subscriptions' => [
|
||||||
new \Dapr\PubSub\Subscription(pubsubname: 'pubsub', topic: 'transactions', routes: (
|
new \Dapr\PubSub\Subscription(pubsubname: 'pubsub', topic: 'inventory', routes: (
|
||||||
rules: => [
|
rules: => [
|
||||||
('match': 'event.type == "withdraw.v3"', path: '/withdraw.v3'),
|
('match': 'event.type == "widget"', path: '/widgets'),
|
||||||
('match': 'event.type == "withdraw.v2"', path: '/withdraw.v2'),
|
('match': 'event.type == "gadget"', path: '/gadgets'),
|
||||||
]
|
]
|
||||||
default: '/withdraw')),
|
default: '/products')),
|
||||||
]]));
|
]]));
|
||||||
$app->post('/withdraw', function(
|
$app->post('/products', function(
|
||||||
#[\Dapr\Attributes\FromBody]
|
#[\Dapr\Attributes\FromBody]
|
||||||
\Dapr\PubSub\CloudEvent $cloudEvent,
|
\Dapr\PubSub\CloudEvent $cloudEvent,
|
||||||
\Psr\Log\LoggerInterface $logger
|
\Psr\Log\LoggerInterface $logger
|
||||||
|
@ -266,7 +266,34 @@ $app->start();
|
||||||
|
|
||||||
{{< /tabs >}}
|
{{< /tabs >}}
|
||||||
|
|
||||||
In these examples, depending on the type of the event (`event.type`), the application will be called on `/withdraw.v3`, `/withdraw.v2` or `/withdraw`. The expressions are written as [Common Expression Language (CEL)](https://opensource.google/projects/cel) where `event` represents the cloud event. Any of the attributes from the [CloudEvents core specification](https://github.com/cloudevents/spec/blob/v1.0.1/spec.md#required-attributes) can be referenced in the expression.
|
## Common Expression Language (CEL)
|
||||||
|
|
||||||
|
In these examples, depending on the type of the event (`event.type`), the application will be called on `/widgets`, `/gadgets` or `/products`. The expressions are written as [Common Expression Language (CEL)](https://github.com/google/cel-spec) where `event` represents the cloud event. Any of the attributes from the [CloudEvents core specification](https://github.com/cloudevents/spec/blob/v1.0.1/spec.md#required-attributes) can be referenced in the expression.
|
||||||
|
|
||||||
|
### Example expressions
|
||||||
|
|
||||||
|
Match "important" messages
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
has(event.data.important) && event.data.important == true
|
||||||
|
```
|
||||||
|
|
||||||
|
Match deposits greater than $10000
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
event.type == "deposit" && event.data.amount > 10000
|
||||||
|
```
|
||||||
|
|
||||||
|
Match multiple versions of a message
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
event.type == "mymessage.v1"
|
||||||
|
```
|
||||||
|
```javascript
|
||||||
|
event.type == "mymessage.v2"
|
||||||
|
```
|
||||||
|
|
||||||
|
## CloudEvent attributes
|
||||||
|
|
||||||
For reference, the following attributes are from the CloudEvents specification.
|
For reference, the following attributes are from the CloudEvents specification.
|
||||||
|
|
||||||
|
@ -476,7 +503,13 @@ Currently, comparisons to time (e.g. before or after "now") are not supported.
|
||||||
|
|
||||||
## Next steps
|
## Next steps
|
||||||
|
|
||||||
- Try the [Pub/Sub quickstart sample](https://github.com/dapr/quickstarts/tree/master/pub-sub)
|
Watch [this video](https://www.youtube.com/watch?v=QqJgRmbH82I&t=1063s) on how to use message routing with pub/sub.
|
||||||
|
|
||||||
|
<p class="embed-responsive embed-responsive-16by9">
|
||||||
|
<iframe width="688" height="430" src="https://www.youtube.com/embed/QqJgRmbH82I?start=1063" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
- Try the [Pub/Sub routing sample](https://github.com/dapr/samples/tree/master/pub-sub-routing)
|
||||||
- Learn about [topic scoping]({{< ref pubsub-scopes.md >}})
|
- Learn about [topic scoping]({{< ref pubsub-scopes.md >}})
|
||||||
- Learn about [message time-to-live]({{< ref pubsub-message-ttl.md >}})
|
- Learn about [message time-to-live]({{< ref pubsub-message-ttl.md >}})
|
||||||
- Learn [how to configure Pub/Sub components with multiple namespaces]({{< ref pubsub-namespaces.md >}})
|
- Learn [how to configure Pub/Sub components with multiple namespaces]({{< ref pubsub-namespaces.md >}})
|
||||||
|
|
Loading…
Reference in New Issue