How to route for a react-router app using express? - reactjs

So I have a backend running in expressjs and I have multiple routes on it. Now I just followed this tutorial to set up a RESTful api on express. Now I want to switch to full react on the frontend, so that I will have an api running in the backend to get things from the database and am thinking using fetch from react to get that data. I saw many people say that is the best way to do it. But now there is an issue, I am not sure how to route for this. I have react-router setup so I am assuming I would use that. But how can I serve these files to the client side? How can I make sure every route except /api routes just serve my js files? Like I have a built folder already with an index.html and main<hash>.js. I am running them easily but how can I intergrate them with express? I was not able to find any answers to this. How can I route for a reactjs app to be served using expressjs? and also I saw a tutorial telling me to use a * route but that means even my api routes will only point to that.

There are three ways basically to render an application.
One is Server Side Rendering, the other one is Client Side rendering and the third one is Isomorphic rendering.
So if you are defining your routes in Nodejs and navigating the application through those routes than it will be entirely server side rendering.
I saw a tutorial telling me to use a * route but that means even my
api routes will only point to that. ? How can I make sure every route
except /api routes just serve my js files?
Regarding this what you can do is
server.get('/api', (req, res, next) => {
//You can handle the request here
})
server.get('*', (req, res, next) => {
//You can handle the request here
})
You can define your route in this order.So by this way any call to the '/api' will be handled by the first route and all the other request will be handled by the second route.
Now I want to switch to full react on the frontend, so that I will
have an api running in the backend to get things from the database and
am thinking using fetch from react to get that data
Here you dont need this.It will be an client side rendering completely
server.get('*', (req, res, next) => {
//You can handle the request here
})
For this you can create an react app from scratch or use some boilerplate (https://github.com/facebookincubator/create-react-app).
There you can define all the routing and simply call the url http://localhost/api/xxxx and get the data and you can use this data in the frontend.In this case there will be a Nodejs Server which will be serving the frontend and the expressjs server will he hosting the 'api' service to get data from.
I have react-router setup so I am assuming I would use that. But how
can I serve these files to the client side?`
How can I route for a reactjs app to be served using expressjs?
The Reactjs app when compiled is a combination of static files comprising mainly of html, css, javascript. If you want your app to be served by your express.js server then you need to use isomorphic rendering. It is by far the best approach for rendering application as it is good for SEO and initial fast page load. It comes at the cost of a complicated setup. In this case, whenever the page refreshes or the first request comes, express will serve the first page (index.html) and index.html will contain the required static(bundled) js and css files for client side rendering. The first rendering will be done by the express server and the subsequent rendering will be done by browser itself.

Related

How to use Express routes with React.js frontend?

Can I use Express routing for sending the content of the pages? In classic HTML, you can do:
app.get("/admin", (req, res) => {
res.sendFile("admin.html"); // or res.render() for templating engines like EJS
});
Unfortunately, I am not able to use Express routing for serving the React pages. The only way I found was to use React Router, which technically gets the job done, but then I can't do anything else on the server-side, like validating the login. I could technically make an API endpoint on the server-side for that and then request it within the React JSX page itself, however, that'd be inconvenient for many reasons:
Having the requests be sent only after the page, which means tons of loading indicating and possible issues like the user being able to see the content he should not be able to see at all.
Most of the "on-page-visit" API requests would need to be protected with keys, like the Authorization key
If the API request is done anywhere on the client-side, the keys are insecure and also the response can be manually altered by the user which creates huge security violations.
If there was a React renderer for Express, in which you could render a React JSX file directly from the page (e.g. res.render("page.jsx")) which would compile React and send the pure HTML, that'd be great! But of course, I haven't been able to find such and I doubt there are any.
Yes you can, but only only with the bundled appilcation. You simply send the index.html you find in the build folder of your react application.
Would look like this:
Assuming that is you express index.js & that the react application lives in a "client" directory of your applicaiton.
const path = require("path");
app.get("*", (req, res) => {
res.sendFile(path.resolve(__dirname, "client", "build", "index.html"));
});

Routing an user in a single page application using the adress bar

I have a backend using express to serve a static directory, to the path /, in which is contained a single page frontend. This backend also serves an API REST.
The frontend is built in React, and uses react-router to route the user from the different views of the web application.
If my react-router have two entries, let say /app and /config,
how can I redirect the client to that view of the application, if the user enters directly the URL in the web browser's address bar?
Right now, if I do that, Express gets the request and obviously returns a 404 message, as the single page is served to / path.
A simple way to resolve that is to always (even on 404s) send to user the index.html in your express route handlers.
See: https://stackoverflow.com/a/25499007/2624575
However, you need to take care of some things:
1) Your React Router code should start to handle 404s: https://stackoverflow.com/a/37491381/2624575
2) You need to handle correctly the path to your assets (icons, css, js, etc), otherwise you'll send the same index.html to those kind of resources (which will make your page render incorrectly)
3) Make sure that react-router is using browserHistory (the history that doesn't use hashes #), This way React will be able to render your routes correctly
Hope it helps!

Single Page App on React.js and ZF2. Is it possible?

I'm thinking how to implement a SPA on Zend framework 2 using Reactjs? Haven't seen any tutorial that might help me. So, I was asking if this is possible. How would zf2 will handle the routes?
The routes are handled on the client side (by pushing URLs into browser's history so you can also use browser's back button for navigation)
Simply put, changing a route will not load a whole page from the server.
The server does not even know that your JS app is changing the URL in the browser (imagine you write by hand http://example.com#test while you were already on example.com; that #test thing is a fragment URL and it will never be sent to a server)
Instead, the JS application will respond to (once again, client-side) route changes by rendering a different page or section, and making some ajax calls to the server to fetch or update data.
Now let's see what the server should do:
send the first page (the "single-page") and the assets (CSS, JS) on
the first load
respond to app-originated AJAX API calls once the page is loaded and
the JS app has been started
That's why they call them "single page apps", because they do much of the logic and the presentation in the browser (DOM rendering, routes), and the server merely acts as a data layer, or a backend if you like this word better.

How does Angular and Express routing work together in a mean.js app?

I'm struggling about Angular and Express Routing (by the way, i'm somehow new to Express), i've been handling routes with Angular — with ui-router — but now that i'm starting to build a MEAN.js Application i notice that i can handle server-side routing and client-side routing... and that's what makes me get confused, here are some of my questions:
How are they different?
If i switch to Express routing will i still have a SPA?
Can i use both at same time? How? Is it good practice? Does it has any benefit?
When should i use only one of them?
How will i handle route parameters?
etc...
If someone can explain with detail these questions, and other extra things people need to know i'll be totally thankful.
Also, something that i want to know is: Do i only have to setup server things in Express or do i need to code in Node?
Routing in Express is sightly different then what it is in angular
In express
Routing refers to the definition of end points (URIs) to an
application and how it responds to client requests.
So if you are doing the routing using angularjs then you do not need to set the route for your html template using express.
you simply use express in a way to create your RESTAPI and then consume those API using angularjs $http or $resource
Summary:
Routing in Angular supports the idea behind a SPA. Ultimately you want to handle UI based route changes (i.e. no server call/logic needed) via Angular. Any route change that hits the backend, and ultimately requires server logic, should use Express routing.
Example
This is express routing to create rest API.
app = express();
app.get('/dowork',function(res,req){
console.log(req.params.msg);
/... code to do your work .../
});
now in angularjs call do work
$http.get('http://localhost:8080/dowork',{"msg":"hi"}).success(function(data){
console.log(data);
});
Just two cents here. Other expert should correct me and explain further :
Routing at frontend usually means routing management in url after #.
This is because anything after # is ignored by browser. So this is utilized by angular to make on the fly ajax calls and fetch resources depending on route path after #.
What express handles is url before #. This is used to make actual request from browser to server.
How are they different : answered
If i switch to Express routing will i still have a SPA :
You can always have SPA if you manage urls manually at front end side while making ajax calls to populate your single page. managing urls at front end should be with intention of readability.
Can i use both at same time? How? :
Everyone uses both. A SPA also uses both. Usually authentication based thing is handled by express routing while authorization and other routing based interaction like requesting for resources and others, front end routing is used. Even if you use front end routing, for ajax request behind the scene, you are still relying on express's routing.
Is it good practice? Does it has any benefit? :
Using express's routing for authentication and providing resources AND using angular routing for front end to keep SPA in action is always a good practice.
When should i use only one of them? : answered
How will i handle route parameters? :
There are parameters handling both for front end side using route params ( if using ng-route) and at the back end using slug, bodyparser and others.
You need to spare some time learning those.
Can we use both
of-course you can use both. Depending on your application requirement, what portion of your app need to be spa for better user experience and what portion views need to be render by your express app.
If i switch to Express routing will i still have a SPA?
if a particular routing is not handled by angular and you want to generate a view by express app you can do that. if you want to develop a complete spa then you need to develop a api (http end points) in you express app to respond to AJAX requests of your angular app. Angular routing is all bout clint side routing that is used to generate template and fetch data from server (in your case express) and render a view. Over all your angular routing calls to your express routing to fetch json data or any template to give the impression of a spa
example
in express we have
app.get("/", function (req, res) {
res.render("home");
});
you home page must include all the angular script files to initialize the angular app
in clint side code you can have
var app = angular.module("myApp", ["ui.router"])
.config(function ($stateProvider, ) {
$stateProvider.state("home", {
url: "/"
})
.state("manas", {
url: "/manas",
templateUrl: "/templates/manas.html"
// when the state or url is manas its fetch the static manas.html from server and inject that to ui view
})
// i am using angular UI router here
Can i use both at same time? How? Is it good practice? Does it has any benefit?
Ya we can use both at same time. It depends on your application logic their is no harm or benefit of using both.
When should i use only one of them?
Go with express routing only if you are more concerned about search engine optimization. Because SPA are not by-default search engine friendly you need to take some extra action to make it search engine friendly.
How will i handle route parameters?
it depends on what angular routing you are using. I mean vanilla angular routing or UI routing. But the concept is same for both
passing parameters
For passing parameters to server with UI routing go through
https://github.com/angular-ui/ui-router/wiki/URL-Routing#url-parameters
for UI routing follow this link
https://github.com/angular-ui/ui-router/wiki
if you app is not more complex you don't care about nested views child views etc
my suggetion go with angular plain routing.
No doubt UI router gives more advance routing concepts but learning curve is steep as well. if you app is simple in nature go with angular routing

Isomorphic Javascript Routes with React-Route vs REST API Routes

I have been studying react/flux/react-router and how pre-rendering virtual DOM in server happens. Calling Router.run() and renderToString in the server will take care of pre-rendering the page in the server and lazily loading and downloading the rest of .js files to the client. React-router deals with UI URLs in any scenario (either client or server). This is not necessarily the same as REST API URLs of the server.
What is the best practice to add routes functionality If I want to use the backend for a native app with REST features as well. should I have a complete set of routes definitions for express.js and re-define all the routes in react-routes as well?
React routes are not necessarily similar to express routes (can have more or less route patterns). So replicating route definitions seem inevitable. Is that correct? even this example seems to be doing the same thing.
I was hoping to find a way to reuse routes definition or something more DRY.
You don't want to duplicate routes on a client and server. See flux examples from Yahoo: https://github.com/yahoo/flux-examples/tree/master/react-router
Then, just specify API request before the react router on the server. E.g.:
var express = require('express');
var server = express();
// Static files
server.use('/assets', express.static('src/assets'));
server.use('/build', express.static('build'));
// Declare API handling:
require('apiRouting')(server);
// Decalre react-router handling
require('./routing.jsx')(server);
// In the apiRouting.js:
module.exports = function (server) {
server.get('/api/methodA', function (req, res) {
// body...
});
server.get('/api/methodB', function (req, res) {
// body...
});
};
Also, there's a library that makes it so you can build your APIs in an isomorphic fashion, and re-use it in the client and server without bloating or breaking the bundle. This is what we're currently using in a big single-page application.
It's called Isomorphine, and you can find it here: https://github.com/d-oliveros/isomorphine.
Disclaimer: I'm the author of this library.

Resources