-
Notifications
You must be signed in to change notification settings - Fork 30
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* docs: add python client example * docs: add skeleton for clients * docs: add golang client docs * docs: clients: add python and golang docs * docs: clients: add javascript client docs * docs: clients: add java client docs * docs: clients: show line numbers in quickstart examples * docs: simplify quickstart * docs: clients: overview: add details about wire and serialization types * docs: clients: golang: add explanation for serializer * docs: quickstart: fix event example
- Loading branch information
Showing
7 changed files
with
463 additions
and
330 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
# Golang | ||
|
||
## Requirements | ||
Make sure that Go >= `1.16` is installed on your system. See [installation instructions](https://go.dev/doc/install) on Go's website for more info. | ||
|
||
## Installation | ||
Install Raccoon's Go client using | ||
```bash | ||
$ go get github.com/raystack/raccoon/clients/go | ||
``` | ||
## Usage | ||
|
||
### Quickstart | ||
|
||
Below is a self contained example of Raccoon's Go client that uses the Websocket API to publish events | ||
|
||
```go title="quickstart.go" showLineNumbers | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"log" | ||
raccoon "github.com/raystack/raccoon/clients/go" | ||
"google.golang.org/protobuf/types/known/timestamppb" | ||
"github.com/google/uuid" | ||
"github.com/raystack/raccoon/clients/go/serializer" | ||
"github.com/raystack/raccoon/clients/go/testdata" | ||
"github.com/raystack/raccoon/clients/go/ws" | ||
) | ||
|
||
func main() { | ||
client, err := ws.New( | ||
ws.WithUrl("ws://localhost:8080/api/v1/events"), | ||
ws.WithHeader("x-user-id", "123"), | ||
ws.WithHeader("x-user-type", "ACME"), | ||
ws.WithSerializer(serializer.JSON), | ||
) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
defer client.Close() | ||
_, err = client.Send([]*raccoon.Event{ | ||
{ | ||
Type: "page", | ||
Data: &testdata.PageEvent{ | ||
EventGuid: uuid.NewString(), | ||
EventName: "clicked", | ||
SentTime: timestamppb.Now(), | ||
}, | ||
}, | ||
}) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
fmt.Println(<-client.EventAcks()) | ||
} | ||
``` | ||
|
||
### Guide | ||
|
||
#### Creating a client | ||
|
||
Raccoon's API is exposed over 3 different protocols. | ||
Depending on which protocol you wish to utilise to publish events to Raccoon, you will need to intantiate a different client. | ||
|
||
Following is a table describing which package you should use for a given protocol. | ||
|
||
| Protocol | Package | | ||
| --- | --- | | ||
| Websocket | `github.com/raystack/raccoon/clients/go/ws` | | ||
| REST | `github.com/raystack/raccoon/clients/go/rest` | | ||
| gRPC | `github.com/raystack/raccoon/clients/go/grpc` | | ||
|
||
For instance, you can create a client over REST API using: | ||
```go | ||
import "github.com/raystack/raccoon/clients/go/rest" | ||
|
||
func main() { | ||
client, err := rest.New( | ||
rest.WithURL("http://localhost:8080/api/v1/events"), | ||
rest.WithHeader("x-user-id", "123") | ||
) | ||
if err != nil { | ||
panic(err) | ||
} | ||
|
||
// use the client here | ||
} | ||
``` | ||
|
||
Depending on which protocol client you create, specifying the URL or the address of the server is mandatory. | ||
|
||
For `REST` and `Websocket` clients, this can be done via the `WithUrl` option. For `gRPC` server you must use the `WithAddr` option. | ||
|
||
#### Sending events | ||
|
||
Event's can be sent using `client.Send(events []*raccoon.Event)`. The return signature of the `Send` method depends on the type of Client. | ||
|
||
| Type | Signature | | ||
| --- | --- | | ||
| `REST`, `gRPC` | `Send([]*raccoon.Event) (string, *raccoon.Response, error)` | | ||
| `Websocket` | `Send([]*raccoon.Event) (string, error)` | | ||
|
||
For `gRPC` and `REST` clients, the response is returned synchronously. For `Websocket` the responses are returned asynchronously via a channel returned by `EventAcks()`. | ||
|
||
`Event` structu has two fields: `Type` and `Data`. | ||
`Type` denotes the event type. This is used by raccoon to route the event to a specific topic downstream. `Data` field contains the payload. This data is serialised by the `serializer` that's configured on the client. The serializer can be configured by using the `WithSerializer()` option of the respective clients. | ||
|
||
The following table lists which serializer to use for a given payload type. | ||
|
||
| Message Type | Serializer | | ||
| --- | --- | | ||
| JSON | `Serializer.JSON` | | ||
| Protobuf | `Serializer.PROTO`| | ||
|
||
Once a client is constructed with a specific kind of serializer, you may only pass it events of that specific type. In particular, for `JSON` serialiser the event data must be a value that can be encoded by `json.Marshal`. While for `PROTOBUF` serialiser the event data must be a protobuf message. | ||
|
||
### Examples | ||
You can find examples of client usage over different protocols [here](https://github.com/raystack/raccoon/tree/main/clients/go/examples) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
# Java | ||
|
||
## Requirements | ||
Make sure you have Java JDK `>=8` and Gradle `>=7` installed on your system. See installation instructions for [openjdk](https://openjdk.org/install/) and [gradle](https://gradle.org/install/) for more information. | ||
## Installation | ||
|
||
In your `build.gradle` file add `io.odpf.raccoon` as a dependency. | ||
```groovy | ||
dependencies { | ||
implementation group: 'io.odpf', name: 'raccoon', version: '0.1.5-rc' | ||
} | ||
``` | ||
|
||
## Usage | ||
|
||
### Quickstart | ||
|
||
Below is a self contained example of Raccoon's Java client that uses the REST API to publish events | ||
```java title="App.java" showLineNumbers | ||
package org.example; | ||
|
||
import io.odpf.raccoon.client.RestConfig; | ||
import io.odpf.raccoon.client.RaccoonClient; | ||
import io.odpf.raccoon.client.RaccoonClientFactory; | ||
import io.odpf.raccoon.model.Event; | ||
import io.odpf.raccoon.model.Response; | ||
import io.odpf.raccoon.model.ResponseStatus; | ||
import io.odpf.raccoon.serializer.JsonSerializer; | ||
import io.odpf.raccoon.wire.ProtoWire; | ||
|
||
public class App { | ||
|
||
public static void main(String[] args) { | ||
RestConfig config = RestConfig.builder() | ||
.url("http://localhost:8080/api/v1/events") | ||
.header("x-user-id", "123") | ||
.serializer(new JsonSerializer()) // default is Json | ||
.marshaler(new ProtoWire()) // default is Json | ||
.retryMax(5) // default is 3 | ||
.retryWait(2000) // default is one second | ||
.build(); | ||
|
||
// get the rest client instance. | ||
RaccoonClient Client = RaccoonClientFactory.getRestClient(config); | ||
|
||
Response res = Client.send(new Event[]{ | ||
new Event("page", "EVENT".getBytes()) | ||
}); | ||
|
||
if (res.isSuccess() && res.getStatus() == ResponseStatus.STATUS_SUCCESS) { | ||
System.out.println("The event was sent successfully"); | ||
} | ||
} | ||
} | ||
|
||
``` | ||
|
||
### Guide | ||
|
||
#### Creating a client | ||
|
||
Raccoon's Java client only supports sending events over Raccoon's HTTP/JSON (REST) API. | ||
|
||
To create a client, you must pass the `io.odpf.raccoon.client.RestConfig` object to the client factory `io.odpf.raccoon.client.RaccoonClientFactory.getRestClient()`. | ||
|
||
You can use `RestConfig.builder()` as a convenient way of building the config object. | ||
|
||
Here's a minimal example of what it looks like: | ||
```java | ||
RestConfig config = RestConfig.builder() | ||
.url("http://localhost:8080/api/v1/events") | ||
.build(); | ||
RacconClient client = RaccoonClientFactory.getRestClient(config); | ||
``` | ||
|
||
#### Sending events | ||
|
||
Events can be sent to raccoon use `RestClient.send()` method. The `send()` methods accepts an array of `io.odpf.raccoon.model.Event` | ||
|
||
Here's a minimal example of what this could look like: | ||
```java | ||
Event[] events = new Event[]{ | ||
new Event("event_type", obj) | ||
}; | ||
client.send(events); | ||
``` | ||
|
||
Each event has a `type` and `data` field. `type` denotes the event type. This is used by raccoon to route the event to a specific topic downstream. `data` field contains the payload. This data is serialised by the `serializer` that's configured on the client. | ||
|
||
The following table lists which serializer to use for a given payload type. | ||
|
||
| Message Type | Serializer | | ||
| --- | --- | | ||
| JSON | `io.odpf.raccoon.serializer.JsonSerializer` | | ||
| Protobuf | `io.odpf.raccoon.serializer.ProtoSerializer`| | ||
|
||
Once a client is constructed with a specific kind of serializer, you may only pass it events of that specific type. In particular, for `JSON` serialiser the event data must be a Java object. While for `PROTOBUF` serialiser the event data must be a protobuf message object |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
# Javascript | ||
|
||
## Requirements | ||
Make sure that Nodejs >= `20.0` is installed on your system. See [installation instructions](https://nodejs.org/en/download/package-manager) on Nodejs's website for more info. | ||
|
||
## Installation | ||
Install Raccoon's Javascript client using npm | ||
```javascript | ||
$ npm install --save @raystack/raccoon | ||
``` | ||
## Usage | ||
|
||
### Quickstart | ||
|
||
Below is a self contained example of Raccoon's Javascript client that uses Raccoon's REST API to publish events. | ||
|
||
```javascript title="quickstart.js" showLineNumbers | ||
import { RaccoonClient, SerializationType, WireType } from '@raystack/raccoon'; | ||
|
||
const jsonEvents = [ | ||
{ | ||
type: 'test-topic1', | ||
data: { key1: 'value1', key2: ['a', 'b'] } | ||
}, | ||
{ | ||
type: 'test-topic2', | ||
data: { key1: 'value2', key2: { key3: 'value3', key4: 'value4' } } | ||
} | ||
]; | ||
|
||
const raccoonClient = new RaccoonClient({ | ||
serializationType: SerializationType.JSON, | ||
wireType: WireType.JSON, | ||
timeout: 5000, | ||
url: 'http://localhost:8080/api/v1/events', | ||
headers: { | ||
'X-User-ID': 'user-1' | ||
} | ||
}); | ||
|
||
raccoonClient | ||
.send(jsonEvents) | ||
.then((result) => { | ||
console.log('Result:', result); | ||
}) | ||
.catch((error) => { | ||
console.error('Error:', error); | ||
}); | ||
``` | ||
|
||
### Guide | ||
|
||
#### Creating a client | ||
Raccoon's Javascript client only supports sending event's over Raccoon's HTTP/JSON (REST) API. | ||
|
||
To create the client, use `new RaccoonClient(options)`. `options` is javascript object that contains the following properites: | ||
|
||
| Property | Description | | ||
| --- | --- | | ||
| url | (required) The base URL for the API requests | | ||
| serializationType | (required) The serialization type to use, either 'protobuf' or 'json' | | ||
| wireType | The wire configuration, containing ContentType (default: `wireType.JSON`)| | ||
| headers | Custom headers to be included in the HTTP requests (default: `{}`)| | ||
| retryMax | The maximum number of retry attempts for failed requests (default: `3`) | | ||
| retryWait | The time in milliseconds to wait between retry attempts (default: `1000`)| | ||
| timeout | The timeout in milliseconds (default: `1000`)| | ||
| logger | Logger object for logging (default: `global.console`) | ||
|
||
#### Publishing events | ||
To publish events, create an array of objects and pass it to `RaccoonClient#send()`. The return value is a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise). | ||
|
||
```js | ||
const events = [ | ||
{ | ||
type: "event_type", | ||
data: {}, | ||
} | ||
]; | ||
|
||
client.send(events) | ||
.then(result => console.log(result)) | ||
.catch(err => console.error(err)) | ||
``` | ||
|
||
`type` denotes the event type. This is used by raccoon to route the event to a specific topic downstream. `data` field contains the payload. This data is serialised by the `serializerType` that's configured on the client. | ||
|
||
The following table lists which serializer to use for a given payload type. | ||
|
||
| Message Type | Serializer | | ||
| --- | --- | | ||
| JSON | `SerializationType.JSON` | | ||
| Protobuf | `SerializationType.PROTOBUF`| | ||
|
||
Once a client is constructed with a specific kind of serializer, you may only pass it events of that specific type. In particular, for `JSON` serialiser the event data must be a javascript object. While for `PROTOBUF` serialiser the event data must be a protobuf message. | ||
|
||
## Examples | ||
You can find examples of client usage [here](https://github.com/raystack/raccoon/tree/main/clients/js/examples) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
# Overview | ||
|
||
## Introduction | ||
Raccoon provides a suite of client libraries designed to help developers easily send clickstream events to its low-latency, high-throughput event ingestion service. Whether you’re building real-time analytics, tracking user behavior, or processing large-scale event data, Raccoon's clients offer flexible and efficient integration via WebSocket, REST, and gRPC APIs. | ||
|
||
## Key Features | ||
|
||
- **Multi-Protocol Support**: WebSocket, REST, and gRPC are available in all clients, allowing you to choose the best fit for your application’s needs. | ||
- **Ease of Integration**: Designed with simplicity in mind, the clients integrate easily into existing projects with minimal configuration. | ||
- **Reliability**: Each client includes retry mechanisms and error handling to ensure events are delivered reliably, even in the face of transient failures. | ||
|
||
## Wire and Serialization Types | ||
|
||
A concept that exists in all the Client libraries is that of wire type and serialization type. | ||
|
||
Raccoon's API accepts both JSON and Protobuf requests. These are differentiated by the `Content-Type` header (in case of REST & gRPC protocols) and by `MessageType` for Websocket requests. | ||
|
||
`Wire` denotes what the request payload is serialised as. If wire type is `JSON` the request is sent as a JSON-encoded string. If it's `Protobuf` the request is the serialized bytes of [`SendEventRequest`](https://github.com/raystack/proton/blob/main/raystack/raccoon/v1beta1/raccoon.proto#L23) proto | ||
|
||
`Serialization` is how data in individual events is encoded. Just like wire type, it also supports `JSON` and `Protobuf` encoding. | ||
|
||
You may use any combination of wire and serialization type that suits your needs. | ||
|
||
## Getting Started | ||
|
||
To start using Raccoon's client libraries, check out the detailed installation and usage instructions for each supported language: | ||
|
||
- [Golang](clients/golang.md) | ||
- [Python](clients/python.md) | ||
- [Java](clients/java.md) | ||
- [JavaScript](clients/javascript.md) | ||
|
||
By leveraging Raccoon’s clients, you can focus on building your applications while Raccoon efficiently handles the ingestion of your clickstream events. |
Oops, something went wrong.