How to enable gzip at GraphQL server? - encoding

According to the this article, it's encouraged that any production GraphQL services enable GZIP and encourage their clients to send the header: Accept-Encoding: gzip
I've tested this in Postman, with "Accept-Encoding" enabled or disable, I didn't see any difference in the responded "content-length".
So my question, how to enable GZIP encoding at graphQL server?

Q: How to enable GZIP encoding at graphQL server?
A: Short answer, you can't.
Why? Because GraphQL is just a library for parsing your graph queries and calling the appropriate functions, supplied by you, to build out a graph response.
It is not about compressing your HTTP response and making sure that the response has the Content-Type=Gzip header in it.
In other words, what that piece of document is trying to say is that the GraphQL response looks pretty much like JSON and therefore they work well when compressed. Mainly because raw graph responses can be quite bloated in size and it is inefficient and slow to transfer them across the network.
Just in case your HTTP server for graphql is implemented in NodeJS, you can use the zlib to do the compression. See documentation.
If you are the majority of people who uses theexpress framework for NodeJs then it is even more easier as there is a compression plugin for it already. See here.

Related

Opinions on using Flatbuffer in REST

I was wondering what the general opinion was about using different serialization methods for REST APIs. JSON and XML are the most popular but I was wondering if serialization in Flatbuffers might be a possible alternative.
Deserialization on the server side is technically cheaper than JSON (the big win is "zero-copy" reads and fast serialization responses on larger servers). On the client browser FB serialization would be slower than JSON (JSON serial/deserial is implemented natively) but I think that's minor given that the datasets are extremely small the user wouldn't notice a difference anyways.
I imagine REST purists would say this is taboo. The downsides would be:
Tooling for reading FB in REST isn't quite there
Client-side performance with larger datasets isn't as performant
MIME type sent would be application/octet since FB doesn't have its own MIME yet
This thought came from the fact that I'm using FB in gRPC and now have to accept requests via browser. Transforming from REST adds an extra serialization step (if I took a similar approach to using gRPC-Web).
There is nothing about REST that specifically dictates or suggest any mimetype. REST predates JSON, so purists definitely should not call this taboo =)

Using Accept request header to branch on JSON vs html

Looking at using the http Accept header to branch if the server should return html or json of a resource. I was thinking of just using:
Accept: application/json
But further research and reading the GitHub API, the standard seems to be:
Accept: application/vnd.company.app+json
What is the advantage of doing this? Why not just use application/json without the vendor prefix of company and app?
The major difference is that application/json is a generic definition. Just because a request document is formatted as "application/json" doesn't mean that it could still be consumed by your application.
For the most part, on the server side you'd find yourself registering your media-type as being provided by your generic serialisation/deserialisation library (e.g. Jackson), so there's very little practical difference which it makes - if the provided document is not deserialisable to the the class you're expecting then there'll be an exception which will duly get turned into a 40x response code.
However, it's useful to be sure that both your server and your client expect to be speaking the same language. That can be logged and it can help to locate problems, either from external clients who expect an 'old' version of the API or from internal issues relating to incompatible client-server combinations.

Passing array in GET for a REST call

