req.ezdoc 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. ::: The Req object
  2. The Req object is this variable that you will use to obtain
  3. information about a request, read the body of the request
  4. and send a response.
  5. :: A special variable
  6. While we call it an "object", it is not an object in the
  7. OOP sense of the term. In fact it is completely opaque
  8. to you and the only way you can perform operations using
  9. it is by calling the functions from the `cowboy_req`
  10. module.
  11. Almost all the calls to the `cowboy_req` module will
  12. return an updated request object. Just like you would
  13. keep the updated `State` variable in a gen_server,
  14. you MUST keep the updated `Req` variable in a Cowboy
  15. handler. Cowboy will use this object to know whether
  16. a response has been sent when the handler has finished
  17. executing.
  18. The Req object allows accessing both immutable and
  19. mutable state. This means that calling some of the
  20. functions twice will not produce the same result.
  21. For example, when streaming the request body, the
  22. function will return the body by chunks, one at a
  23. time, until there is none left.
  24. :: Overview of the cowboy_req interface
  25. With the exception of functions manipulating the request
  26. body, all functions return a single value. Depending on
  27. the function this can be the requested value (method,
  28. host, path, ...), a boolean (has_body, has_resp_header...)
  29. a new Req object (set_resp_body, set_resp_header...), or
  30. simply the atom `ok` (chunk, continue, ...).
  31. The request body reading functions may return `{Result, Req}`
  32. or `{Result, Value, Req}`. The functions in this category
  33. are `body/{1,2}`, `body_qs/{1,2}`, `part/{1,2}`, `part_body/{1,2}`.
  34. This chapter covers the access functions mainly. Cookies,
  35. request body and response functions are covered in their
  36. own chapters.
  37. :: Request
  38. When a client performs a request, it first sends a few required
  39. values. They are sent differently depending on the protocol
  40. being used, but the intent is the same. They indicate to the
  41. server the type of action it wants to do and how to locate
  42. the resource to perform it on.
  43. The method identifies the action. Standard methods include
  44. GET, HEAD, OPTIONS, PATCH, POST, PUT, DELETE. Method names
  45. are case sensitive.
  46. ``` erlang
  47. Method = cowboy_req:method(Req).
  48. ```
  49. The host, port and path parts of the URL identify the resource
  50. being accessed. The host and port information may not be
  51. available if the client uses HTTP/1.0.
  52. ``` erlang
  53. Host = cowboy_req:host(Req),
  54. Port = cowboy_req:port(Req),
  55. Path = cowboy_req:path(Req).
  56. ```
  57. The version used by the client can of course also be obtained.
  58. ``` erlang
  59. Version = cowboy_req:version(Req).
  60. ```
  61. Do note however that clients claiming to implement one version
  62. of the protocol does not mean they implement it fully, or even
  63. properly.
  64. :: Bindings
  65. After routing the request, bindings are available. Bindings
  66. are these parts of the host or path that you chose to extract
  67. when defining the routes of your application.
  68. You can fetch a single binding. The value will be `undefined`
  69. if the binding doesn't exist.
  70. ``` erlang
  71. Binding = cowboy_req:binding(my_binding, Req).
  72. ```
  73. If you need a different value when the binding doesn't exist,
  74. you can change the default.
  75. ``` erlang
  76. Binding = cowboy_req:binding(my_binding, Req, 42).
  77. ```
  78. You can also obtain all bindings in one call. They will be
  79. returned as a list of key/value tuples.
  80. ``` erlang
  81. AllBindings = cowboy_req:bindings(Req).
  82. ```
  83. If you used `...` at the beginning of the route's pattern
  84. for the host, you can retrieve the matched part of the host.
  85. The value will be `undefined` otherwise.
  86. ``` erlang
  87. HostInfo = cowboy_req:host_info(Req).
  88. ```
  89. Similarly, if you used `...` at the end of the route's
  90. pattern for the path, you can retrieve the matched part,
  91. or get `undefined` otherwise.
  92. ``` erlang
  93. PathInfo = cowboy_req:path_info(Req).
  94. ```
  95. :: Query string
  96. The raw query string can be obtained directly.
  97. ``` erlang
  98. Qs = cowboy_req:qs(Req).
  99. ```
  100. You can parse the query string and then use standard library
  101. functions to access individual values.
  102. ``` erlang
  103. QsVals = cowboy_req:parse_qs(Req),
  104. {_, Lang} = lists:keyfind(<<"lang">>, 1, QsVals).
  105. ```
  106. You can match the query string into a map.
  107. ``` erlang
  108. #{id := ID, lang := Lang} = cowboy_req:match_qs(Req, [id, lang]).
  109. ```
  110. You can use constraints to validate the values while matching
  111. them. The following snippet will crash if the `id` value is
  112. not an integer number or if the `lang` value is empty. Additionally
  113. the `id` value will be converted to an integer term, saving
  114. you a conversion step.
  115. ``` erlang
  116. QsMap = cowboy_req:match_qs(Req, [{id, int}, {lang, nonempty}]).
  117. ```
  118. Note that in the case of duplicate query string keys, the map
  119. value will become a list of the different values.
  120. Read more about ^constraints^.
  121. A default value can be provided. The default will be used
  122. if the `lang` key is not found. It will not be used if
  123. the key is found but has an empty value.
  124. ``` erlang
  125. #{lang := Lang} = cowboy_req:match_qs(Req, [{lang, [], <<"en-US">>}]).
  126. ```
  127. If no default is provided and the value is missing, the
  128. query string is deemed invalid and the process will crash.
  129. :: Request URL
  130. You can reconstruct the full URL of the resource.
  131. ``` erlang
  132. URL = cowboy_req:url(Req).
  133. ```
  134. You can also obtain only the base of the URL, excluding the
  135. path and query string.
  136. ``` erlang
  137. BaseURL = cowboy_req:host_url(Req).
  138. ```
  139. :: Headers
  140. Cowboy allows you to obtain the header values as string,
  141. or parsed into a more meaningful representation.
  142. This will get the string value of a header.
  143. ``` erlang
  144. HeaderVal = cowboy_req:header(<<"content-type">>, Req).
  145. ```
  146. You can of course set a default in case the header is missing.
  147. ``` erlang
  148. HeaderVal
  149. = cowboy_req:header(<<"content-type">>, Req, <<"text/plain">>).
  150. ```
  151. And also obtain all headers.
  152. ``` erlang
  153. AllHeaders = cowboy_req:headers(Req).
  154. ```
  155. To parse the previous header, simply call `parse_header/{2,3}`
  156. where you would call `header/{2,3}` otherwise.
  157. ``` erlang
  158. ParsedVal = cowboy_req:parse_header(<<"content-type">>, Req).
  159. ```
  160. Cowboy will crash if it doesn't know how to parse the given
  161. header, or if the value is invalid.
  162. You can of course define a default value. Note that the default
  163. value you specify here is the parsed value you'd like to get
  164. by default.
  165. ``` erlang
  166. ParsedVal = cowboy_req:parse_header(<<"content-type">>, Req,
  167. {<<"text">>, <<"plain">>, []}).
  168. ```
  169. The list of known headers and default values is defined in the
  170. manual.
  171. :: Meta
  172. Cowboy will sometimes associate some meta information with
  173. the request. Built-in meta values are listed in the manual
  174. for their respective modules.
  175. This will get a meta value. The returned value will be `undefined`
  176. if it isn't defined.
  177. ``` erlang
  178. MetaVal = cowboy_req:meta(websocket_version, Req).
  179. ```
  180. You can change the default value if needed.
  181. ``` erlang
  182. MetaVal = cowboy_req:meta(websocket_version, Req, 13).
  183. ```
  184. You can also define your own meta values. The name must be
  185. an `atom()`.
  186. ``` erlang
  187. Req2 = cowboy_req:set_meta(the_answer, 42, Req).
  188. ```
  189. :: Peer
  190. You can obtain the peer address and port number. This is
  191. not necessarily the actual IP and port of the client, but
  192. rather the one of the machine that connected to the server.
  193. ``` erlang
  194. {IP, Port} = cowboy_req:peer(Req).
  195. ```
  196. :: Reducing the memory footprint
  197. When you are done reading information from the request object
  198. and know you are not going to access it anymore, for example
  199. when using long-polling or Websocket, you can use the `compact/1`
  200. function to remove most of the data from the request object and
  201. free memory.
  202. ``` erlang
  203. Req2 = cowboy_req:compact(Req).
  204. ```
  205. You will still be able to send a reply if needed.