resgateio / resgate

A Realtime API Gateway used with NATS to build REST, real time, and RPC APIs, where all your clients are synchronized seamlessly.
https://resgate.io
MIT License
685 stars 67 forks source link

Add resource ID in delete event #208

Closed jurgisk closed 2 years ago

jurgisk commented 2 years ago

Hi. First, thanks for the work you've done, I'm really impressed with resgate performance. So well done. But I wanted a little improvement. Would it be possible to have a RID of the item that gets deleted in the event that get's sent when item is deleted from collection. Here's how an actual event looks like: {"event":"environments.outputs.80.remove","data":{"idx":2}}

And I would like to have tool like this: {"event":"environments.outputs.80.remove","data":{"idx":2, "rid": "environments.outputs.80.output.20"}}

In this example: "environments.outputs.80" is the collection of items "environments.outputs.80.output.20" is the individual item in the collection that gets deleted.

Essentially having the resource id that's being deleted in the event would make it super clear for tracking items that are deleted without having to calculate what the element position in the list is (as in my case the positions change quite frequently).

Many thanks, Jurgis

jirenius commented 2 years ago

Hi @jurgisk !

Glad it is working well for you. Yes, it does perform quite well for us well :)

Unfortunately, no. That is not possible for more than one reason - such as collections possibly containing other types of values, and that collections are allowed to contain the same values on multiple index positions.

What you suggest was actually part of an early draft of the RES protocol, but was scrapped due to such reasons mentioned above.

But there is another solution that I would recommend: If your collection contains items where sort order is either 1) not important, or 2) may be derived from the item info, you can instead use a model. Let's show with an example.

Example

Let's assume your output model is something that looks like this:

Model: environments.outputs.$groupId.output.$outputId

{
    "outputId": 20,
    "groupId": 80,
    "name": "Twenty",
    "timestamp": 1000
}

And then you have your collection, maybe sorted by timestamp:

Collection: environments.outputs.$groupId

[
    { "rid": "environments.outputs.80.output.20" },
    { "rid": "environments.outputs.80.output.12" },
    { "rid": "environments.outputs.80.output.42" }
]

Since the timestamp, by which the items are sorted, is included in the output model itself, we actually don't need the order within the collection. So, instead of a collection, we could turn it into a model, where each model key is the output item's ID:

Model : environments.outputs.$groupId (same resource as above, but as a model)

{
    "20": { "rid": "environments.outputs.80.output.20" },
    "12": { "rid": "environments.outputs.80.output.12" },
    "42": { "rid": "environments.outputs.80.output.42" }
}

Now, by doing that, I no longer have to care about the index (idx), since models don't have that - instead they have keys. When I want to delete/remove an item, I can just do a change event where I set the value of the key to delete to a delete action object:

event.environments.outputs.80.change:

{
    "values": {
        "20": { "action": "delete" }
    }
}

And adding values are also done with change events:

event.environments.outputs.80.change:

{
    "values": {
        "53": { "rid": "environments.outputs.80.output.53" }
    }
}

Hopefully that may be a solution for you :)

/Samuel

jurgisk commented 2 years ago

Hi Samuel! I really like this solution. I did get around the issue by making a restful api call to get the list of current items in the collection and from there I deduct which items are deleted. But this is way more elegant. Thank you very much for getting back to me on this, really appreciate this.

Many thanks, Jurgis