endpoints.tex 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. \section{Endpoints}
  2. N2O Erlang Processes are instantiated and run by Web Server.
  3. Depending on Web Server endpoint bindings you can specify
  4. module for HTTP requests handling.
  5. \paragraph{}
  6. N2O comes with three endpoint handlers for each Web Server supported.
  7. However you are not required to use any of these.
  8. You can implement your own endpoint handlers, e.g. for using with
  9. Meteor.js or Angular.js and providing Erlang back-end event streaming
  10. from server-side. Here is an example of using HTTP, WebSocket and
  11. REST endpoint handlers with Cowboy Web Server.
  12. \vspace{1\baselineskip}
  13. \begin{lstlisting}
  14. {"/rest/:resource", rest_cowboy, []},
  15. {"/rest/:resource/:id", rest_cowboy, []},
  16. {"/ws/[...]", n2o_stream, []},
  17. {'_', n2o_cowboy, []}
  18. \end{lstlisting}
  19. \subsection{HTML Pages over HTTP}
  20. This handler is used for serving initial dynamic HTML page.
  21. In case you are serving static HTML content this handler is
  22. not included into the running stack. {\bf {n2o}\_{cowboy}} is
  23. a default HTML page handler.
  24. \paragraph{}
  25. On initial page load {\bf {n2o}\_{document}:run} of page document endpoint is started.
  26. During its execution {\bf {wf}\_{render}:render} proceeds
  27. by calling {\bf Module:main} selected by the routing handler.
  28. \newpage
  29. \subsection{JavaScript Events over WebSocket}
  30. JavaScript handler shares the same router information as the
  31. HTML handler because during its initial phase the same chain
  32. of N2O handlers is called.
  33. \paragraph{}
  34. This handler knows how to deal with XHR and WebSocket requests.
  35. {\bf {n2o}\_{stream}} is a default JavaScript event handler
  36. based on Bullet library created by Loïc Hoguin, optimized and refined.
  37. \paragraph{}
  38. You can send several types of events directly from JavaScript
  39. using various protocols. E.g. you may need to use client protocol:
  40. \vspace{1\baselineskip}
  41. \begin{lstlisting}
  42. JavaScript> ws.send(enc(tuple(atom('client'),
  43. tuple(atom('phone_auth'),bin("+380..")))));
  44. \end{lstlisting}
  45. \vspace{1\baselineskip}
  46. And catch this event at Erlang side:
  47. \vspace{1\baselineskip}
  48. \begin{lstlisting}
  49. event({client,{phone_auth,Phone}}) ->
  50. io:format("Phone: ~p~n",[Phone]).
  51. \end{lstlisting}
  52. \vspace{1\baselineskip}
  53. You can also send direct messages to event/1, but use it carefully
  54. because it may violate security rules.
  55. \vspace{1\baselineskip}
  56. \begin{lstlisting}
  57. > ws.send(enc(tuple(atom('direct'),atom('init'))));
  58. \end{lstlisting}
  59. \vspace{1\baselineskip}
  60. With catching at Erlang side:
  61. \vspace{1\baselineskip}
  62. \begin{lstlisting}
  63. event(init) -> io:format("Init called~n").
  64. \end{lstlisting}
  65. \vspace{1\baselineskip}
  66. \newpage
  67. \subsection{HTTP API over REST}
  68. REST handler's request context initialization differs for the one
  69. used by HTML and JavaScript handlers. N2O handler chains are not
  70. applied to REST requests. {\bf rest\_cowboy} is a default REST
  71. handler.
  72. \vspace{1\baselineskip}
  73. \begin{lstlisting}
  74. {"/rest/:resource", rest_cowboy, []},
  75. {"/rest/:resource/:id", rest_cowboy, []},
  76. \end{lstlisting}
  77. \lstset{captionpos=b}
  78. \vspace{1\baselineskip}
  79. \begin{lstlisting}[caption=users.erl]
  80. -module(users).
  81. -behaviour(rest).
  82. -compile({parse_transform, rest}).
  83. -include("users.hrl").
  84. -export(?REST_API).
  85. -rest_record(user).
  86. init() -> ets:new(users,
  87. [public, named_table, {keypos, #user.id}]).
  88. populate(Users) -> ets:insert(users, Users).
  89. exists(Id) -> ets:member(users, wf:to_list(Id)).
  90. get() -> ets:tab2list(users).
  91. get(Id) -> [User] = ets:lookup(users, wf:to_list(Id)), User.
  92. delete(Id) -> ets:delete(users, wf:to_list(Id)).
  93. post(#user{} = User) -> ets:insert(users, User);
  94. post(Data) -> post(from_json(Data, #user{})).
  95. \end{lstlisting}
  96. \vspace{1\baselineskip}
  97. To add users to in-memory storage perform POST requests:
  98. \vspace{1\baselineskip}
  99. \begin{lstlisting}
  100. curl -i -X POST -d "id=vlad" localhost:8000/rest/users
  101. curl -i -X POST -d "id=doxtop" localhost:8000/rest/users
  102. curl -i -X GET localhost:8000/rest/users
  103. curl -i -X PUT -d "id=5HT" localhost:8000/rest/users/vlad
  104. curl -i -X GET localhost:8000/rest/users/5HT
  105. curl -i -X DELETE localhost:8000/rest/users/5HT
  106. \end{lstlisting}
  107. \vspace{1\baselineskip}