How does an api compare to directly querying your database - node.js

I am kind of confused about when an API is needed. I have recently created a mobile app with flutter and cloud firestore as the database where i simply queried and wrote to the database when needed. Now i am learning full stack web development and I recently watched a tutorial where he built like an Express API with GET, POST, and DELETE functionality for a simple item in the database.
Coming from a background where i just directly accessed the database i am not sure why an API in this case is necessary, is it so I wouldnt have to rewrite the queries every time? This is a very simple project so he's definitely not making a 3rd party api for other developers to use. Am i misunderstanding what an API does exactly?
It was really simple, there was one collection in a MongoDB database and he was using postman to read and write to and from the database to check if it works.

API is a standard way with which your front-end (web/mobile) stores/gets information for your application. Your front-end can/should not directly access database ever. Understand the purpose of front-end which is to just display the interface and should do minimal processing. All the application logic should be at your backend (API server) which is exposed to your frontend via API (GET, POST etc) calls. So to store an item in your database, you will write data storing logic in your backend, and expose an API end-point which when triggered will perform the storing operation. That API call should be used by your front-end to trigger the storing process. In this way your logic of storing/database or any other thing is not exposed, only the API URL is. The purpose of front-end is to be exposed whereas backend/database should never be exposed and used from front-end

May be for you, an API is not necessary. But, the use-cases of an API is a lot.
For example:
You don't have to write business logic for every platform. (iOS, Android, Web, Whatever)
Your app will be lightweight since some computation would be offloaded to server.
Your app can be reverse engineered to get secret informations. (or, Your secret algorithm may be?)
What if you need to store something in filesystem that you want share with others?
Also a good read: Why we should use REST?

In your case, you are using a pre-written SDK which knows how to connect to Firestore, does caching and updates application data when needed, and provides a standard method of reading, writing and deleting data in Firestore (with associated documentation and example data from google).
Therefore, using an API (as described for the mongoDB) is not required and is undesirable.
There are some cases where you might want to have no read or write access to a firestore collection or document, and in this case, you could write a cloud function which your app calls with parameters, that receives the data that you want to write and does some sort of checking or manipulation beyond the capabilities of cloud firestore rules (although these can get pretty sophisticated). See https://firebase.google.com/docs/firestore/security/get-started
Todd (in the video contained in this link) does a few good videos on this subject.
However, this is not really working in the same was as the API you mentioned in your question.
So in the case of using Firestore, you should use the SDK and not re-invent the wheel by creating your own API.
If you want to share photos for example, you can also store them in firebase storage and then provide a URL for other devices to access them without your app being installed.
If you want to write something to firestore which is then sent to all other users then you can use listeners on each app, and the data will be sent to the apps after it arrives at Firestore.
https://firebase.google.com/docs/firestore/query-data/listen gives an overview of this.
One thing to always look at with firebase is the cost of doing anything. Cloud functions cost more than doing a read of a firestore document.
This gives an overview of pricing for different capabilities within the firebase set of capabilities.
https://firebase.google.com/pricing

Another most important factor is coupling. To add to #Dijkstra API provides a way to decouple the logic from each other, thus allowing for more application reliability, maintainability, fault-tolerance and if required scalability.
Thus there is no right or wrong here, or the comparison of API vs DB call is in itself not justified for the fact that fetching the data from Database is the ultimate aim. Even if you use a REST API or Query a database.
The means to achieve the same can differ based on specific requirements. For example, fetching water from the well.
You can always climb down the well and fetch a bucket of water if you need 1 bucket per day and you are the only user.
But if there are many users you would want to install a pull and wheel where people use it to pour fetched water into their bucket, yet again this will depend if there are 100 users per day using or more than that. As this will not work in the case of more than 100 users.
IF the case is that an entire community of say 1000 user are going to need the water you would go with a more complex solution of installing a motorized water pump to pump out the water and supply it to the user's home via a pipeline. This solution has many benefits like fast supply, easy to use, filtered water, scheduled, etc. But the cost and effort to achieve the solution is higher as well.
All in all, It comes down to the cost-vs-benefit ratio which you and only you can chart out, for different solutions vs the particular problem, as you are the best judge of scale and future user flow.
While doing that you can ask the following question about the solution to help decide :
Is the solution satisfying the primary requirement of the problem?
How much time is it going to take to build it?
For the time we spend to build a solution, is it going to working at more than 75% or more of its capacity?
If not is there a simpler solution that I can use to satisfy the problem and scale it as the requirement increases?
HTH.

