arangodb erlang数据库驱动
Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

286 Zeilen
8.6 KiB

vor 4 Jahren
  1. Client / Server Communication (VST 1.1)
  2. =======================================
  3. Version 1.1.0 of 23 November 2016
  4. HTTP
  5. ----
  6. Use VelocyPack as body. Content-Type is `"application/vpack"`
  7. Binary Protocol
  8. ---------------
  9. This is not a request / response protocol. It is symmetric (in
  10. principle). Messages can be sent back and forth, pipelined, multiplexed,
  11. uni-directional or bi-directional.
  12. It is possible that a message generates
  13. - no response
  14. - exactly one response
  15. - multiple responses
  16. The VelocyStream does **not** impose or specify or require one of the
  17. above behaviors. The application must define a behavior in general or on
  18. a per-request basis, see below. The server and client must then
  19. implement that behavior.
  20. ### Message vs. Chunk
  21. The consumer (client or server) will deal with messages. A message
  22. consists of one or more VelocyPacks (or in some cases of certain parts
  23. of binary data). How many VelocyPacks are part of a message is
  24. completely application dependent, see below for ArangoDB.
  25. It is possible that the messages are very large. As messages can be
  26. multiplexed over one connection, large messages need to be split into
  27. chunks. The sender/receiver class will accept a vector of VelocyPacks,
  28. split them into chunks, send these chunks over the wire, assemble these
  29. chunks, generates a vector of VelocyPacks and passes this to the
  30. consumer.
  31. ### Chunks
  32. In order to allow reassemble chunks, each package is prefixed by a small
  33. header. A chunk is always at least 24 bytes long. The byte order is
  34. ALWAYS little endian. The format of a chunk is the following, regardless
  35. on whether it is the first in a message or a subsequent one:
  36. | name | type | description |
  37. | --------------- | ------------------------- | --- |
  38. | length | uint32\_t | total length in bytes of the current chunk, including this header |
  39. | chunkX | uint32\_t | chunk/isFirstChunk (upper 31bits/lowest bit), details see below |
  40. | messageId | uint64\_t | a unique identifier, it is the responsibility of the sender to generate such an identifier (zero is reserved for not set ID) |
  41. | messageLength | uint64\_t | the total size of the message. |
  42. | Binary data | binary data blob | size b1 |
  43. Clarification: "chunk" and "isFirstChunk" are combined into an unsigned
  44. 32bit value. Therefore it will be encoded as
  45. uint32_t chunkX
  46. and extracted as
  47. chunk = chunkX >> 1
  48. isFirstChunk = chunkX & 0x1
  49. For the first chunk of a message, the low bit of the second uint32\_t is
  50. set, for all subsequent ones it is reset. In the first chunk of a
  51. message, the number "chunk" is the total number of chunks in the
  52. message, in all subsequent chunks, the number "chunk" is the current
  53. number of this chunk.
  54. The total size of the data package is (24 + b1) bytes. This number is
  55. stored in the length field. If one needs to send messages larger than
  56. UINT32\_MAX, then these messages must be chunked. In general it is a
  57. good idea to restrict the maximal size to a few megabytes.
  58. **Notes:**
  59. When sending a (small) message, it is important (for performance reasons)
  60. to ensure that only one TCP
  61. packet is sent. For example, by using sendmmsg under Linux
  62. ([*https://blog.cloudflare.com/how-to-receive-a-million-packets/*](https://blog.cloudflare.com/how-to-receive-a-million-packets/))
  63. Implementors should nevertheless be aware that in TCP/IP one cannot
  64. enforce this and so implementations must always be aware that some part
  65. of the network stack can split packets and the payload might arrive in
  66. multiple parts!
  67. ArangoDB
  68. ========
  69. ### Request / Response
  70. For an ArangoDB client, the request is of the following format, the
  71. array is a VelocyPack array:
  72. [
  73. /* 0 - version: */ 1, // [int]
  74. /* 1 - type: */ 1, // [int] 1=Req, 2=Res,..
  75. /* 2 - database: */ "test", // [string]
  76. /* 3 - requestType: */ 1, // [int] 0=Delete, ...
  77. /* 4 - request: */ "/_api/collection", // [string\]
  78. /* 5 - parameter: */ { force: true }, // [[string]->[string]]
  79. /* 6 - meta: */ { x-arangodb: true } // [[string]->[string]]
  80. ]
  81. Body (binary data)
  82. If database is missing (entry is `null`), then "\_system" is assumed.
  83. `type`:
  84. 1 = Request
  85. 2 = Response (final response for this message id)
  86. 3 = Response (but at least one more response will follow)
  87. 1000 = Authentication
  88. `requestType`:
  89. 0 = DELETE
  90. 1 = GET
  91. 2 = POST
  92. 3 = PUT
  93. 4 = HEAD (not used in VPP)
  94. 5 = PATCH
  95. 6 = OPTIONS (not used in VPP)
  96. For example:
  97. The HTTP request
  98. http://localhost:8529/_db/test/_admin/echo?a=1&b=2&c[]=1&c[]=3
  99. With header:
  100. X-ArangoDB-Async: true
  101. is equivalent to
  102. [
  103. 1, // version
  104. 1, // type
  105. "test", // database
  106. 1, // requestType GET
  107. "/_admin/echo", // request path
  108. { // parameters
  109. a: 1,
  110. b: 2,
  111. c: [ 1, 3 ]
  112. },
  113. { // meta
  114. x-arangodb-async: true
  115. }
  116. ]
  117. The request is a message beginning with one VelocyPack. This VelocyPack
  118. always contains the header fields, parameters and request path. If the
  119. meta field does not contain a content type, then the default
  120. `"application/vpack"` is assumed and the body will be one or multiple
  121. VelocyPack object.
  122. The response will be
  123. [
  124. 1, // 0 - version
  125. 2 or 3, // 1 - type
  126. 400, // 2 - responseCode
  127. { etag: "1234" } // 3 - meta: [[str]->[str]]
  128. ]
  129. Body (binary data)
  130. Request can be pipelined or mixed. The responses are mapped using the
  131. "messageId" in the header. It is the responsibility of the **sender** to
  132. generate suitable "messageId" values.
  133. The default content-type is `"application/vpack"`.
  134. ### Authentication
  135. A connection can be authenticated with the following message:
  136. [
  137. 1, // version
  138. 1000, // type
  139. "plain", // encryption
  140. "admin", // user
  141. "plaintext", // password
  142. ]
  143. or
  144. [
  145. 1, // version
  146. 1000, // type
  147. "jwt", // encryption
  148. "abcd..." // token
  149. ]
  150. The response is
  151. { "error": false }
  152. if successful or
  153. {
  154. "error": true,
  155. "errorMessage": "MESSAGE",
  156. "errorCode": CODE
  157. }
  158. if not successful, and in this case the connection is closed by the server.
  159. One can acquire a JWT token in the same way as with HTTP using the
  160. open, unauthenticated route `/_open/auth` with the same semantics as
  161. in the HTTP version. In this way, the complete authentication can be
  162. done in a single session via JWT.
  163. ### Content-Type and Accept
  164. In general the content-type will be VPP, that is the body is an object
  165. stored as VelocyPack.
  166. Sometimes it is necessary to respond with unstructured data, like text,
  167. css or html. The body will be a VelocyPack object containing just a
  168. binary attribute and the content-type will be set accordingly.
  169. The rules are as follows.
  170. #### Http
  171. Request: Content-Type
  172. - `"application/json"`: the body contains the JSON string representation
  173. - `"application/vpack"`: the body contains a velocy pack
  174. There are some handler that allow lists of JSON (seperared by newline).
  175. In this case we also allow multiple velocy packs without any separator.
  176. Request: Accept
  177. - `"application/json"`: send a JSON string representation in the body,
  178. if possible
  179. - `"application/vpack"`: send velocy pack in the body, if possible
  180. If the request asked for `"application/json"` or `"application/vpack"` and
  181. the handler produces something else (i.e. `"application/html"`), then the
  182. accept is ignored.
  183. If the request asked `"application/json"` and the handler produces
  184. `"application/vpack"`, then the VPACK is converted into JSON.
  185. If the request asked `"application/vpack"` and the handler produces
  186. "application/json", then the JSON is converted into VPACK.
  187. #### VPP
  188. Similar to HTTP with the exception: the "Accept" header is not supported
  189. and `"application/json"` will always be converted into
  190. "application/vpack". This means that the body contains one or more
  191. velocy-packs. In general it will contain one - notable exception being
  192. the import.
  193. If the handler produces something else (i.e. `"application/html"`), then
  194. The body will be a binary blob (instead of a velocy-pack) and the
  195. content-type will be set accordingly.
  196. The first bytes sent after a connection (the "client" side - even if the
  197. program is bi-directional, there is a server listening to a port and a
  198. client connecting to a port) are
  199. VST/1.1\r\n\r\n
  200. (11 Bytes)