An implementation of the Spine web
is an API based on the Firebase Realtime Database.
This module provides
the FirebaseQueryServlet
which extends the QueryServlet
. Subtype this class in order to use the Firebase client transport.
The servlet handles POST
query requests. The Query
is parsed from the request body and
dispatched to the QueryService
.
The query response is written into a location in the Firebase Realtime Database. Each entity is represented via a node with a string value. The value is the message JSON representation.
The HTTP response is the path to the parent node which contains all the responses.
Note that the query response messages are appended to the response one-by-one, in an asynchronous manner, i.e. when the client receives the HTTP response, the query response may still not be ready.
The client should subscribe to the child added event of the node, denoted by resulting path.
Let's assume there is a projection User
with following state:
message User {
string name = 1;
}
A client forms a query for all the users whose name is "Martin":
final Query query = requestFactory.query().select(User.class)
.where(eq("name", "Martin"))
.build();
The query is then transformed into a JSON and sent to the server in a POST
request.
{
"id": { ... },
"target": {
"@type": "example.org/example.User",
"filters": {
"filter": [
{
"operator": "ALL",
"filter": [
{
"column_name": "name",
"value": {
"@type": "type.googleapis.com/google.protobuf.StringValue",
"value": "Martin"
},
"operator": "EQUAL"
}
]
}
]
}
},
"context": { ... }
}
This JSON is parsed back into the Query
message by the QueryServlet
and sent to
the QueryService
for an asynchronous processing.
Alternatively, the Query
may be represented as a Base64-encoded byte string.
See HttpMessages
for more info.
The response path is generated basing on the Query
. Assume that the path is foo/bar
.
Then the servlet response contains the literal string foo/bar
without any additional info.
When the client receives the response, it should subscribe to the child events of foo/bar
. Each
matching entity is written into a separate child of that node.
The DB fragment should look as follows:
"foo/bar": {
"123": "{...}",
"456": "{...}",
"789": "{...}"
}
Each child represents a queried entity. The value of a child node is a string JSON representation of
an example.User
.
Do not assume the keys as they are generated by the Firebase DB itself.