How does Apollo serve both the Sandbox's html and graphql query handler on the same endpoint simultaneously? - server

Can anybody explain how Apollo serves both the Sandbox's html and the graphql query handler simultaneously on the same route endpoint?
SPECIFICALLY, What protocol(s), method(s), and how is the body content used? Is this all done via headers? Thanks for the semi-technical deep dive.

Sandbox is served via GET, queries via POST

The answer is a bit more complicated. These blog posts: Making GraphQL Requests using HTTP Methods and Configuring CSRF Cross-Site Request Forgery prevention in the Apollo Router give an insight into GET and POST, along with nuances of headers in a GraphQL client/server context.
It seems the differentiator is a combination of headers and url query string that Apollo server "intelligently" interprets to return a graphQL result, or sandbox html.
This is a valid GET based query from the browser: http://localhost:4000/api/v1/pub?query={hello}
Excerpts:
GET METHOD
You can make GraphQL requests using the GET HTTP method. The rules for making GraphQL requests this way are almost the same as the POST version — there are just slight differences:
• Each property is provided as an HTTP query parameter (values separated by an ampersand — &)
• Limitation (variables): Because they need to be parsed as JSON, GraphQL requests with variables don’t work in GET requests.
• Limitation (operations): You can only execute query operations (mutation operations don’t work)
POST METHOD
To make a GraphQL request using the POST HTTP method, we pass the following properties into the JSON body of the request.
• query — the full GraphQL query containing the operation type (can be either query or mutation), the types & fields requested, and any variables included
• operationName — optional, but if included, must be present in the query
• variables — optional if there are no variables included in the query

Related

Sails can I use Actions2 for GET request

The issue
Can I use actions2 for GET requests with query params?
Example
https://path/filename?id=123&age=45
If this is the url in request, can I access each param as input.id and input.age?
I have not found many resources (basically only one) that show examples of this syntax being used for requests with query string parameters.
The github page redirects to a blog where they talk about the different methods one can apply actions2 syntax to, but does not directly display an example with a GET request
https://www.logisticinfotech.com/2018/sails-js-actions2-example-with-crud/.
The only online source that somewhat confirms this affirmation is the following:
how to get query parameter in action2 in sails.
I am a newbie in SailsJS so feel free to ask me additional information.
Yes, you can use Actions2 for any API request; PUT, POST, GET, etc.
Here is an example from a repo I open sourced: https://github.com/neonexus/sails-react-bootstrap-webpack/blob/release/api/controllers/admin/get-me.js
While the example isn’t using GET params, it would use the “inputs” section just like with a PUT.

POST method for RestHeart API

We know that RESTHEART API can provide data using GET method. But if the list of paramaters grows then GET Rest call will hit the limit.
Please confirm if we can use POST calls to fetch data via rest heart.
something like
GET /test/coll?filter={'title':{ << 1000s.. params >>}}
Here I am just illustrating the long list of parameters using << 1000 params >>
Regards,
Abhinav
RESTHeart strictly follows the HTTP protocol and the RESTful paradigm:
According to the RFC 261
POST
The POST method is used to request that the origin server accept the
entity enclosed in the request as a new subordinate of the resource
identified by the Request-URI in the Request-Line.
We have discussed between the community about allowing to GET data with a POST but rejected it.
Said that, your need is clear but it can be addressed with a RESTHeart custom Application Logic Handler.

Should I create a POST version of my GET REST endpoint in case the GET URI is too long?

I have a REST endpoint GET /api/rules. It takes several query parameters for filtering/querying, like type, name, owner, description, and tag. So you could end up with a URI like this:
GET /api/rules?name=rule1,rule2&owner=john,jane&description=VeryLongDescription
Specifically, I'm concerned that the description queried for could be very long and make the URI too long (I forget the limit). Should I create a POST version of this same endpoint for users that get a 414 URI Too Long response from the server?
I mean, generally speaking, when does it make sense to just make a POST that gets a resource? Anytime you introduce query params?
In theory URIs have no limits, but in practice they might be limited by implementations. If you have to circumvent limitations imposed by the implementation that are not inherent to the protocol, you should try to decouple them from your application.
If you're a purist, the more or less standard way of supporting functionality through the POST method is using the x-http-method-override header, which can be decoupled from your application if it's implemented as a request pre-processor. You can have the preprocessor convert the POST request to the GET request your application expects, converting the payload to a query string.
Here's an example of this approach in the Google Translate API: https://cloud.google.com/translate/v2/using_rest#Translate
If you're not a purist, or if that's too complicated for your users, or you don't want to use a custom header, I think it's fine to make a POST endpoint that gets a resource, as long as it's properly documented and the resource being queried is identified by the URI.

