Skip to content

Commit

Permalink
feat: create GET endpoint to return events for an interest range (#276)
Browse files Browse the repository at this point in the history
* feat: add new GET route to retrieve event data for an interest range

I considered reusing the EventFeed response, but used something different to make the "resume" semantics clear. Feed supports the token in all cases, whereas the resume_offset is only "valid" (that is, useful) with the same parameters

* feat: write a basic test for new endpoint
  • Loading branch information
dav1do authored Feb 14, 2024
1 parent b3c1f69 commit a802e2a
Show file tree
Hide file tree
Showing 14 changed files with 934 additions and 38 deletions.
1 change: 1 addition & 0 deletions api-server/.openapi-generator/FILES
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ api/openapi.yaml
docs/Event.md
docs/EventDeprecated.md
docs/EventFeed.md
docs/EventsGet.md
docs/EventsPostRequest.md
docs/Version.md
docs/default_api.md
Expand Down
5 changes: 4 additions & 1 deletion api-server/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ To see how to make this your own, look here:
[README]((https://openapi-generator.tech))

- API version: 0.11.0
- Build date: 2024-02-12T14:25:37.570843794Z[Etc/UTC]
- Build date: 2024-02-14T13:01:15.078464-07:00[America/Denver]



Expand Down Expand Up @@ -63,6 +63,7 @@ To run a client, follow one of the following simple steps:

```
cargo run --example client EventsEventIdGet
cargo run --example client EventsSortKeySortValueGet
cargo run --example client FeedEventsGet
cargo run --example client InterestsSortKeySortValuePost
cargo run --example client LivenessGet
Expand Down Expand Up @@ -103,6 +104,7 @@ Method | HTTP request | Description
------------- | ------------- | -------------
[****](docs/default_api.md#) | **GET** /events/{event_id} | Get event data
[****](docs/default_api.md#) | **POST** /events | Creates a new event
[****](docs/default_api.md#) | **GET** /events/{sort_key}/{sort_value} | Get events matching the interest stored on the node
[****](docs/default_api.md#) | **GET** /feed/events | Get all new event keys since resume token
[****](docs/default_api.md#) | **POST** /interests/{sort_key}/{sort_value} | Register interest for a sort key
[****](docs/default_api.md#) | **GET** /liveness | Test the liveness of the Ceramic node
Expand All @@ -115,6 +117,7 @@ Method | HTTP request | Description
- [Event](docs/Event.md)
- [EventDeprecated](docs/EventDeprecated.md)
- [EventFeed](docs/EventFeed.md)
- [EventsGet](docs/EventsGet.md)
- [EventsPostRequest](docs/EventsPostRequest.md)
- [Version](docs/Version.md)

Expand Down
90 changes: 90 additions & 0 deletions api-server/api/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,66 @@ paths:
"204":
description: success
summary: Register interest for a sort key
/events/{sort_key}/{sort_value}:
get:
parameters:
- description: name of the sort_key e.g. 'model'
explode: false
in: path
name: sort_key
required: true
schema:
type: string
style: simple
- description: value associated with the sort key e.g. model ID
explode: false
in: path
name: sort_value
required: true
schema:
type: string
style: simple
- description: the controller to filter
explode: true
in: query
name: controller
required: false
schema:
type: string
style: form
- description: the stream to filter
explode: true
in: query
name: streamId
required: false
schema:
type: string
style: form
- description: "token that designates the point to resume from, that is find\
\ keys added after this point"
explode: true
in: query
name: offset
required: false
schema:
type: integer
style: form
- description: "the maximum number of events to return, default is 10000."
explode: true
in: query
name: limit
required: false
schema:
type: integer
style: form
responses:
"200":
content:
application/json:
schema:
$ref: '#/components/schemas/EventsGet'
description: success
summary: Get events matching the interest stored on the node
/feed/events:
get:
parameters:
Expand Down Expand Up @@ -289,6 +349,36 @@ components:
- resumeToken
title: Ceramic Event feed data
type: object
EventsGet:
description: Ceramic event keys as part of a Ceramic Stream
example:
resumeOffset: 0
events:
- data: data
id: id
- data: data
id: id
isComplete: true
properties:
events:
description: An array of events
items:
$ref: '#/components/schemas/Event'
type: array
resumeOffset:
description: An integer specifying where to resume the request. Only works
correctly for the same input parameters.
type: integer
isComplete:
description: A boolean specifying if there are more events to be fetched.
Repeat with the resumeOffset to get next set.
type: boolean
required:
- events
- isComplete
- resumeOffset
title: Information about multiple events.
type: object
_events_post_request:
description: "Event to add to the node. Temp while we transition to id/data\
\ style, at which time we can swap this out for the Event schema."
Expand Down
12 changes: 12 additions & 0 deletions api-server/docs/EventsGet.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# EventsGet

## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**events** | [**Vec<models::Event>**](Event.md) | An array of events |
**resume_offset** | **i32** | An integer specifying where to resume the request. Only works correctly for the same input parameters. |
**is_complete** | **bool** | A boolean specifying if there are more events to be fetched. Repeat with the resumeOffset to get next set. |

[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)


40 changes: 40 additions & 0 deletions api-server/docs/default_api.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Method | HTTP request | Description
------------- | ------------- | -------------
****](default_api.md#) | **GET** /events/{event_id} | Get event data
****](default_api.md#) | **POST** /events | Creates a new event
****](default_api.md#) | **GET** /events/{sort_key}/{sort_value} | Get events matching the interest stored on the node
****](default_api.md#) | **GET** /feed/events | Get all new event keys since resume token
****](default_api.md#) | **POST** /interests/{sort_key}/{sort_value} | Register interest for a sort key
****](default_api.md#) | **GET** /liveness | Test the liveness of the Ceramic node
Expand Down Expand Up @@ -63,6 +64,45 @@ No authorization required

[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)

# ****
> models::EventsGet (sort_key, sort_value, optional)
Get events matching the interest stored on the node

### Required Parameters

Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
**sort_key** | **String**| name of the sort_key e.g. 'model' |
**sort_value** | **String**| value associated with the sort key e.g. model ID |
**optional** | **map[string]interface{}** | optional parameters | nil if no parameters

### Optional Parameters
Optional parameters are passed through a map[string]interface{}.

Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
**sort_key** | **String**| name of the sort_key e.g. 'model' |
**sort_value** | **String**| value associated with the sort key e.g. model ID |
**controller** | **String**| the controller to filter |
**stream_id** | **String**| the stream to filter |
**offset** | **i32**| token that designates the point to resume from, that is find keys added after this point |
**limit** | **i32**| the maximum number of events to return, default is 10000. |

### Return type

[**models::EventsGet**](EventsGet.md)

### Authorization

No authorization required

### HTTP request headers

- **Content-Type**: Not defined
- **Accept**: application/json

[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)

# ****
> models::EventFeed (optional)
Get all new event keys since resume token
Expand Down
21 changes: 19 additions & 2 deletions api-server/examples/client/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
#[allow(unused_imports)]
use ceramic_api_server::{
models, Api, ApiNoContext, Client, ContextWrapperExt, EventsEventIdGetResponse,
EventsPostResponse, FeedEventsGetResponse, InterestsSortKeySortValuePostResponse,
LivenessGetResponse, SubscribeSortKeySortValueGetResponse, VersionPostResponse,
EventsPostResponse, EventsSortKeySortValueGetResponse, FeedEventsGetResponse,
InterestsSortKeySortValuePostResponse, LivenessGetResponse,
SubscribeSortKeySortValueGetResponse, VersionPostResponse,
};
use clap::{App, Arg};
#[allow(unused_imports)]
Expand Down Expand Up @@ -35,6 +36,7 @@ fn main() {
.help("Sets the operation to run")
.possible_values(&[
"EventsEventIdGet",
"EventsSortKeySortValueGet",
"FeedEventsGet",
"InterestsSortKeySortValuePost",
"LivenessGet",
Expand Down Expand Up @@ -111,6 +113,21 @@ fn main() {
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
},
*/
Some("EventsSortKeySortValueGet") => {
let result = rt.block_on(client.events_sort_key_sort_value_get(
"sort_key_example".to_string(),
"sort_value_example".to_string(),
Some("controller_example".to_string()),
Some("stream_id_example".to_string()),
Some(56),
Some(56),
));
info!(
"{:?} (X-Span-ID: {:?})",
result,
(client.context() as &dyn Has<XSpanIdString>).get().clone()
);
}
Some("FeedEventsGet") => {
let result = rt
.block_on(client.feed_events_get(Some("resume_at_example".to_string()), Some(56)));
Expand Down
19 changes: 17 additions & 2 deletions api-server/examples/server/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,8 @@ impl<C> Server<C> {

use ceramic_api_server::server::MakeService;
use ceramic_api_server::{
Api, EventsEventIdGetResponse, EventsPostResponse, FeedEventsGetResponse,
InterestsSortKeySortValuePostResponse, LivenessGetResponse,
Api, EventsEventIdGetResponse, EventsPostResponse, EventsSortKeySortValueGetResponse,
FeedEventsGetResponse, InterestsSortKeySortValuePostResponse, LivenessGetResponse,
SubscribeSortKeySortValueGetResponse, VersionPostResponse,
};
use std::error::Error;
Expand Down Expand Up @@ -141,6 +141,21 @@ where
Err(ApiError("Generic failure".into()))
}

/// Get events matching the interest stored on the node
async fn events_sort_key_sort_value_get(
&self,
sort_key: String,
sort_value: String,
controller: Option<String>,
stream_id: Option<String>,
offset: Option<i32>,
limit: Option<i32>,
context: &C,
) -> Result<EventsSortKeySortValueGetResponse, ApiError> {
info!("events_sort_key_sort_value_get(\"{}\", \"{}\", {:?}, {:?}, {:?}, {:?}) - X-Span-ID: {:?}", sort_key, sort_value, controller, stream_id, offset, limit, context.get().0.clone());
Err(ApiError("Generic failure".into()))
}

/// Get all new event keys since resume token
async fn feed_events_get(
&self,
Expand Down
Loading

0 comments on commit a802e2a

Please sign in to comment.