I'm building a classic database backed, dynamic website, that will allow users to share leads.
I'm a little old school, and want to implement my system using a pure MVC architecture. I'm considering using React in a pure 'V' mode, with Vapor fulfilling the 'M' and 'C' roles. I need some help understanding how to integrate Vapor and React, or more precisely decide where some functionality is best to reside.
My Vapor server side app, handles all security, routing, models (which are stored in a PostgreSQL DB via Fluent) and model controllers. The model controllers only output pure JSON responses, to requests that will have been through middleware layers that: check a user's permissions to access a 'command' (based on a role profile held in the database, to allow dynamic changes to privilege); verify permission to access the associated record (based on a hierarchy of groups they can be members of); and also to log actions that a user is taking.
Up to this point I've been using the Leaf templating engine to generate the .html files for the web site a user would use. The Leaf template is normally passed only one or two attributes - say the id of the record which is going to be displayed, and then I use some javascript to pull in the data via AJAX calls back to the model controller. The model controller and middleware has access to the cookie for all user auth / session related needs. This keeps a very clean separation between the model and view, and would allow me to more easily build say a mobile app that calls the model RESTful interfaces in the future.
Now I am thinking of using React for the web front end, using the React-Bootstrap library. But to be honest I'm getting a little lost of how to integrate this properly. For example to render a page to display a record - how do I pass over the record id (pseudo code warning!):
a) Should I create a leaf template into which I pass the id as a parameter. The template would simply have a short piece of javascript to pass the parameter onto the react.js script? Vapor side would look something like:
drop.get("viewRecord", myObject) { request in
let parameters = try Node(node:["objectId": myObject?.id.makeNode()])
return try webApp.view.make("viewObject", parameters)
}
And .leaf template would have a bit like:
<script ...>
var objectID = #(viewObject.id)
</script>
b) Or should I make a call such as, where I pass the id as a URL param, which I would then extract with a little javascript and pass into a react component:
drop.get("viewRecord", myObject) { request in
return Response(redirect: "/viewObject.html", myObject?.Id)
}
c) Some other way within Vapor? Am I missing the point with React? I thought it was meant to be focused no the front end and agnostic about backend, but the React Router suggests it wants some backend work too?
d) Abandon React, and say stick with leaf?
On this last point - if I go the React way, would I have a .jsx file (transpiled to .js) for every "screen" that I would have built a leaf template for? If so how would I go about reducing the file sizes down by referencing common elements (such as react and react-bootstrap components). At the moment I'm using Webpack to produce a single .js file. Am assuming I would not use React router, as I use Vapor for this.
Sorry, if some of this is quite basic, but I'm more comfortable with the backend, but want the front end to be well engineered too, and to get the split of responsibilities optimal.
Thank you for your considered ideas!
So after some work the answer to my question is c.
I have two separate projects:
1) One using Vapor to build a pure restful service that responds to GET and POST requests with JSON responses. It handles all the security assuming the browser is insecure.
2) Then on the front end, I have a React single page app. It downloads a user's permissions during logon, and uses this to control what is visible on screen.
The server ensures that no data is ever sent or persisted that is outside a user's permissions. Therefore if a user was able to try and see a page in the React app that they didn't have permission to, they would only see the page structure and no data.
Coming back to this...I have written an intro tutorial for this on my site, here: https://www.vaporforums.io/thread/25
But essentially, use 2 separate projects, and use the front end to make API requests to the backend.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With