Restful web service GET request parameters

I'm using fiddler to test a Web API service I'm writing.
I know I can pass parameters to a RESTful web service in the querystring with a request like -
www.example.com/api/Book?Id=123&category=fiction.
Are there other ways of passing the parameters to the service, while still using a GET.
There are many parts of the HTTP request which you can use to pass parameters, namely the URI, headers and body. GET requests don't have bodies (some frameworks actually allow that, but they're not common so for all purposes, let's just assume that they can't), so you're limited to the headers and the URI.
In the URI you can pass parameters in different places:
Query string (as you're already doing)
Ex.: www.example.com/api/Book?Id=123&category=fiction
Request path
Many frameworks will allow you to get parameters to your actions from paths in the request URI. With ASP.NET Web API you'd typically do that using routing
Ex.: www.example.com/api/Book/fiction/123
In the fragment, or the part of the URI after the # character. See the URI RFC, section 3.5.
Ex.: www.example.com/api/Book?Id=123&category=fiction#somethingElse
You can also pass paramters in the HTTP request headers. One parameter which is honored by the ASP.NET Web API is the Accept header, which is used when doing content negotiation. You can also expect custom parameters from those headers, and read them in your actions (or even have value providers which will read them and map them to the parameters in the methods themselves).

HTTP POST with URL query parameters -- good idea or not?

I'm designing an API to go over HTTP and I am wondering if using the HTTP POST command, but with URL query parameters only and no request body, is a good way to go.
Considerations:
"Good Web design" requires non-idempotent actions to be sent via POST. This is a non-idempotent action.
It is easier to develop and debug this app when the request parameters are present in the URL.
The API is not intended for widespread use.
It seems like making a POST request with no body will take a bit more work, e.g. a Content-Length: 0 header must be explicitly added.
It also seems to me that a POST with no body is a bit counter to most developer's and HTTP frameworks' expectations.
Are there any more pitfalls or advantages to sending parameters on a POST request via the URL query rather than the request body?
Edit: The reason this is under consideration is that the operations are not idempotent and have side effects other than retrieval. See the HTTP spec:
In particular, the convention has been
established that the GET and HEAD
methods SHOULD NOT have the
significance of taking an action other
than retrieval. These methods ought to
be considered "safe". This allows user
agents to represent other methods,
such as POST, PUT and DELETE, in a
special way, so that the user is made
aware of the fact that a possibly
unsafe action is being requested.
...
Methods can also have the property of
"idempotence" in that (aside from
error or expiration issues) the
side-effects of N > 0 identical
requests is the same as for a single
request. The methods GET, HEAD, PUT
and DELETE share this property. Also,
the methods OPTIONS and TRACE SHOULD
NOT have side effects, and so are
inherently idempotent.
If your action is not idempotent, then you MUST use POST. If you don't, you're just asking for trouble down the line. GET, PUT and DELETE methods are required to be idempotent. Imagine what would happen in your application if the client was pre-fetching every possible GET request for your service – if this would cause side effects visible to the client, then something's wrong.
I agree that sending a POST with a query string but without a body seems odd, but I think it can be appropriate in some situations.
Think of the query part of a URL as a command to the resource to limit the scope of the current request. Typically, query strings are used to sort or filter a GET request (like ?page=1&sort=title) but I suppose it makes sense on a POST to also limit the scope (perhaps like ?action=delete&id=5).
Everyone is right: stick with POST for non-idempotent requests.
What about using both an URI query string and request content? Well it's valid HTTP (see note 1), so why not?!
It is also perfectly logical: URLs, including their query string part, are for locating resources. Whereas HTTP method verbs (POST - and its optional request content) are for specifying actions, or what to do with resources. Those should be orthogonal concerns. (But, they are not beautifully orthogonal concerns for the special case of ContentType=application/x-www-form-urlencoded, see note 2 below.)
Note 1: HTTP specification (1.1) does not state that query parameters and content are mutually exclusive for a HTTP server that accepts POST or PUT requests. So any server is free to accept both. I.e. if you write the server there's nothing to stop you choosing to accept both (except maybe an inflexible framework). Generally, the server can interpret query strings according to whatever rules it wants. It can even interpret them with conditional logic that refers to other headers like Content-Type too, which leads to Note 2:
Note 2: if a web browser is the primary way people are accessing your web application, and application/x-www-form-urlencoded is the Content-Type they are posting, then you should follow the rules for that Content-Type. And the rules for application/x-www-form-urlencoded are much more specific (and frankly, unusual): in this case you must interpret the URI as a set of parameters, and not a resource location. [This is the same point of usefulness Powerlord raised; that it may be hard to use web forms to POST content to your server. Just explained a little differently.]
Note 3: what are query strings originally for? RFC 3986 defines HTTP query strings as an URI part that works as a non-hierarchical way of locating a resource.
In case readers asking this question wish to ask what is good RESTful architecture: the RESTful architecture pattern doesn't require URI schemes to work a specific way. RESTful architecture concerns itself with other properties of the system, like cacheability of resources, the design of the resources themselves (their behavior, capabilities, and representations), and whether idempotence is satisfied. Or in other words, achieving a design which is highly compatible with HTTP protocol and its set of HTTP method verbs. :-) (In other words, RESTful architecture is not very presciptive with how the resources are located.)
Final note: sometimes query parameters get used for yet other things, which are neither locating resources nor encoding content. Ever seen a query parameter like 'PUT=true' or 'POST=true'? These are workarounds for browsers that don't allow you to use PUT and POST methods. While such parameters are seen as part of the URL query string (on the wire), I argue that they are not part of the URL's query in spirit.
You want reasons? Here's one:
A web form can't be used to send a request to a page that uses a mix of GET and POST. If you set the form's method to GET, all the parameters are in the query string. If you set the form's method to POST, all the parameters are in the request body.
Source: HTML 4.01 standard, section 17.13 Form Submission
From a programmatic standpoint, for the client it's packaging up parameters and appending them onto the url and conducting a POST vs. a GET. On the server-side, it's evaluating inbound parameters from the querystring instead of the posted bytes. Basically, it's a wash.
Where there could be advantages/disadvantages might be in how specific client platforms work with POST and GET routines in their networking stack, as well as how the web server deals with those requests. Depending on your implementation, one approach may be more efficient than the other. Knowing that would guide your decision here.
Nonetheless, from a programmer's perspective, I prefer allowing either a POST with all parameters in the body, or a GET with all params on the url, and explicitly ignoring url parameters with any POST request. It avoids confusion.
I would think it could still be quite RESTful to have query arguments that identify the resource on the URL while keeping the content payload confined to the POST body. This would seem to separate the considerations of "What am I sending?" versus "Who am I sending it to?".
The REST camp have some guiding principles that we can use to standardize the way we use HTTP verbs. This is helpful when building RESTful API's as you are doing.
In a nutshell:
GET should be Read Only i.e. have no effect on server state.
POST is used to create a resource on the server.
PUT is used to update or create a resource.
DELETE is used to delete a resource.
In other words, if your API action changes the server state, REST advises us to use POST/PUT/DELETE, but not GET.
User agents usually understand that doing multiple POSTs is bad and will warn against it, because the intent of POST is to alter server state (eg. pay for goods at checkout), and you probably don't want to do that twice!
Compare to a GET which you can do as often as you like (idempotent).
I find it perfectly acceptable to use query parameters on a POST end-point if they refer to an already-existing resource that must be updated through the POST end-point (not created).
For example:
POST /user_settings?user_id=4
{
"use_safe_mode": 1
}
The POST above has a query parameter referring to an existing resource, mirroring the GET end-point definition to get the same resource.
The body parameter defines how to update the existing resource.
Edited:
I prefer this to having the path of the end-point to point directly to the already-existing recourse, like some suggest to do, like so:
POST /user_settings/4
{
...
}
The reason is three-fold:
I find it has better readability, since the query parameters are named, like "user_id" in the above, in stead of just "4".
Usually, there is also a GET endpoint to get the same resource. In that case the path of the end-point and the query parameters will be the same and I like that symmetry.
I find the nesting can become cumbersome and difficult to read in case multiple parameters are needed to define the already-existing resource:
POST /user_settings/{user_id}/{which_settings_id}/{xyz}/{abc}/ ...
{
...
}