I have been applying a pattern in some small apps I worked on, which next tools:
Frontend: ReactJS, Redux, Firebase (only authentication stuff)
Backend: Node with Express and the library for the database I was using (mysql or mongo)
The flow used to be like this:
Page loading and validating if user is signed in. If yes, fetching app data with backend. If not, just checking if user is not on a protected route and then let him navigate (create account, reset password, etc)
When fetch occurs and user signed in, backend send all data from that user (categories, stores, products, profile and any other info to let application run fluid) so when navigating there is not continuously loading to fetch each chunk of data. This also happens like this because is not a big amount of data (at the beginning), lets say maybe 1 or 2 stores with 15-20 products each one.
When updating data like changing product name, price or any kind of data mutation, the frontend send a request to the backend and then the update is done and a response of success true/false is sent as an answer for the request.
Let's say the previous step is a store creation. So, the frontend receives the success response and then dispatch an APPEND_STORE event to redux store to catch the new store with its data (only the ID + other data which is created on the backend is received as response on http request, data which was generated at the frontend is taken from the app itself) and append it to the stores array and then set the store array object again.
The reason why the previous step occurs like that is to avoid the backend first make the update and then make a new query to get again the new register (ej: create new store request -> backend creates the store and retrieve the new ID -> backend find/query the new register with its ID -> answer the data)
So, basically the question is about the pattern. So far this pattern had not give big troubles by now but I'm pretty sure there are some details I haven't seen from this point and also I think there are recommended ways to handle this that I couldn't find on internet yet.
I would like to know the best approach for this (or at least a better approach from the above) in order to implement it to bigger applications to handle more users and data which will increase as time goes.
Main questions:
When loading, should the backend process all data and send it to the frontend or should send minimal data to let the application begin and then send as navigation requires? I was also thinking when data grows up send a chunk of data with limit of 10/20 registers to keep the same approach but want to know the standard/correct way to handle it.
When a data validation fails on backend, should the backend answer with an OK status code with a key called success: "true/false" and additional data to handle this on the frontend, or should the backend answer with an error status code?
As I said, backend only answer with the data created by backend itself (ID, creation date, etc). Should the backend answer only with this or should backend make a new query to get full register and send it as response? Initially took this approach in order to optimize resources (minimum quantity of request and data sent by response). I'm also thinking maybe this is a dumb approach because today's world have a lot of resources so that difference should not change performance of anything. Also, with this answer my behavior on redux will change. Do you have any comments also from this redux approach?
Is it ok to make a query to database to first update and then another query to fetch all registered again? I know databases are created to handle multiple queries but I don't know if there are some cons to take on mind when doing like this.
Really thanks!
Related
I have two applications, spring boot backend and react frontend. I need to load a lot of data (lets say 100 000 objects, each 3 Integer fields), and present it on a leaflet map. However i don't know which protocol should I use. I thought about two approaches:
Do it with REST, 1 000 (or more/less) objects each request, create some progress bar on front end so user does not refresh the page all the time because he thinks something is wrong.
Do it with websocket, so it is faster? Same idea with progress bar, however I am worried that if user starts to refresh the page, backend will stream the data even though connection from frontend is crashed and new one is established, for the new one the process will begin too, and so on.
If it is worth mentioning, I am using spring-boot 2.3.1, together with spring cloud (eureka, spring-cloud-gateway). Websocket i chose is SockJS, data is being streamed by SimpMessagingTemplate from org.springframework.messaging.simp.SimpMessagingTemplate.
If you have that amount of data and alot of read write operations, I would recommend not returning it in either websocket or rest call(reactor or MVC) sending big amount of data over tcp has it issues, what I would recommend is quite simple, save the data to Storage(AWS S3 for example), return the S3 bucket url, and from the client side read the data from the S3 directly,
alternatively you can have a message queue that the client is subscribe on(pub/sub), publish the data in the server side, and subscribe to it on the client side, but this may be an overkill.
If you are set on rest you can use multipart data see the stack overflow question here:
Multipart example
Sorry for a general question. My situation looks so: i have mongodb database and 2 reactjs pages. In each page i want to fetch a different information from database. Depending by your practice, which is the best way to fetch data from mongodb in a reactjs component?
I would recommend reading up on the MERN stack - tons of guides available online via google and youtube. The gist would be that a typical web application will consist of a few key components. In this case:
1 - (React) The client page rendered to the user
2 - (Node + Express) The server which processes data, allows you to use endpoints to make changes to your application. These endpoints make the necessary database queries. You can use a database client to write these queries as JavaScript within your NodeJS endpoints.
3 - (MongoDB) Your database.
So for instance a typical CRUD app allows you to create, read, update, and delete. Let's say you are looking at making a standard TODO list app.
You would need to make requests to these endpoints to perform these operations.
You could have a POST to /todo which would then insert a new document into your database.
You would need a way to read the information from the page... say a GET request to /todos to read all items. Or also a GET request to /todo/:id to get a specific item.
You would need a way to update an existing item... say a PUT request to /todo/:id with the updates you want to take place.
Finally you would need a way to delete an item... a DELETE request to /todo/:id which would delete the item.
Each of these endpoints would make a request to insert / read / update / delete items from the database, and return content to the client React code --> which then displays it to the user.
Frontend side, in react.js call api data using fetch() method. Pass your Mongodb URI string. If you want data in slot based use limit() and Skip() function for pagination.
Follow MVC pattern where your frontend only calla controller api. And controller calls DAO methods for Mongodb. You can Use Mongodb Stitch for serverless app.sor data leak can be avoided forntend side. Mongodb has connecting pool max.100 so that each time client request Mongodb connection cashed object given from pool to further speed up your connection time.
I have a React/Redux front-end with an Express back-end application, and I'm rather new, but I have a question regarding how to deal with the flow of data.
So, on my front end side, I have a search bar. When a user enters a search term, I sent a post request from React which is handled in my Express routes.js file. In this file, I am taking that search term, and I am looking for that term in my Mongo database. After that, all I want to do is send an object back if the term was found in the database.
I have used axios in this application to make an HTTP request to a certain route to pull off some data, but that was within an app.get(...) on the express side, and I used an axios.get(...) on the React side to retrieve the information.
But, this situation is slightly different since the data is flowing in two directions. Initially, from a front end to the backend, and then back-end to front-end. And in this case, I'm using app.post(...).
Now my question is, how would I retrieve the data to the front end? Could I simply just do an axios.get(...) on an app.post(...) or is there some other way to do this?
If you GET from the browser to your back-end's route which is implemented to respond to POST only, you will probably get a 405 error. Implement a POST Axios request and a POST Express reply.
You can use either GET or POST, but you need to be consistent on the server and the client side. If you do an http GET from the client, the server will only respond if you have a app.get(...) as a server route.
As far as the flow of data is concerned, both a get and a post can return data, it just needs to be specified on the express route.
After the business logic of looking if the key exists in mongo do something like res.send({'found': true}) or res.json({'found': false}). This will ensure that the data gets back to the client.
If I were to do this, I would:
1.) Use an Axios get request and pass in as a parameter the identifying attributes, such as a related _id or key phrase.
2.) Use mongoDB's query filter search parameters to index and aggregate the schema data in the DB. I would probably use .findOne or .find.
3.) Use the router callback to pass in the filtered data, then dispatch a function to save it to a state.
This way you can set up specific terms or keywords to search with, and utilize the searched data throughout the app.
I have a page with multiple widgets, each receiving data from a different query in the backend. Doing a request for each will consume the limit the browser puts on the number of parallel connections and will serialize some of them. On the other hand, doing one request that will return one response means it will be as slow as the slowest query (I have no apriori knowledge about which query will be slowest).
So I want to create one request such that the backend runs the queries in parallel and writes each result as it is ready and for the frontend to handle each result as it arrives. At the HTTP level I believe it can be just one body with serveral json, or maybe multipart response.
Is there an angularjs extension that handles the frontend side of things? Optimally something that works well with whatever can be done in the Java backend (didn't start investigating my options there)
I have another suggestion to solve your problem, but I am not sure you would be able to implement such a thing as from you question it is not very clear what you can or cannot do.
You could implement WebSockets and the server would be able to notify the front-end about the data being fetched or it could send the data via WebSockets right away.
In the first example, you would send a request to the server to fetch all the data for your dashboard. Once a piece of data is available, you could make a request for that particular piece and given that the data was fetched couple of seconds ago, it could be cached on the server and the response would be fast.
The second approach seems a more reasonable one. You would make an HTTP/WebSocket request to the server and wait for the data to arrive over WebSocket.
I believe this would be the most robust an efficient way to implement what you are asking for.
https://github.com/dfltr/jQuery-MXHR
This plugin allows to parse a response that contains several parts (multipart) by having a callback to parse each part. This can be used in all our frontends to support responses for multiple data (widgets) in one requests. The server side will receive one request and use servlet 3 async support (or whatever exists in other languages) to ‘park’ it, sending multiple queries, writing each response to the request as each query returns (and with the right multipart boundary).
Another example can be found here: https://github.com/anentropic/stream.
While both of these may not be compatible with angularjs, the code does not seem complex to port there.
I have a server written in Express that interfaces with an application written in Angular on the client.
My Express server is receiving a post from a third-party service to a route which will perform business logic, and then here is where I am a little uncertain about the best path forward.
After receiving the post variables, I want to redirect the request to an Angular route, but I want to make those received post variables available to the route as well.
Somehow, I want to be able to mix the res.json() and res.redirect() method, but I'm pretty sure they both end the response.
What would be a logical way to structure this?
Update: To expand on the issue, imagine I have a route called /receivetransaction which receives some postback variables, including transaction ID, amount etc. I want to perform business logic (save to a database), and then redirect the user to /thankyou (an angular route) but have them be able to access that data that was just received in the postback.
It looks like maybe my best option would be to save to the database, and then send the transaction-id as JSON to the angular view, which will then hit the database and pull the info. A little inefficient though (not really a big deal) but I would hope there would be another way around it.
What I've decided to do is the following:
After the express route receives the postback variables, it performs the business logic (specifically saving the data to the database), and redirects the request to the angular route with a query var indicating the id of the transaction.
The angular controller uses $location.search() to pull the transaction id from the query var, and from there it performs a get request to the express API, which performs authentication and loads the relevant information into $scope variables to be passed to the view.