Related

Social Network development in node.js and mongoDB

I want to know following things so that I can fix my server architecture and make it more flexible.
Is it good to store home feed data [ex: Facebook homeFeed] to the variable for future manipulation or just fetch data related to homeFeed and manipulate everything which needs to be done on run time.
Please note that data set of home feed can contain anything. [ not developed yet ]
Is there any limit to request to MongoDB at any given time which can create a delay in data processing?
Are node.js and MongoDB a good option for social network development?
If you know anything related to social network development then please share the pros and cons.
Is it good to store home feed data [ex: Facebook homeFeed] to the variable for future manipulation or just fetch data related to homeFeed and manipulate everything which needs to be done on run time.
You can (and sometimes should) pre-compute home feed data for certain users (for example those who are the most active). You don't store that in a variable though, you cache the results with something like Redis.
Generating the home feed on a "request" basis is also possible and good.
Both approaches require careful thinking about your system's architecture, performance, scalability, robustness, fault-tolerance, etc...
Is there any limit to request to MongoDB at any given time. which can create a delay in data processing?
Yes. A MongoDB instance (or any other database) has limited resources. Look at the Sharding and Replication docs of MongoDB for more info about how to work with MongoDb at scale.
Are node.js and MongoDB are a good option for social network development.
Node.js and MongoDb are a good combinations for quick prototyping, you can get productive fairly quickly. Any language(s) you are familiair with is/are a good choice here, since your focus seems to be on architecture. Go, Java and PHP are good candidates too.
In the real world social networks are built with a lot more tools than that. Since the teams use various programming languages, databases and frameworks depending on the task at hand.

How to serve node.js service for worldwide customers and fast?

I have a local VPS that hosting and providing my Node.js REST API in my country.
However soon I will need to open it for different countries.
That means that clients from remote will ask for my services.
Since they are far it will be probably slow connection.
How can I avoid this? Maybe I need more servers located in their countries too, but still, how the data could be shared over one DB?
I do not looking for a full tutorial for how to do that (could be nice to have) but I am looking for get info about the methodology of this.
What do you recommend to do, keep buying servers in remote countries, sharing their data between them someway, or maybe choose to use some cloud service like Firebase? How cloud services work in first place?
Without going into too much detail for each item, here are some keypoints in which I think you should focus your on learning to solve your problem.
For data storage - look into firestore (not the json database) as firestore is globally scaleable.
For your REST endpoints I would use google cloud functions, but without knowing the nature of your application its hard to say if its suitable. The key to being able to reach global scale is having cacheable endpoints. Then you are leveraging google's global CDN which is much faster than hitting the origin server. Note: The firebase cloud functions infrastructure WILL face cold start issues which may/may not be a problem for you.
Cache invalidation is a little lacking so you can leverage longer max-age cache settings but use either cache busing and/or the header stale-while-revalidate to help with this.
There is some great info here https://www.youtube.com/watch?v=dbV-293m1dQ that covers some of what I have mentioned in more detail.

Is a backend API using node, mongo to slow for front end client to get results for live suggestions?

I want to write a series of small apps for myself as micro services. This is for practicality and self learning. I want these apps to be able to work independently, but build a separate frontend client that has a search bar that can find data across all of the services. I wanted to implement a live autocomplete with search results as the user is typing that will search across multiple databases.
My current approach was to split each app into two apps, backend API, and a frontend client. Have a common auth service that all of the apps utilize for authorization.
I think this approach would work fine except for speed and performance, which I am not sure about. It is a personal requirement of mine to be able to implement this search bar with autocomplete search results. This means it will have to make API requests to each service to get those results, it just feels like it might be too slow.
Also, in case anyone is wondering, I was planning on using node, express, and mongodb for backend. Probably go with node, express, vue or something for the front end.
Q. Does anyone have personal experience with the performance aspect of working with multiple APIs?
Q. If this approach is too slow, is there a better approach that still allows for a separation of the applications?
The performance will be depending on so many other factors before/with the number of rest calls. It is really hard to say anything beforehand.
But according to my previous experience if you need to provide such a search functionality for a autocomplete feature you may most likely need elastic search for that.
That means instead of sending a request to each and every service for each autocomplete request you should have an index to search in (partial or maybe all data you need to show in your frontend) and search that index first to find the corresponding items then ask for the remaining/full data to other services if necessary. Details are totally depends on your requirements.
Of course if you go that way you should also implement a data population/syncronization mechanism to elastic search.

