GraphQL/Apollo application with file download from server - reactjs

I'm a little new to GraphQL and this question falls under "It cannot possibly be this hard. I have to be missing something."
I have a fairly standard GraphQL/Apollo/React application split into client and server. Everything is working well with the client making API calls and getting data back from the server. The client is even able to upload files to the server. However, I now need the server to stream back files saved on disk. That's it.
This is the "I have to be missing something" part. Everything I've seen in the docs and on Stackoverflow is some variation of pushing the file back from the server and through the GraphQL query as a base64-endocded string and then doing some very hacky stuff on the client, often involving a hidden href tag and a simulated click. To this I say, "What???"
Seriously. There are files on disk that the server knows how to find. The client needs to show a button to the user that they can click on to download the file. That's it. Every other framework in every other language has an easy way to do this. Can someone show me the incredibly simple thing that I'm missing here?
Thanks,
Alex

What you're missing is that GraphQL really shouldn't be used for this purpose.
While GraphQL itself does not specify a specific format for serializing responses, the de facto format is JSON. And the only way to get the file inside a JSON response is if it's serialized as a string.
If you want to serve static content, you should set up Nginx, Apache or another web server that's been built with that in mind. Alternatively, if you're already using some existing web server library like Express, it most likely has tools for serving static content as well.
Just because you have a GraphQL endpoint does not necessarily mean it should be the only way your client communicates with your backend.

Related

SSR vs CSR explanation

I've been working as a full stack web developer for over a year now. Nextjs/golang is our stack. Today I realized that I have no idea whether we use CSR or SSR. I think we use CSR but I'm not sure. I've gone down rabbitholes on this topic like 100 times but its never stuck.
First question:
When they say server side, do they mean on the backend? i.e. golang? or does that mean on the nextjs server? Whenever someone says server I think backend but I don't think this is correct.
Second question:
How does client side rendering work? Like I know the server sends javascript to the client then the client uses the javascript to build the page. But all of this javascript must make a bunch of requests to the server to grab data and html right? Like how would the javascript build the page otherwise? Is this why react/nextjs is written in jsx? So the server can send all the JSX which is actually just javascript to the client then the client can build the html?
Third Question:
If CSR has the client build the page, how would this ever work? Like what about all of the data that needs to be pulled from our database for specific users / etc etc. That can't be done directly from the frontend.
I tried reading tons of articles online! Hasn't clicked yet
You said the essential thing yourself: in client-side rendering, "the server sends javascript to the client, then the client uses the javascript to build the page." Hold on to that one point – everything else is secondary. The client "renders."
Now that "client-side" rendering capabilities have become so powerful – and, so varied – it has generally become favored. If you "tell the client what to do and then let him do it," you are more likely to get a consistently favorable outcome for most clients. Yes, the client will issue perhaps-many AJAX requests in carrying out your instructions. That is irrelevant.
CSR - server sends HTML that contains links to javascript (script tags). Clients then loads and executes JS (JavaScript typically contains fetching code). That means that each client will perform several round trips to the server to get HTML and then the data.
SSR - server sends HTML and embeds the necessary data in it
The client already has the data and HTML, so it can render it. SSR does fetch on each request, meaning the client still gets the latest data.
Benefits of using SSR compared to CSR is lower load time, it makes the website feel "faster" and also improves the ranking by search engine bots. On the other hand, the server does the rendering, which increases its burden (though fewer requests decreases it).
SSG is the same as SSR but fetching occurs at build time, the result page is computed only once and returned for each request. It is possible to use SSG with or without data.
Use SSG if possible, then mostly SSR. In some occasions it may be better to use CSR instead of SSR, though I'm not experienced enough to give the answer when.
Now answering your questions:
Yes, SSR happens on the server. If you use fetch function then it will work on client. But if you use getServerSideProps or getStatisSideProps then it will work on server. You can read from the file system, fetch public API or query the database, whatever you do in getStatisSideProps, getServerSideProps will run on the server, before returning the response.
Yes, you're correct. Client need the data to render the page, so it has to send requests to server and then render.
The third question is the same as the second. I hope the long answer I gave clarified your confusion.
Sorry for long answer.

Best practices for model validation using a REST API and a javascript front-end such as Angular

