using graphql with a cache to reduce database access - node.js

Hey guys I'm a complete beginner in term of developing web application using node.js, react and so on.
So far I decided to use graphql and especially subscriptions to implement the communication between my server and client side.
I wan't to build one server using graphql to provide the same data for every client side access. Because every client needs to see the exact same data set as everyone else.
And i want to try to cache the last fetched data from the Database until there is a reason to access the database again.
For example:
When client one requests a list of books i want the server to cache the data.
So that when client two does the same request it just gets the data that was last fetched
from the database.
Its on my part to make sure the internal cache will be erased when the database table changed. But i don't want to request the Database every single time just to get the same answer 20 times in a row.
Is there a good way to cache the data inside the server ?

Related

Node.js: Is there an advantage to populating page data using Socket.io vs res.render(), or vice-versa?

Let's say, hypothetically, I am working on a website which provides live score updates for sporting fixtures.
A script checks an external API for updates every few seconds. If there is a new update, the information is saved to a database, and then pushed out to the user.
When a new user accesses the website, a script queries the database and populates the page with all the information ingested so far.
I am using socket.io to push live updates. However, when someone is accessing the page for the first time, I have a couple of options:
I could use the existing socket.io infrastructure to populate the page
I could request the information when routing the user, pass it into res.render() as an argument and render the data using, for example, Pug.
In this circumstance, my instinct would be to utilise the existing socket.io infrastructure; purely because it would save me writing additional code. However, I am curious to know whether there are any other reasons for, or against, using either approach. For example, would it be more performant to render the data, initially, using one approach or the other?

Where do I store my non-private data in a React App?

So I'm trying to make a full website for the first time, e-commerce. Of course the user data should be stored in database, and reached by a backend like nodejs. But what about the non-private data, like all the products.
Is there any difference between having all the products as an object inside my react code, in a like Product.js file vs Having all the products on the server, and fetch them ? Which one is recommended ?
One difference I can think of is, fetching them from database would make the initial load of the website faster, since the user isn't downloading all the data until they visit products page. But that can be achieved with react's built in lazy loading anyways.
So which one of those is recommended ? And why ? Thanks.
option1- Keep products as object in frontend. And use lazy loading so user doesn't download all products only if they visit products page, instead of the initial visit.
option2- Fetch them from database to frontend directly. Normally bad practice but; from a whole different, second database. The firebase database for example. The other database (mongodb) which has private data will never be accessed from the front-end.
option3- Fetch them from database -> to backend -> to frontend. I'm guessing this approach isn't good because it would make the load quite slow ?
Option 3 is likely the best for your use case. The additional latency incurred by going through the backend server is going to be negligible at worst, possibly a couple of milliseconds (provided the database and backend server are closely located, i.e. within the same datacentre).
A public firestore instance could work well, however there doesn't seem to be any good reason to complicate the stack and have two databases. If you are going to use a mongodb database anyway, you may as well commit to this route. Exposing your data via an API running on a backend server is always preferable in this case. In the simplest case, you would just have API routes returning the data in the "products" table. However in the future the advantages of this approach will show, for example; what if you want to restrict certain products to a release date, prevent certain users from seeing specific products. Both of these examples could be achieved through access-control managed by your backend server, acting as a "gatekeeper" to the data held within your database. Likewise you can implement rate limiting etc.
You could make use of Next.js or some other SSR (server-side rendering) technology to pre-render the page with product information embedded within the initial HTML document. This would save you the second round trip time after page load. It would also mean google search, embedded links in apps like twitter messenger etc would have the correct product metadata to display in the preview.
Normal AJAX request:
HTTP GET
Client ------------------> Frontend Server
HTML |
Client <------------------ Frontend Server
products_request
Client ------------------> Backend Server
| database query
Backend Server ------------------> mongodb
product_data |
Backend Server <------------------ mongodb
products_data |
Client <------------------ Backend Server
Next.js:
HTTP GET
Client ------------------> Frontend Server
|
|
| products_request
|
V database query
Backend Server ------------------> mongodb
product_data |
Backend Server <------------------ mongodb
|
| products_data
HTML page V
Client ------------------> Frontend Server
I would point you here for a more in-depth Node.js, Express, Mongodb tutorial if that is the stack you want to use.

Can making API calls and Database queries cause a bottleneck? Node.js and MongoDB

Frontend is React and Backend in Node.js.
Currently storing unregistered user carts in MongoDB using sessions (express-session and connect-mongo)
Now in the frontend, I'm making an API call every time a page loads to keep the mini cart on the top right updated. So basically every navbar rerender I'm making a call to the backend and querying to session in the database.
Is this the correct way of doing things or will this cause some stress on the backend since its been queried so much?
I'm still new to API call and database query costs etc. I just want this to cause a bottleneck.
It depends on if it's stateless or not. If it is we need to make continuous requests to the API, otherwise we can skip this step.

how to use cache data in mvc architecture

As the title suggest. I'm trying to figure out where I should cache data in my node.js application.
I'm using a express.js and controllers to handle the routes in the application. The controller for a particular route will get data via the model layer using REST API and then it uses handlebars for the view rendering on the server.
For this particular route, I'm displaying a menu and the data I have got for this has been done in the model and a remote REST call.
When the user select different items in the menu, I do not want to make a new REST call to get the same data for the menu again, I just need to get the data for this menu once since it will never change.
I need to find out a way to cache it, but do not know where I should implement it?
Best Regards
You could just cache the response from the REST API or DB lookup using a memory-store like Redis or Memcached, both have good modules available on npm - (Redis, memcached).
You would need to attempt to fetch the data from the memory-store (in your controller), if no matching data was found, you would make the request to the API or database to get the data, and then store it in your chosen memory-store so future requests will hit the cache.
note: There are also some pure JavaScript caches available such as memory-cache or lru-cache if you don't want to add an additional application.

Posting Firebases's thirdpartyuserdata object to the server

I'm using Firebase and the SimpleLogin to allow users to login via Google, Twitter etc.
I'd like to use some of the thirdpartyuserdata object to create a user profile for my application which runs on Node.
Currently I'm posting this data to the server so that I can add to it and create the profile object, but I wondered if there's a better way of doing this - is there something I can call server side to get this thirdpartyuserdata without having to post it from the client?
Start by considering that your "server" is actually just another consumer of Firebase data. Since FirebaseSimpleLogin is simply a token generator with some fancy tools for doing OAuth, and because this happens completely client-side, there is nothing to consume about this.
If you want to consume the data at the server, you will either need to POST it, as you have done, or use Firebase to transfer the information. You'll find that a queue approach can save you a large amount of code, as this allows you to use Firebase as the API, and avoid creating RESTful services in Node, and all the baggage that comes with that.
The idea of a queue is simply that you push data into Firebase at one client and read it out (and probably delete it) at the intended recipient (in this case your node worker).

Resources