1

Abstract

I'm working on a REST interface to a graph database (Titan/Gremlin-Server, but this shouldn't matter) that has a strong sense of type for vertices and edges. I'd like to design a REST API to perform CRUD operations while enforcing some type information.

Overview

The purpose of this database is to model the flow of information (a unit of which is called a message) across various actors, keeping track of the channels that mediate message routing. For instance, it can be said that a YouTuber (type: actor) produces a Video (type: message) and distributes it via a YouTube Channel (type: channel), to which another YouTuber (type: actor) is subscribed.

The data model is as follows with vertices represented as boxes and edges represented as arrows:

                              publish
|***************| ---------------------------------> |*******************|
|               |                                    |                   |
|               |  produce   |*********|  distribute |                   |
|    Actor      | ---------> |         | ----------> |      Channel      |
|               |            | Message |             |                   |
|               | <--------- |         | <---------- |                   |
|               |  notify    |*********|   deliver   |                   |
|               |                                    |                   |
|***************| <--------------------------------- |*******************|
                              subscribe

To help with understanding, it is said that:

  • An actor publishes to a channel
  • An actor produces a message
  • A message notifies an actor (inversely stated: an actor is notified of a message)
  • A message is distributed via a channel
  • A channel delivers a message (inversely stated: a message is delivered by a channel)
  • An channel subscribes an actor (inversely stated: an actor is subscribed to a channel)

Notice how the types of the vertices in any edge-creation operation, createE(v1, v2), determines the type of edge that is created. For instance, an edge from an Actor to a Message is necessarily a produce edge. Likewise, an edge from Channel to Actor is necessarily a subscribe edge.

N.B.: Vertices in this model constitute (I think...) a mathematical category. We can think of edges as functions that map one category to another. For example, the function that takes us from an Actor to a Channel is called publish, and is equivalent to distribute ∘ produce. I mention this because I had these principles in mind when designing the data model ... perhaps they can be leveraged for a REST API?

Problem Statement

Given the above data model, I need to create a REST API that supports basic CRUD operations for both vertices and edges. At a minimum, the API should:

  1. Operate on both individual resources and collections
  2. Provide a mechanism for constraining the vertices/edges on which a given API call operates (an informal and non-exhaustive example: "I want to create an edge going from the vertex with UUID 5F1506A2-4824-416D-95F2-BC2D82B15A29 to all vertices created in the last hour)
  3. Infer the type of edge to be created based on the source and destination vertex types, with the intent of validating user-supplied data (i.e.: createE(some_actor, some_message) should implicitly create a produce-type edge).

Current approach

One of the nicer properties of this data model is that edge type is fully-determined by the vertices at each end, and inversely, a pair of vertices can be typed based on an edge's type and direction. This makes it possible to do things like:

POST /:srcV/:dstV
{ edge JSON data goes here }

In doing so, we can validate the contents of the edge JSON data, ensuring that it corresponds to the type of edge implicitly created. For clarity, :srcV and :dstV are variables that will contain AGENT, MESSAGE or CHANNEL.

However, a few things are missing:

  1. how do I represent constraints
  2. how should constraints be transmitted over HTTP (query params?)
  3. how do I distinguish between resources and collections of resources?

Question 2 is of particular relevance because I want to be able to DELETE a collection of resources based on constraints. For instance, "remove all edges of type publish for which the actor is subscribed to a given channel".

This is my first time doing non-trivial work with REST, and it feels like I'm shoehorning this data-model into something that might not necessarily fit. Therefore, my question is twofold:

  1. Can someone point me in the right direction? Any ideas on what this API should look like?
  2. Any comments, suggestions or criticisms?

My understanding is that softwareengineering.stackexchange is for doing "whiteboarding" of sorts, so I hope the community will forgive the open-ended nature of this question. If it needs to be narrowed down, please guide me with questions and I'll update accordingly.

Many thanks in advance!

Additional notes

  1. It's possible (perhaps even likely) that my vertex/edge nomenclature leads to confusion. I'm open to suggestions.

  2. Some of my assumptions (particularly with respect to category theory) may be misguided or flat-out wrong. Corrections and friendly inquisitions are welcome!

7
  • for a generic Java Graph implementation check my repo. github.com/MatheusArleson/Graphs/blob/master/src/main/java/br/… The Class of the Nodes and Edges can be modeled by you. The class of the Edges must know how to connect the Nodes. Commented Feb 16, 2017 at 14:07
  • 1
    @linuxunil Forgive me, I don't see how this is relevant. My problem isn't in creating a graph per se, but rather in representing CRUD operations on the graph in a RESTful manner. Commented Feb 16, 2017 at 14:09
  • i see. About that, you are mixing two concepts. REST vs RPC. this link gives a good view about the two approaches. apihandyman.io/do-you-really-know-why-you-prefer-rest-over-rpc Commented Feb 16, 2017 at 14:16
  • 1
    Could you please elaborate on where exactly am I mixing REST and RPC? If you're referring to my discussion of functions, please note that I'm not (consciously, at least) trying to issue function calls via REST. I'm trying to describe something that could be modeled as a function call via REST. (That said, I may have crossed the streams somewhere... if I have, please do point it out!) Commented Feb 16, 2017 at 14:18
  • 1
    @linuxunil I'm sorry, I don't see how JCR is related to my problem. Again, my content is already stored as a graph. Moreover, your solutions appear to be Java-centric and I am not developing in Java. My question instead relates to RESTful CRUD of graphical data. As for REST, you most certainly can delete resources or collections (see: restapitutorial.com/lessons/httpmethods.html). Not all REST methods are idempotent (e.g. POST). With respect, we may be talking past each other, but I'm truly struggling to understand how your suggestions are even remotely pertinent. Commented Feb 16, 2017 at 14:27

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.