I'm transitioning towards more responsive front-end web apps and I have a question about model validation. Here's the set-up: the server has a standard REST API for inserting, updating, retrieving, etc. This could be written in Node or Java Spring, it doesn't matter. The front-end is written with something like Angular (or similar).
What I need is to figure out where to put the validation code. Here's the requirements:
All validation code should be written in one place only. Not both client and server. this implies that it should reside on the server, inside the REST API when persisting.
The front-end should be capable of understanding validation errors from the server and associating them to the particular field that caused the error. So if the field "username" is mandatory, the client can place an error next to that field saying "Username is mandatory".
It should be possible to validate correct variable types. So if we were expecting a number or a date and got a string instead, the error would be something like "'Yo' is not a correct date."
The error messages should be localized to the user's language.
Can anyone help me out? I need something simple and robust.
Thanks
When validating your input and it fails you can return a response in appropriate format (guessing you use JSON) to contain the error messages along with a proper HTTP error code.
Just working on a project with a Symfony backend, using FOSRestBundle to provide proper REST API. Using the form component of Symfony whenever there's a problem with the input a well structured JSON response is generated with error messages mapped to the fields or the top level if for example there's unexpected input.
After much research I found a solution using the Meteor.js platform. Since it's a pure javascript solution running on both the server and the client, you can define scripts once and have them run on both the client and the server.
From the official Meteor documentation:
Files outside the client, server and tests subdirectories are loaded on both the client and the server! That's the place for model definitions and other functions.
Wow. Defining models and validation scripts only once is pretty darn cool if you ask me. Also, there's no need to map between JSON and whatever server-side technology. Plus, no ORM mapping to get it in the DB. Nice!
Again, from the docs:
In Meteor, the client and server share the same database API. The same exact application code — like validators and computed properties — can often run in both places. But while code running on the server has direct access to the database, code running on the client does not. This distinction is the basis for Meteor's data security model.
Sounds good to me. Here's the last little gem:
Input validation: Meteor allows your methods and publish functions to take arguments of any JSON type. (In fact, Meteor's wire protocol supports EJSON, an extension of JSON which also supports other common types like dates and binary buffers.) JavaScript's dynamic typing means you don't need to declare precise types of every variable in your app, but it's usually helpful to ensure that the arguments that clients are passing to your methods and publish functions are of the type that you expect.
Anyway, sounds like I've found the a solution to the problem. If anyone else knows of a way to define validation once and have it run on both client and server please post an answer below, I'd love to hear it.
Thanks all.
To be strict, your last gate keeper of validation for any CRUD operations is of course on server-side. I do not know what is your concern that you should handle your validation on one end only(either server or client), but usually doing on both sides is better for both user experience and performance.
Say your username field is a mandatory field. This field can be easily handled in front-end side; before a user click submit and then been sent to the server and then get returned and shows the error code. You can save that round trip with a one liner code in front-end.
Of course, one may argue that from client-side the bad guys may manipulate the data and thus bypassing the front-end validation. That goes to my first point - your final gate keeper in validation should be on your server-side. That's why, data integrity is still the server's job. Make sure whatever that goes into your database is clean, dry and valid.
To answer you question, (biased opinion though) AngularJS is still a pretty awesome framework to let you do front-end validation, as well as providing a good way to do server-side error handling.

Mobile application backend

I'm currently developing a mobile application that will fetch data from server by request (page load) or by notification received (e.g. GCM).
Currently I'm starting to think about how to build the backend for that app.
I thought about using PHP to handle the http requests to my database (mySQL) and to return the response as JSON. As I see it there are many ways to implement such server and would like to hear to hear thoughts about my ideas for implementations:
1. create a single php page that will receive an Enum/Query, execute and send the results.
2. create a php page for every query needs to be made.
Which of my implementations should I use? if none please suggest another. Thank you.
P.S, this server will only use as a fetcher for SQL and push notifications. if you have any suggestion past experience about how to perform it (framework, language, anything that comes to mind) I'd be happy to learn.
You can use PHP REST Data services framework https://github.com/chaturadilan/PHP-Data-Services
I am also looking for information about how to power a web and mobile application that has to get and save data on the server.
I've been working with a PHP framework such as Yii Framework, and I know that this framework, and others, have the possibility to create a API/Web service.
APIS can be SOAP or REST, you should read about the differences of both to see wich is best for mobile. I think the main and most important one is that for SOAP, you need a Soap Client library on the device you are trying to connect, but for REST you just make a http request to the url.
I have built a SOAP API with Yii, is quite easy, and I have use it to communicate between two websites, to get and put data in the same database.
As for your question regarding to use one file or multiple files for every request, in the case of SOAP built on Yii, you have to normally define all the functions available to the API on the server side in only one file(controller) and to connect to that webservice you end up doing:
$client=new SoapClient("url/of/webservice);
$result=$client->methodName($param1, $param2, etc..);
So basically what you get is that from your client, you can run any method defined on the server side with the parameters that you wish.
Assuming that you use to work program php in the "classic way" I suggest you should start learning a framework, there are many reasons to do it but in the end, it is because the code will result more clean and stable, for example:
You shouldn't be writing manual queries (sometimes yes), but you can use the framework's models to handle data validation and storage into the database.
Here are some links:
http://www.larryullman.com/series/learning-the-yii-framework/
http://www.yiiframework.com/doc/guide/1.1/en/topics.webservice
http://www.yiiframework.com/wiki/175/how-to-create-a-rest-api/
As I said, I am also looking to learn how to better power a mobile application, I know this can be achieved with a API, but I don't know if that is the only way.
create a single php page that will receive an Enum/Query, execute and send the results.
I created a single PHP file named api.php that does exactly this, the project is named PHP-CRUD-API. It is quite popular.
It should take care of the boring part of the job and provides a sort of a framework to get started.
Talking about frameworks: you can integrate the script in Laravel, Symfony or SlimPHP to name a few.

Open and Save Word files through internet

I have a situation that override my knowledge. Here is situation:
A simple web based system store a Word files. Users create them locally, then upload them to server. After that, another user can download, edit and upload again. All that is okay, but that steps of repeating Download/Upload cause troubles - in case when user forgot to upload after he make changes. The prerequisites is that they want to use only Word, so i can't use any web editors like CKEditor or Google Documents.
So - a question - is there a way to let users open/save that DOC files with Word without setting a VPN?
Server is a Windows 2008, and language is ASP.NET / classicASP. User access system via browsers.
I think you can embed a plugin called aceoffix in your web system, if the customers do not have to download, upload and save back to server. With aceoffix they can edit online and save back to the server directly. It is exactly the same interface as MS Office. Hope this will be helpful.
How about a tiny app (on clients) to act as a syncronizer (using FTP) ?
I think an embedded Word viewer would be something quite complex to pull off - especially if they require the native, proper and exact Word look/menus.
One alternative is to provide a plugin to your users, where they can access/sync documents directly from/to the server. But then you aren't using the a web site but a local plugin, which comes with its own headaches of course.
Creating a Word plugin is a nice way to make it seem like something "in the Office program" when you have actually created it yourself, so that your user don't have to feel like they are using another program. My idea is that you could create a way for users to load a Word file from the server, do changes to it and then upload them back to the server automatically.

How can a server communiate with two clients at once (JavaScript, HTML, PHP)?

I got an assignment to do and for that I could use any www technology like HTML, JavaScript, PHP etc. I'm really sorry to say that I haven't studied any of these technologies. Therefore I took few tutorials and skimmed through them searching for answers.
I found solutions for many problems but one problem yet unsolved. It is this:
I want two clients to communicate through a server for this assignment. One send a message, server processes it and forwards it to the next.
None of PHP tutorials showed me anyway of doing this. All of them talked of communication between one client with a server.
Please help. Show me a way to do this. Thanks.
Currently, without reverting to cutting-edge (and possibly hacky/unreliable) techniques, your PHP server cannot initiate communications with a page you've already loaded into a web browser. This is a result of the way the HTTP protocol works.
One way to solve this would be polling on the "receiving" end for data. Something like a publish-subscribe pattern.
One way to do this would be:
One client sends data to the server using an HTTP request (XHR aka AJAX) specifying the target for this data (the other client).
The server stores this data in a persistent storage (local file, database, etc).
The second client periodically sends a request to the server asking if there's any new data for it to consume. This can be done using setInterval and XHR in JavaScript.
I would suggest you take a look at:
http://en.wikipedia.org/wiki/Publish/subscribe
And also, for a cutting edge way to do this, check out Socket.IO:
http://socket.io
You might want to Google on "php chat server." Building a chat server is a simple way to get started.
http://net.tutsplus.com/tutorials/javascript-ajax/how-to-create-a-simple-web-based-chat-application/
http://code.jenseng.com/jenChat/

Resources