Advertisement
Guest User

Untitled

a guest
May 6th, 2015
242
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. Version 1
  2.  
  3.  
  4. ## Original Web App Controller Code for /api/postMessage:
  5.  
  6. app.post('/api/postMessage', function(req, res){
  7.   var ebWrapped1 = {
  8.     payload: {
  9.       token: req.get('token-auth'),
  10.       method: 'post',
  11.       path: '/api/postMessage',
  12.     }
  13.   }
  14.   var ebWrapped2 = {
  15.     identityId: null,
  16.     payload: {
  17.       channel: req.body.channel,
  18.       text: req.body.text,
  19.     }
  20.   }
  21.   eb.send('checkAuth', ebWrapped1, function(ebRes){
  22.     if(ebRes.ok) {
  23.       ebWrapped2.identityId = ebRes.identity._id;
  24.       eb.send('/api/postMessage', ebWrapped2, function(ebRes2){
  25.         if(ebRes2.ok){
  26.           return res.status(200).json(ebRes2);
  27.         } else {
  28.           return res.status(ebRes2.statusCode).json(ebRes2);
  29.         }
  30.       })
  31.     } else {
  32.       return res.status(ebRes.statusCode).json(ebRes);
  33.     }
  34.   })
  35. })
  36.  
  37. ===
  38. Notes on the above: 30 Lines, hard to read and follow, a little spaghetti with the 4 parts of method construction intertwined.
  39.  
  40. ## Here is the Original Web App Controller Code again for /api/postMessage with the '4 parts of method construction' marked:
  41.  
  42. app.post('/api/postMessage', function(req, res){
  43.  
  44.   # Collect Input
  45.   var ebWrapped1 = {
  46.     payload: {
  47.       token: req.get('token-auth'),
  48.       method: 'post',
  49.       path: '/api/postMessage',
  50.     }
  51.   }
  52.  
  53.    # Collect Input
  54.   var ebWrapped2 = {
  55.     identityId: null,
  56.     payload: {
  57.       channel: req.body.channel,
  58.       text: req.body.text,
  59.     }
  60.   }
  61.  
  62.   # Perform Work
  63.   eb.send('checkAuth', ebWrapped1, function(ebRes){
  64.    
  65.     if(ebRes.ok) {
  66.    
  67.       # Deliver Output # Collect Input
  68.       ebWrapped2.identityId = ebRes.identity._id;
  69.  
  70.       # Perform Work
  71.       eb.send('/api/postMessage', ebWrapped2, function(ebRes2){
  72.         if(ebRes2.ok){
  73.    
  74.           # Deliver Output
  75.           return res.status(200).json(ebRes2);
  76.         } else {
  77.    
  78.           # Handle Failure
  79.           return res.status(ebRes2.statusCode).json(ebRes2);
  80.         }
  81.       })
  82.     } else {
  83.    
  84.       # Handle Failure
  85.       return res.status(ebRes.statusCode).json(ebRes);
  86.     }
  87.   })
  88. })
  89.  
  90.  
  91. ## Here is a refactored version with extra comments:
  92.  
  93. Given both postMessage and checkAuth are located behind event bus:
  94.  
  95. app.post('/api/postMessage', function(req, res){
  96.  
  97.   // Collect Input
  98.   var payload = {
  99.     token:   req.get('token-auth'),
  100.     channel: req.body.channel,
  101.     text:    req.body.text
  102.   }
  103.  
  104.   // Perform Work
  105.   backend.postMessage(payload, function(backend_response){
  106.  
  107.     // Deliver Output
  108.     if(backend_response.ok){
  109.       return res.status(200).json(backend_response);
  110.  
  111.     // Handle Failure
  112.     } else {
  113.       return res.status(backend_response.statusCode).json(backend_response);
  114.     }
  115.   })
  116. }
  117.  
  118. Here is the same Original behavior version but refactored and without extra comments:
  119.  
  120. app.post('/api/postMessage', function(req, res){
  121.   var payload = { token: req.get('token-auth'), channel: req.body.channel, text: req.body.text}
  122.   backend.postMessage(payload, function(backend_response){
  123.     if(backend_response.ok){
  124.         return res.status(200).json(backend_response);
  125.       } else {
  126.         return res.status(backend_response.statusCode).json(backend_response);
  127.     }
  128.   })
  129. }
  130.  
  131.  
  132. ===
  133. Notes:
  134. - Controller method complexity and LOC from 30 lines to 10 lines
  135. - No nested IF's
  136. - Clean using 'Tell Don't Ask' convention
  137. - Backend can take care of the auth itself
  138. - The backend library in node now is truly abstracted out so that:
  139.   1) the backend can be swapped out for a REST, WEBSOCKETS, GRPC2.... anything
  140.      and the nodejs route/controller does not need to be touched.
  141. - Follows the 4 Parts of a method convention: Collect Input, Perform Work, Deliver Output, Handle Failures
  142. - Clear and well defined interface in the controller and backend allows us to swap out the backend easily since it is well, using a well defined small and simple interface.
  143.  
  144. ## The backend js lib could be something similar to the below:
  145. Note: this library can be used from ANY application or node process. It is not intertwined with HTTP or PI cross boundary code:
  146.  
  147. sopro.backend.postMessage = function(payload){
  148.   payload.method = 'post';
  149.   payload.path = '/api/postMessage';
  150.   return eb.send('/api/postMessage', payload);
  151. }
  152.  
  153.  
  154. # Special Notes:
  155.  
  156. The payload sent to the backend has everything it needs to take care of:
  157. 1) Checking the Auth and User ID lookup
  158. 2) Sanity Checks on Message/Channel destination
  159. 3) Actual persistence
  160. 4) Sending out a new event over the message bus containing the new message. Resulting in ALL node webapps listening on the event bus for this event to react to and render the new messages over websockets and in the GUI.
  161. 4) Returning a conventional response
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement