I've recently spent some more time thinking about the response format and I think the results should be inside a list called data again. This essentially turns it back into the GraphSONv3 ResponseMessage. So "result" would be an object that contains an array called "data". It might be useful to do this just in case there is some metadata that needs to be added to the response.
On Tue, May 7, 2024 at 1:59 PM Ken Hu <kenhu...@gmail.com> wrote: > Another update is that for GraphSONv4, the result field will no longer be > null if there are no results instead it will become an empty array. This > means that the new ResponseResult always expects a List<Object> rather than > just an Object. > > Are there any concerns about changing it from being null to an empty array? > > On Wed, Apr 24, 2024 at 1:30 PM Ken Hu <kenhu...@gmail.com> wrote: > >> An update regarding the API, the materializeProperties option is being >> added back which should be set to either "all" or "tokens". The "all" >> option returns all the properties while the "tokens" option returns only >> the id and label. So the request syntax currently looks like: >> >> ---------- Request Syntax ---------- >> >> POST /gremlin HTTP/1.1 >> Accept: <<mimetype>> >> Content-Type: <<mimetype>> >> Gremlin-Hints: <<hints>> >> >> { >> "gremlin": "string", >> "timeoutMs": number, >> "materializeProperties": "string", >> "bindings": object, >> "g": "string" >> "language" : "string" >> } >> >> Additionally, there seems to be a difference between options needed to >> change server behavior (timeoutMs, materializeProperties) and options >> needed to change the behavior of the Traversal. Currently, we allow these >> server options to be set using the with() options. I think it makes sense >> for these to only be set in the HTTP request body as it isn't information >> needed by the traversal. This leads to a better separation of options that >> affect both all traversals (embedded and remote) and options that are >> server/remote only. This means that we would drop the GremlinScriptChecker >> from the server that is used for parsing through a script for specific >> with() options that the server needs. However, a user may need to set >> specific options per query so we could add a GLV-only step like request(). >> The request() step wouldn't be part of the language and would be something >> that only the GLVs would recognize and would cause them to add those >> options to the HTTP request body. It should be noted that request() is a >> working idea, but for now, the most important point is that there will be a >> way to set these server options per request from the GLVs. >> >> On Wed, Apr 10, 2024 at 12:45 PM Ken Hu <kenhu...@gmail.com> wrote: >> >>> Hi, >>> >>> The following is a reference of what the upcoming HTTP API will look >>> like for the /gremlin resource. Some smaller items are probably subject to >>> change. >>> >>> There are three differences between the 4.x HTTP API and the 3.x HTTP >>> API that should be noted. First, the server always generates the requestId >>> and returns it to the client. Second, the format of the request body has >>> changed as the OpProcessors have been removed so the request fields have >>> been flattened. Third, because the results are now streamed back to the >>> user with chunked transfer encoding, there are certain errors that can >>> occur after the initial 200 OK has been sent. This means that the user must >>> check either the status object in the response body or the trailers to see >>> if there are any errors. >>> >>> The format below uses a bit of pseudo-JSON to help represent request and >>> response bodies. The actual format of the request and response bodies will >>> be determined by the serializers defined via the "Accept" and >>> "Content-Type" headers. As a result, a generic type definition in this >>> document like "number" could translate to a "long" for a serializer that >>> supports types like GraphBinary. >>> >>> >>> ---------- Request Syntax ---------- >>> >>> POST /gremlin HTTP/1.1 >>> Accept: <<mimetype>> >>> Content-Type: <<mimetype>> >>> Gremlin-Hints: <<hints>> >>> >>> { >>> "gremlin": "string", >>> "timeoutMs": number, >>> "bindings": object, >>> "g": "string" >>> "language" : "string" >>> } >>> >>> >>> ---------- Headers ---------- >>> >>> Gremlin-Hints - When provided this header is a semi-colon separated list >>> of key/value >>> pair metadata that could be helpful to the server in >>> processing a >>> particular request in some way. >>> Required: No >>> >>> ---------- Header Options ---------- >>> >>> mimetype - the serialization accepted for the response. >>> Required: No. Defaults to >>> "application/vnd.gremlin-v4.0+json;types=false" >>> >>> application/vnd.gremlin-v4.0+json;types=false >>> GraphSON without embedded types that will be easy to parse and >>> work with using >>> cURL and similar tools. >>> >>> application/vnd.gremlin-v4.0+json;types=true >>> GraphSON with embedded types, mostly present for consistency, so >>> that both >>> configurations of GraphSON are available. Note that official >>> TinkerPop drivers >>> will not support this serializer. >>> >>> application/vnd.graphbinary-v4.0 >>> GraphBinary which has embedded types, mostly of use to Gremlin >>> Language Drivers. >>> >>> hints >>> mutations - Indicates if the Gremlin contains steps that can mutate >>> the graph. The >>> default would be "unknown". Language drivers would set >>> this hint >>> automatically at query submission by dynamically >>> detecting mutating >>> steps in the query being sent. >>> yes | no | unknown >>> >>> >>> ---------- Request Body ---------- >>> >>> gremlin - The Gremlin query to execute. >>> Type: String >>> Required: Yes. >>> >>> timeoutMs - The maximum time a query is allowed to execute in >>> milliseconds. >>> Type: Number >>> Required: No. If not present, then server default is used. >>> >>> bindings - Any bindings used to execute the query. For example, the >>> incoming Gremlin script might >>> be g.V(x) where x=1 is a binding that would be applied to it. >>> Type: object >>> Required: No. >>> >>> g - The name of the graph traversal source to which the query applies. >>> Type: String >>> Required: No, defaults to "g" >>> >>> language - The name of the ScriptEngine to use to parse the gremlin >>> query. >>> Type: String >>> Required: No, defaults to "gremlin-lang" >>> >>> >>> ---------- Response Syntax ---------- >>> >>> HTTP/1.1 200 >>> Content-type: <<mimetype>> >>> Transfer-Encoding: chunked >>> Gremlin-RequestId: uuid >>> { >>> "result": list, >>> "status": object >>> } >>> >>> ---------- Headers ---------- >>> >>> Gremlin-RequestId - A UUID to identify this request, which can be used >>> to help trace the request on the server in logs and such. >>> Type: uuid >>> >>> >>> ---------- Response Elements ---------- >>> result - A list of objects that represent the result of the query. >>> Single objects are >>> coerced to list. >>> Type: list >>> >>> status - The actual status of the request after its been fully executed. >>> Type: object >>> >>> >>> ---------- Example Responses ---------- >>> >>> An example "result", in this case a single graph element, looks like the >>> following: >>> >>> // g.V().limit(1) >>> >>> [ >>> { >>> "id": "string" >>> "label": "string" >>> "type": "string" >>> "properties": object >>> } >>> ] >>> >>> An example "status", which comes at the very end of the response looks >>> like the following: >>> { >>> code: "string" >>> message: "string" >>> exception: "string" >>> } >>> >>> A concrete example would be: >>> { >>> "code": "400" >>> "message": "An eval requires a gremlin argument" >>> "exception": "InvalidRequestException" >>> } >>> >>> The trailers will have the following format: >>> >>> Status: "number" >>> Exception: "string" >>> >>> The status corresponds to the real status code and the exception is an >>> exception class returned by the server. For example, >>> >>> Status: 429 >>> Exception: TooManyRequestsException >>> >>> >>> >>> Are there any modifications or updates that you think would be >>> appropriate? >>> >>> Thanks, >>> Ken >>> >>>