I have a url to fetch appointments for a user like this:
/user/:userId/appointments
How should the url look like if I want to get appointments for multiple users?
should it be:
/appointments?users=1d1,1d2..
Thanks,
Chris.
Collections are a resource so /appointments is fine as the resource.
Collections also typically offer filters via the querystring which is essentially what users=id1,id2... is.
So,
/appointments?users=id1,id2
is fine as a filtered RESTful resource.
Another way of doing that, which can make sense depending on your server architecture/framework of choice, is to repeat the same argument over and over again. Something like this:
/appointments?users=id1&users=id2
In this case I recommend using the parameter name in singular:
/appointments?user=id1&user=id2
This is supported natively by frameworks such as Jersey (for Java). Take a look on this question for more details.
I think it's a better practice to serialize your REST call parameters, usually by JSON-encoding them:
/appointments?users=[id1,id2]
or even:
/appointments?params={users:[id1,id2]}
Then you un-encode them on the server. This is going to give you more flexibility in the long run.
Just make sure to URLEncode the params as well before you send them!
This worked for me.
/users?ids[]=id1&ids[]=id2
/appointments?users=1d1,1d2..
is fine. It's pretty much your only sensible option since you can't pass in a body with a GET.
Instead of using http GET, use http POST. And JSON. Or XML
This is how your request stream to the server would look like.
POST /appointments HTTP/1.0
Content-Type: application/json
Content-Length: (calculated by your utility)
{users: [user:{id:id1}, user:{id:id2}]}
Or in XML,
POST /appointments HTTP/1.0
Content-Type: application/json
Content-Length: (calculated by your utility)
<users><user id='id1'/><user id='id2'/></users>
You could certainly continue using GET as you have proposed, as it is certainly simpler.
/appointments?users=1d1,1d2
Which means you would have to keep your data structures very simple.
However, if/when your data structure gets more complex, http GET and without JSON, your programming and ability to recognise the data gets very difficult.
Therefore,unless you could keep your data structure simple, I urge you adopt a data transfer framework. If your requests are browser based, the industry usual practice is JSON. If your requests are server-server, than XML is the most convenient framework.
JQuery
If your client is a browser and you are not using GWT, you should consider using jquery REST. Google on RESTful services with jQuery.

REST vs. SOAP for large amount of data with Security

I have a requirement where I have large amount of data(in form of pdf,images,doc files) on server which will be distributed to many users. I want to pull these file using web services along with their meta-data. I will be getting the files in bytes. I am confused in which type of web service will be more secure, easy to parse? Which one is easy to implement on iPhone client?
I know REST is simpler but I read somewhere that it is not suitable for distributed environment. At the same time SOAP is too heavy for mobile platform.
I have searched many sites describing how REST is easier and how SOAP is secure. I got confused about which one to use?
Also about the kind of response, which will be better JSON or XML for my requirement?
For your requirements JSON will be the best kind of response because it is way smaller than XML (More than 50% smaller in many tests). You can use SBJSON (https://github.com/stig/json-framework/) to parse it easily on iOS.
Concerning REST or SOAP, the last one is indeed really heavy for mobile platform and not so easy to implement. SOAP requires XML too and cannot be used with JSON. Whereas with REST you can use JSON or XML and easily implement it on iOS with RESTKit (http://restkit.org/), for security you can use an SSL connection with HTTPS and a signed certificate.
The only advantage of SOAP is the WSDL (Webservice specification) which made your webservices really strong.
Unless you have a specific requirement to pull the file data and the metadata in the same response, you might consider just pulling down the file with a regular HTTP GET. You can get decent security with HTTPS and Basic Auth or client certificates. I would then include a Link header pointing to the metadata for your file, as in:
Link: </path/to/metadata>;rel=meta
In particular, this lets you have separate caching semantics for the file itself and for its metadata, which is useful in the common case where the files are much larger than their metadata and where metadata can change without file contents changing.

Using NSStream to communicate with PHP?

I'm working on an iPhone project that needs to receive data from a PHP script during execution. My first thought was to use sockets/streams on either end to connect the two, but I am having trouble finding information on how to do this from the iPhone side.
Has anyone been down this path that could point me towards some useful resources or offer some advice? The official documentation seems to be geared more towards desktop apps and uses code that doesn't seem to be supported on the iPhone (namely NSHost).
Update: The intended use of this app is to receive log messages from an executing script, so I can't use a simple HTTP request with JSON or XML. Many cases will involve the page being loaded by another client, where the script would relay/push log messages to the iPhone.
Polling is evil. You'll chew through batteries doing that.
You might consider running an HTTP server on the iPhone. Check out this blog post; it has an implementation of an HTTP server in Cocoa as well as example code for using it for two-way communication.
The PHP CURL library (can't link it because the site doesn't trust me yet, just search php.net for it) is a (relatively) simple, easy way to make http requests with a PHP script.
Why don't you just use HTTP? Create an ad-hoc protocol with XML or JSON, use POST for upstream data transmission. I'm a fan of JSON for this sort of thing, personally. The PHP, instead of returning a webpage in HTML for rendering, should just return your data in a JSON format.