docs: update README and examples with new API (#138)
This commit modifies the README to show new API usage for the `HTTPReceiver` and `CloudEvent` classes, and updates the examples to use this as well. Overall structure and content has been modified to look more like the sdk-go README. Fixes: https://github.com/cloudevents/sdk-javascript/issues/128 Signed-off-by: Lance Ball <lball@redhat.com>
This commit is contained in:
parent
5a6cde5695
commit
b866edddd9
305
README.md
305
README.md
|
@ -3,7 +3,6 @@
|
|||
[](https://www.codacy.com/app/fabiojose/sdk-javascript?utm_source=github.com&utm_medium=referral&utm_content=cloudevents/sdk-javascript&utm_campaign=Badge_Grade)
|
||||
[](https://www.codacy.com/app/fabiojose/sdk-javascript?utm_source=github.com&utm_medium=referral&utm_content=cloudevents/sdk-javascript&utm_campaign=Badge_Coverage)
|
||||
[](https://travis-ci.org/cloudevents/sdk-javascript)
|
||||
[](https://www.npmjs.com/package/cloudevents-sdk)
|
||||
[](https://www.npmjs.com/package/cloudevents-sdk)
|
||||
[](https://snyk.io/test/github/cloudevents/sdk-javascript)
|
||||
[](http://www.apache.org/licenses/LICENSE-2.0)
|
||||
|
@ -11,273 +10,91 @@
|
|||
|
||||
The CloudEvents SDK for JavaScript.
|
||||
|
||||
## Status
|
||||
This module will help you to:
|
||||
|
||||
This SDK is still considered a work in progress.
|
||||
* Represent CloudEvents in memory
|
||||
* Use [Event Formats](https://github.com/cloudevents/spec/blob/v1.0/spec.md#event-format) to serialize/deserialize CloudEvents
|
||||
* Use [Protocol Bindings](https://github.com/cloudevents/spec/blob/v1.0/spec.md#protocol-binding) to send/receive CloudEvents
|
||||
|
||||
This SDK current supports the following versions of CloudEvents:
|
||||
_Note:_ Supported
|
||||
[CloudEvents specification](https://github.com/cloudevents/spec): 0.3, 1.0
|
||||
|
||||
- v1.0
|
||||
### A Note on Versioning
|
||||
|
||||
**Checkout the [changelog](CHANGELOG.md) to see what's going on!**
|
||||
The CloudEvents protocol version is distinct from this module's version number.
|
||||
For example, this module may be versioned as v2.0.0 but support the v0.3 and v1.0
|
||||
versions of the CloudEvent specification.
|
||||
|
||||
## Installation
|
||||
## Usage
|
||||
|
||||
This CloudEvents SDK requires nodejs 6.11+
|
||||
**See the full working example: [here](./examples/express-ex).**
|
||||
|
||||
### Nodejs
|
||||
### Installation
|
||||
|
||||
```sh
|
||||
npm install cloudevents-sdk
|
||||
```
|
||||
## Specification Support
|
||||
The CloudEvents SDK requires a current LTS version of Node.js. At the moment
|
||||
those are Node.js 10.x and Node.js 12.x. To install in your Node.js project:
|
||||
|
||||
These are the supported specifications by this version.
|
||||
|
||||
| **Specifications** | v0.3 | **v1.0** |
|
||||
|---------------------------------------|------|----------|
|
||||
| CloudEvents | yes | yes |
|
||||
| HTTP Transport Binding - Structured | yes | yes |
|
||||
| HTTP Transport Binding - Binary | yes | yes |
|
||||
| JSON Event Format | yes | yes |
|
||||
|
||||
### What we can do
|
||||
|
||||
| **What** | v0.3 | **v1.0** |
|
||||
|-------------------------------------|------|----------|
|
||||
| Create events | yes | yes |
|
||||
| Emit Structured events over HTTP | yes | yes |
|
||||
| Emit Binary events over HTTP | yes | yes |
|
||||
| JSON Event Format | yes | yes |
|
||||
| Receive Structured events over HTTP | yes | yes |
|
||||
| Receive Binary events over HTTP | yes | yes |
|
||||
|
||||
## How to use
|
||||
|
||||
### Usage
|
||||
|
||||
```js
|
||||
const v1 = require("cloudevents-sdk/v1");
|
||||
|
||||
/*
|
||||
* Creating an event
|
||||
*/
|
||||
let myevent = v1.event()
|
||||
.type("com.github.pull.create")
|
||||
.source("urn:event:from:myapi/resource/123");
|
||||
```console
|
||||
npm install --save cloudevents-sdk
|
||||
```
|
||||
|
||||
#### Formatting
|
||||
|
||||
```js
|
||||
const v1 = require("cloudevents-sdk/v1");
|
||||
|
||||
/*
|
||||
* Creating an event
|
||||
*/
|
||||
let myevent = v1.event()
|
||||
.type("com.github.pull.create")
|
||||
.source("urn:event:from:myapi/resource/123");
|
||||
|
||||
/*
|
||||
* Format the payload and return it
|
||||
*/
|
||||
let formatted = myevent.format();
|
||||
```
|
||||
|
||||
#### Emitting
|
||||
|
||||
```js
|
||||
const v1 = require("cloudevents-sdk/v1");
|
||||
|
||||
/*
|
||||
* Creating an event
|
||||
*/
|
||||
let myevent = v1.event()
|
||||
.type("com.github.pull.create")
|
||||
.source("urn:event:from:myapi/resource/123");
|
||||
|
||||
// The binding configuration using POST
|
||||
let config = {
|
||||
method: "POST",
|
||||
url : "https://myserver.com"
|
||||
};
|
||||
|
||||
// The binding instance
|
||||
let binding = new v1.StructuredHTTPEmitter(config);
|
||||
|
||||
// Emit the event using Promise
|
||||
binding.emit(myevent)
|
||||
.then(response => {
|
||||
// Treat the response
|
||||
console.log(response.data);
|
||||
|
||||
}).catch(err => {
|
||||
// Deal with errors
|
||||
console.error(err);
|
||||
});
|
||||
```
|
||||
### Receiving and Emitting Events
|
||||
|
||||
#### Receiving Events
|
||||
|
||||
You can choose any framework for port binding. But, use the
|
||||
StructuredHTTPReceiver or BinaryHTTPReceiver to process the HTTP Payload and
|
||||
HTTP Headers, extracting the CloudEvents.
|
||||
|
||||
:smiley: **Checkout the full working example: [here](./examples/express-ex).**
|
||||
You can choose almost any popular web framework for port binding. Use an
|
||||
`HTTPReceiver` to process the incoming HTTP request. The receiver accepts
|
||||
binary and structured events in either the 1.0 or 0.3 protocol formats.
|
||||
|
||||
```js
|
||||
// some parts were removed //
|
||||
const {
|
||||
CloudEvent,
|
||||
HTTPReceiever
|
||||
} = require("cloudevents-sdk");
|
||||
|
||||
const v1 = require("cloudevents-sdk/v1");
|
||||
// Create a receiver to accept events over HTTP
|
||||
const receiver = new HTTPReceiver();
|
||||
|
||||
const receiver = new v1.StructuredHTTPReceiver();
|
||||
// body and headers come from an incoming HTTP request, e.g. express.js
|
||||
const receivedEvent = receiver.accept(req.body, req.headers);
|
||||
console.log(receivedEvent.format());
|
||||
```
|
||||
|
||||
// some parts were removed //
|
||||
#### Emitting Events
|
||||
|
||||
app.post("/", (req, res) => {
|
||||
try {
|
||||
let myevent = receiver.parse(req.body, req.headers);
|
||||
Currently, to emit events, you'll need to decide whether the event is in
|
||||
binary or structured format, and determine what version of the CloudEvents
|
||||
specification you want to send the event as.
|
||||
|
||||
// TODO use the event
|
||||
```js
|
||||
const { CloudEvent } = require("cloudevents-sdk");
|
||||
const { StructuredHTTPEmitter } = require("cloudevents-sdk/v1");
|
||||
|
||||
res.status(201).send("Event Accepted");
|
||||
const myevent = new CloudEvent()
|
||||
.type("com.github.pull.create")
|
||||
.source("urn:event:from:myapi/resource/123");
|
||||
|
||||
} catch(err) {
|
||||
// TODO deal with errors
|
||||
console.error(err);
|
||||
res.status(415)
|
||||
.header("Content-Type", "application/json")
|
||||
.send(JSON.stringify(err));
|
||||
}
|
||||
const emitter = new StructuredHTTPEmitter({
|
||||
method: "POST",
|
||||
url : "https://myserver.com"
|
||||
});
|
||||
|
||||
// Emit the event
|
||||
emitter.emit(myevent)
|
||||
```
|
||||
|
||||
## Unit Testing
|
||||
## Supported specification features
|
||||
|
||||
The unit test checks the result of formatted payload and the constraints.
|
||||
|
||||
```bash
|
||||
npm test
|
||||
```
|
||||
|
||||
## The API
|
||||
|
||||
### `CloudEvent` class
|
||||
|
||||
```js
|
||||
/*
|
||||
* Format the payload and return an Object.
|
||||
*/
|
||||
Object CloudEvent.format()
|
||||
|
||||
/*
|
||||
* Format the payload as String.
|
||||
*/
|
||||
String CloudEvent.toString()
|
||||
```
|
||||
|
||||
### `Formatter` classes
|
||||
|
||||
Every formatter class must implement these methods to work properly.
|
||||
|
||||
```js
|
||||
/*
|
||||
* Format the CloudEvent payload argument and return an Object.
|
||||
*/
|
||||
Object Formatter.format(Object)
|
||||
|
||||
/*
|
||||
* Format the CloudEvent payload as String.
|
||||
*/
|
||||
String Formatter.toString(Object)
|
||||
```
|
||||
|
||||
### `Parser` classes
|
||||
|
||||
Every Parser class must implement these methods to work properly.
|
||||
|
||||
```js
|
||||
/*
|
||||
* The default constructor with Parser as decorator
|
||||
*/
|
||||
Parser(Parser)
|
||||
|
||||
/*
|
||||
* Try to parse the payload to some event format
|
||||
*/
|
||||
Object Parser.parse(payload)
|
||||
```
|
||||
|
||||
### `Spec` classes
|
||||
|
||||
Every Spec class must implement these methods to work properly.
|
||||
|
||||
```js
|
||||
/*
|
||||
* The constructor must receives the CloudEvent type.
|
||||
*/
|
||||
Spec(CloudEvent)
|
||||
|
||||
/*
|
||||
* Checks the spec constraints, throwing an error if do not pass.
|
||||
* @throws Error when it is an invalid event
|
||||
*/
|
||||
Spec.check()
|
||||
|
||||
/*
|
||||
* Checks if the argument pass through the spec constraints
|
||||
* @throws Error when it is an invalid event
|
||||
*/
|
||||
Spec.check(Object)
|
||||
```
|
||||
|
||||
### `Binding` classes
|
||||
|
||||
Every Binding class must implement these methods to work properly.
|
||||
|
||||
#### Emitter Binding
|
||||
|
||||
Following we have the signature for the binding to emit CloudEvents.
|
||||
|
||||
```js
|
||||
/*
|
||||
* The constructor must receives the map of configurations.
|
||||
*/
|
||||
Binding(config)
|
||||
|
||||
/*
|
||||
* Emits the event using an instance of CloudEvent.
|
||||
*/
|
||||
Binding.emit(cloudEvent)
|
||||
```
|
||||
|
||||
#### Receiver Binding
|
||||
|
||||
Following we have the signature for the binding to receive CloudEvents.
|
||||
|
||||
```js
|
||||
/*
|
||||
* The constructor must receives the map of configurations.
|
||||
*/
|
||||
Receiver(config)
|
||||
|
||||
/*
|
||||
* Checks if some Object and a Map of headers
|
||||
* follows the binding definition, throwing an error if did not follow
|
||||
*/
|
||||
Receiver.check(Object, Map)
|
||||
|
||||
/*
|
||||
* Checks and parse as CloudEvent
|
||||
*/
|
||||
CloudEvent Receiver.parse(Object, Map)
|
||||
```
|
||||
|
||||
## Versioning
|
||||
|
||||
- `x.M.p`: where `x` relates to spec version, `M` relates to minor and `p` relates
|
||||
to fixes. See [semver](https://semver.org/)
|
||||
| | [v0.3](https://github.com/cloudevents/spec/tree/v0.3) | [v1.0](https://github.com/cloudevents/spec/tree/v1.0) |
|
||||
| ----------------------------- | --- | --- |
|
||||
| CloudEvents Core | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| AMQP Protocol Binding | :x: | :x: |
|
||||
| AVRO Event Format | :x: | :x: |
|
||||
| HTTP Protocol Binding | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| JSON Event Format | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| Kafka Protocol Binding | :x: | :x: |
|
||||
| NATS Protocol Binding | :x: | :x: |
|
||||
| STAN Protocol Binding | :x: | :x: |
|
||||
|
||||
## Community
|
||||
|
||||
|
@ -291,3 +108,9 @@ to fixes. See [semver](https://semver.org/)
|
|||
[CNCF's Slack workspace](https://slack.cncf.io/).
|
||||
- Email: https://lists.cncf.io/g/cncf-cloudevents-sdk
|
||||
- Contact for additional information: Fabio José (`@fabiojose` on slack).
|
||||
|
||||
## Contributing
|
||||
|
||||
We love contributions from the community! Please check the
|
||||
[Contributor's Guide](https://github.com/cloudevents/sdk-javascript/blob/master/CONTRIBUTING.md)
|
||||
for information on how to get involved.
|
||||
|
|
|
@ -17,7 +17,7 @@ __A Structured One__
|
|||
curl -X POST \
|
||||
-d'@../payload/v1/structured-event-0.json' \
|
||||
-H'Content-Type:application/cloudevents+json' \
|
||||
http://localhost:3000/v1
|
||||
http://localhost:3000/
|
||||
```
|
||||
|
||||
__A Structured One with Extension__
|
||||
|
@ -28,7 +28,7 @@ __A Structured One with Extension__
|
|||
curl -X POST \
|
||||
-d'@../payload/v1/structured-event-1.json' \
|
||||
-H'Content-Type:application/cloudevents+json' \
|
||||
http://localhost:3000/v1
|
||||
http://localhost:3000/
|
||||
```
|
||||
|
||||
__A Structured One with Base64 Event Data__
|
||||
|
@ -39,7 +39,7 @@ __A Structured One with Base64 Event Data__
|
|||
curl -X POST \
|
||||
-d'@../payload/v1/structured-event-2.json' \
|
||||
-H'Content-Type:application/cloudevents+json' \
|
||||
http://localhost:3000/v1
|
||||
http://localhost:3000/
|
||||
```
|
||||
|
||||
__A Binary One__
|
||||
|
@ -53,7 +53,7 @@ curl -X POST \
|
|||
-H'ce-source:https://github.com/cloudevents/spec/pull/123' \
|
||||
-H'ce-id:45c83279-c8a1-4db6-a703-b3768db93887' \
|
||||
-H'ce-time:2019-11-06T11:17:00Z' \
|
||||
http://localhost:3000/v1/binary
|
||||
http://localhost:3000/
|
||||
```
|
||||
|
||||
__A Binary One with Extension__
|
||||
|
@ -68,7 +68,7 @@ curl -X POST \
|
|||
-H'ce-id:45c83279-c8a1-4db6-a703-b3768db93887' \
|
||||
-H'ce-time:2019-11-06T11:17:00Z' \
|
||||
-H'ce-my-extension:extension value' \
|
||||
http://localhost:3000/v1/binary
|
||||
http://localhost:3000/
|
||||
```
|
||||
|
||||
__A Binary One with Base 64 Encoding__
|
||||
|
@ -82,12 +82,9 @@ curl -X POST \
|
|||
-H'ce-source:https://github.com/cloudevents/spec/pull/123' \
|
||||
-H'ce-id:45c83279-c8a1-4db6-a703-b3768db93887' \
|
||||
-H'ce-time:2019-11-06T11:17:00Z' \
|
||||
http://localhost:3000/v1/binary
|
||||
http://localhost:3000/
|
||||
```
|
||||
|
||||
__A Batch One__
|
||||
|
||||
TODO
|
||||
|
||||
## Spec v0.3
|
||||
|
||||
|
@ -99,7 +96,7 @@ __A Structured One__
|
|||
curl -X POST \
|
||||
-d'@../payload/v03/structured-event-0.json' \
|
||||
-H'Content-Type:application/cloudevents+json' \
|
||||
http://localhost:3000/v03
|
||||
http://localhost:3000/
|
||||
```
|
||||
|
||||
__A Structured One with Extension__
|
||||
|
@ -110,7 +107,7 @@ __A Structured One with Extension__
|
|||
curl -X POST \
|
||||
-d'@../payload/v03/structured-event-1.json' \
|
||||
-H'Content-Type:application/cloudevents+json' \
|
||||
http://localhost:3000/v03
|
||||
http://localhost:3000/
|
||||
```
|
||||
|
||||
__A Binary One__
|
||||
|
@ -124,7 +121,7 @@ curl -X POST \
|
|||
-H'ce-source:https://github.com/cloudevents/spec/pull/123' \
|
||||
-H'ce-id:45c83279-c8a1-4db6-a703-b3768db93887' \
|
||||
-H'ce-time:2019-06-21T17:31:00Z' \
|
||||
http://localhost:3000/v03
|
||||
http://localhost:3000/
|
||||
```
|
||||
|
||||
__A Binary One with Extension__
|
||||
|
@ -139,7 +136,7 @@ curl -X POST \
|
|||
-H'ce-id:45c83279-c8a1-4db6-a703-b3768db93887' \
|
||||
-H'ce-time:2019-06-21T17:31:00Z' \
|
||||
-H'ce-my-extension:extension value' \
|
||||
http://localhost:3000/v03
|
||||
http://localhost:3000/
|
||||
```
|
||||
|
||||
__A Binary One with Base 64 Encoding__
|
||||
|
@ -154,10 +151,6 @@ curl -X POST \
|
|||
-H'ce-id:45c83279-c8a1-4db6-a703-b3768db93887' \
|
||||
-H'ce-time:2019-06-21T17:31:00Z' \
|
||||
-H'ce-datacontentencoding:base64' \
|
||||
http://localhost:3000/v03
|
||||
http://localhost:3000/
|
||||
```
|
||||
|
||||
__A Batch One__
|
||||
|
||||
TODO
|
||||
|
||||
|
|
|
@ -1,14 +1,10 @@
|
|||
/* eslint-disable no-console */
|
||||
|
||||
const express = require("express");
|
||||
const { HTTPReceiver } = require("../../");
|
||||
|
||||
const app = express();
|
||||
|
||||
const v03 = require("cloudevents-sdk/v03");
|
||||
const unmarshaller03 = new v03.HTTPUnmarshaller();
|
||||
|
||||
const v1 = require("cloudevents-sdk/v1");
|
||||
const structured1 = new v1.StructuredHTTPReceiver();
|
||||
const binary1 = new v1.BinaryHTTPReceiver();
|
||||
const receiver = new HTTPReceiver();
|
||||
|
||||
app.use((req, res, next) => {
|
||||
let data = "";
|
||||
|
@ -24,18 +20,15 @@ app.use((req, res, next) => {
|
|||
});
|
||||
});
|
||||
|
||||
app.post("/v1", function(req, res) {
|
||||
app.post("/", function(req, res) {
|
||||
console.log(req.headers);
|
||||
console.log(req.body);
|
||||
|
||||
try {
|
||||
const myevent = structured1.parse(req.body, req.headers);
|
||||
// pretty print
|
||||
console.log("Accepted event:");
|
||||
console.log(JSON.stringify(myevent.format(), null, 2));
|
||||
|
||||
res.status(201)
|
||||
.json(myevent.format());
|
||||
const event = receiver.accept(req.headers, req.body);
|
||||
const asJSON = event.format();
|
||||
console.log(`Accepted event: ${JSON.stringify(event.format(), null, 2)}`);
|
||||
res.status(201).json(asJSON);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
res.status(415)
|
||||
|
@ -44,47 +37,6 @@ app.post("/v1", function(req, res) {
|
|||
}
|
||||
});
|
||||
|
||||
app.post("/v1/binary", function(req, res) {
|
||||
console.log(req.headers);
|
||||
console.log(req.body);
|
||||
|
||||
try {
|
||||
const myevent = binary1.parse(req.body, req.headers);
|
||||
// pretty print
|
||||
console.log("Accepted event:");
|
||||
console.log(JSON.stringify(myevent.format(), null, 2));
|
||||
|
||||
res.status(201)
|
||||
.json(myevent.format());
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
res.status(415)
|
||||
.header("Content-Type", "application/json")
|
||||
.send(JSON.stringify(err));
|
||||
}
|
||||
});
|
||||
|
||||
app.post("/v03", function(req, res) {
|
||||
console.log(req.headers);
|
||||
console.log(req.body);
|
||||
|
||||
unmarshaller03.unmarshall(req.body, req.headers)
|
||||
.then((cloudevent) => {
|
||||
// pretty print
|
||||
console.log("Accepted event:");
|
||||
console.log(JSON.stringify(cloudevent.format(), null, 2));
|
||||
|
||||
res.status(201)
|
||||
.json(cloudevent.format());
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
res.status(415)
|
||||
.header("Content-Type", "application/json")
|
||||
.send(JSON.stringify(err));
|
||||
});
|
||||
});
|
||||
|
||||
app.listen(3000, function() {
|
||||
console.log("Example app listening on port 3000!");
|
||||
});
|
||||
|
|
|
@ -1,14 +1,9 @@
|
|||
import CloudEvent, {
|
||||
event,
|
||||
StructuredHTTPEmitter,
|
||||
BinaryHTTPEmitter,
|
||||
StructuredHTTPReceiver,
|
||||
BinaryHTTPReceiver
|
||||
} from 'cloudevents-sdk/v1';
|
||||
import { CloudEvent, HTTPREceiver } from '../../';
|
||||
|
||||
export function doSomeStuff() {
|
||||
const receiver = new HTTPREceiver();
|
||||
|
||||
const myevent: CloudEvent = event()
|
||||
const myevent: CloudEvent = new CloudEvent()
|
||||
.source('/source')
|
||||
.type('type')
|
||||
.dataContentType('text/plain')
|
||||
|
@ -20,39 +15,13 @@ export function doSomeStuff() {
|
|||
console.log(myevent.toString());
|
||||
console.log(myevent.getExtensions());
|
||||
|
||||
const config = {
|
||||
method: "POST",
|
||||
url : "https://enu90y24i64jp.x.pipedream.net/"
|
||||
};
|
||||
|
||||
// ------ emitter structured
|
||||
const structured = new StructuredHTTPEmitter(config);
|
||||
structured.emit(myevent).then(res => {
|
||||
// success
|
||||
console.log("Structured Mode: Success!")
|
||||
})
|
||||
.catch(err => {
|
||||
// error
|
||||
console.error(err);
|
||||
});
|
||||
|
||||
// ------ emitter binary
|
||||
const binary = new BinaryHTTPEmitter(config);
|
||||
binary.emit(myevent).then(res => {
|
||||
console.log("Binary Mode: Success!");
|
||||
})
|
||||
.catch(err => {
|
||||
console.error(err);
|
||||
});
|
||||
|
||||
// ------ receiver structured
|
||||
const payload = myevent.toString();
|
||||
const headers = {
|
||||
"Content-Type":"application/cloudevents+json"
|
||||
};
|
||||
|
||||
const receiverStructured = new StructuredHTTPReceiver();
|
||||
console.log(receiverStructured.parse(payload, headers).toString());
|
||||
console.log(receiver.accept(headers, payload).toString());
|
||||
|
||||
// ------ receiver binary
|
||||
const extension1 = "mycuston-ext1";
|
||||
|
@ -70,10 +39,9 @@ export function doSomeStuff() {
|
|||
"ce-extension1" : extension1
|
||||
};
|
||||
|
||||
const receiverBinary = new BinaryHTTPReceiver();
|
||||
console.log(receiverBinary.parse(data, attributes).toString());
|
||||
console.log(receiver.accept(attributes, data).toString());
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
doSomeStuff();
|
||||
|
|
Loading…
Reference in New Issue