How to write a "middleware" in Node.JS

Apologies if this question is too general. This is not an invitation for "opinion-based" answers. Unfortunately, at this stage of the project and with my limited knowledge in this space, I just need some guidance from more experienced people.
In a large company project, I have a web service that is based on NOSQL data models. I have little influence over the design of this service. Due to the data structure, when overseeing the development of a large and complex mobile app (for multiple platforms), I noticed that sometimes it was necessary to make calls to multiple endpoints in sequence to get the required information.
For example: there is the need to first call an endpoint sending certain parameters to get a user ID, then use that user ID to get details about the user. The system cannot deliver the user details on the first call. This leads to complex data parsing and background processes on the clients.
To simplify mobile development, we now want to build a "middleware" layer that simplifies the API for the mobile clients. The app would call the middleware as the single point of entry, the middleware would call the existing endpoints to gather the necessary data and deliver the result back to the client.
For example, the client would ask for finding a certain user and delivering certain attributes of this user (e.g. the first names of all friends of the user) with one API endpoint. The middleware would need to make many calls to the backend: search for the user, use the result (user ID) to get details and friends of the user, use the delivered friends' userIDs to gather data about the friends. Then the middleware would package the information and deliver it back to the client.
Initial recommendations from colleagues indicate that Node.JS would be a good framework for developing this type of functionality in a maintainable, scalable way.
OK, I know how to run a simple server and manage routes on a node system, but how would you organize this project, e.g. the file structure? Which components would you encapsulate. Are there any frameworks on top of Node that would help with a task like that?
I am not looking for "opinions", just for some insightful recommendations based on experience or knowledge. Feel free to down-vote this question after you have stated what you do not like about it and have asked specific questions to clarify (I will comply as soon as possible). Thanks.
how would you organize this project, e.g. the file structure?
I have described my filesystem layout in my express code structure github repository, which is also posted as a stackoverflow answer here
Which components would you encapsulate.
I think it's OK to encapsulate the interface to each backing API as a "model" or "service" type module. If you are making database queries, encapsulating those either into models or at least modules of related queries is OK.
Are there any frameworks on top of Node that would help with a task like that?
Yes, many. I prefer express as the basic web app framework with hapi being the other strong choice. There are other options both smaller (more 1-purpose libraries) and larger (closer to full-featured frameworks) like loopback or sails.js.

Send requests directly to couchDB from NodeJS/Angular application?

I'm currently building a new web-application with user registration, profiles, image upload and so on. I was using the MEAN stack (MongoDB, ExpressJS, Angular, NodeJS) for previous projects and now want to try out couchDB.
couchDB delivers a REST-API for free. I could shift all the logic to the client and make sure, that the input is valid by couchDBs validation functions. Therefore I could make the requests from client directly to the database and I would not have to code annoying things like CRUD Operations in my expressJS controllers. Authentication, Validation and simple CRUD operations - it's all there and for free.
Is there a reason not to do so? I would then pass the request to my server and then pass it on to the couchDB from there, which pretty much eradicates all the nice benefits over mongoDB.
greetings,
Michel
I think your proposal is at least theoretically true and you might want to go ahead and do it, perhaps forwarding requests from the browser to couchdb with a reverse proxy like nginx or node-http-proxy. I believe there are products on the market espousing this "no application server" architecture such as parse.com, which provides some social proof that this idea is at least interesting and worth exploring.
However I think you will at some point discover there is such a thing as an application server and people use them and write code for them in nearly every application for good reason. Debugging problems with your couchdb data validation code is probably going to be cumbersome at best. Compare that to the amazing features you have debugging node.js code with node-inspector and the chrome developer tools debugger.
couchdb is also probably not going to provide realistically granular enough authorization capabilities. This means eventually your application will be exposed to malicious users just doing a PUT with the right document id and gaining access to data they are unauthorized to see or change.
Very few applications are simple enough that UI + DB can handle all of the data transitions and operations that are needed. You could in theory code some of this logic in the browser, but having the Internet between your compound query logic and your database is going to add so much latency to your app to make some features impossible, especially if you have to do a query, get some results, then do a secondary query based on each of those results. That is sometimes feasible between a server-side application and its couchdb, but doing that across the Internet will suffer from the latency.

Resources