Search code examples
javascriptnode.jsexpressreactjsisomorphic-javascript

Routing get parameters and app logic


I have an endpoint / and this endpoint gets passed at times different get parameters for oAuth and logging into an app.

I've built a function for delegating these requests below called queryAction. Platforms like express allow you to route at the path level but not the res.query level, because you can't have res.query without a route.

For instance if I have /?shop=thomas and /?login=thomas&code=7 I'm going want the user to be doing different things, different returned functions within the app.get("/") callback.

Here's some code that takes in a query object and returns a string based on what action should be done.

function queryAction(query, secret){
  query = (query) ? query : {}
  var signature = checkSignature(query, secret)
  var timestamp = checkTimestamp(query)
  var valid = signature && timestamp
  var hasInstallParams = _.hasOnly(query, ["code","shop","timestamp","signature"])
  var hasErrorParams = _.hasOnly(query, ["error","shop","timestamp","signature"])
  var hasErrorDescParams = _.hasOnly(query, ["error","error_description","shop","timestamp","signature"])
  if(!_.size(query)) return "view" // show shop login form
  if(_.hasOnly(query, ["shop"])) return "shop" // redirect to login
  if(_.hasOnly(query, ["charge_id"])) return "charge"
  if(hasInstallParams && valid) return "installed"
  if(hasInstallParams && !valid) return "installed_invalid_timestamp_and_signature"
  if(hasInstallParams && !signature) return "installed_invalid_signature"
  if(hasInstallParams && !timestamp) return "installed_invalid_timestamp"
  if(hasErrorParams && query.error == "access_denied" && valid) return "install_canceled"
  if(hasErrorParams && query.error == "access_denied" && !signature) return "install_canceled_invalid_signature"
  if(hasErrorParams && query.error == "access_denied" && !timestamp) return "install_canceled_invalid_timestamp"
  if(hasErrorParams && query.error == "access_denied" && !valid) return "install_canceled_invalid_timestamp_and_signature"
  if(hasErrorParams && query.error == "invalid_request" && valid) return "invalid_request"
  if(hasErrorParams && query.error == "invalid_request" && !signature) return "invalid_request_invalid_signature"
  if(hasErrorParams && query.error == "invalid_request" && !timestamp) return "invalid_request_invalid_timestamp"
  if(hasErrorParams && query.error == "invalid_request" && !valid) return "invalid_request_invalid_timestamp_and_signature"
  if(hasErrorDescParams && query.error == "invalid_scope" && valid) return "invalid_scope"
  if(hasErrorDescParams && query.error == "invalid_scope" && !signature) return "invalid_scope_invalid_signature"
  if(hasErrorDescParams && query.error == "invalid_scope" && !timestamp) return "invalid_scope_invalid_timestamp"
  if(hasErrorDescParams && query.error == "invalid_scope" && !valid) return "invalid_scope_invalid_timestamp_and_signature"
  return "undefined_action"
}

With this code I can check if a corresponding function exists and run it for instance.

app.get("/", function(res, req, next){
  var action = queryAction()
  if(actions[action]) return actions[action](req, res)
  return next(action)
}

Some of these functions would perform some database task or otherwise asynchronous task and redirect the user or render a view. I'm having a hard time juggling what express should handle (or if I even need it) and what React should handle.

  • Because I want the same version of React running server-side can there be code that only runs server side and is stripped out of the client, like removing secret oAuth keys from the client-side version of react?
  • Is React capable of routing params to different views / actions, like above?
  • What is the line where React stops being a view engine?
  • Is react capable of rendering out server-side only code and removing parts from the client before it pushes?

Solution

  • This may not answer your individual questions, but the solution you are looking for is react-router.

    The way I have used it with express is that I "catch all" the routes via express.get(/*) or whatever, and pipe that query down to a react-router handler. Please view this page for more information on how that works.

    This allows you to route params to different views, will let you use express to remove/etc oauth keys for React, and really just act as middleware for your React components. I am not sure what you mean by "removing parts from the client before it pushes" but you can surely do whatever you need to at this point before you render the component.