Why we need GraphQL when we can query for a specific field in REST? - rest

GraphQL's principle aim is to solve overfetching problem as faced by many REST APIs and it does that by querying for only specific fields as mentioned in the query.
But in REST APIs, if we use the fields parameter, it also does the same thing. So why need GraphQL if REST can solve overfetching like this?

The option to fetch partial fields is only one of the key features of GraphQL, but not the only one.
One other important advantage is the 'graphic' nature of the model. By treating your schema as a graph (that is, several resources tied together by fields), it allows you to fetch a complex response, constructed of several data types in a single API call. This is a flexibility that you don't have in a standard REST API
Both these features can obviously be done by rest as well, but GraphQL gives it in a much simpler and more intuitive way.
Take a look at this post, there's a fairly good explanation there of the advantages (and disadvantages) of GraphQL.
https://www.altexsoft.com/blog/engineering/graphql-core-features-architecture-pros-and-cons/

When you have a REST setup, you're typically returning a whole JSON representation for each endpoint. This includes all fields that you may or may not need which leads to more data usage or more HTTP calls (if you divide your RESTful API up, that is).
GraphQL on the other hand gives you exactly what you're asking for when you query with a single POST/GET request.

Related

REST GET Design For Optional Feature Param

I have a predictive model that I am wrapping in a REST endpoint. Under the hood, the /forecast endpoint chooses one of hundreds of models to make the prediction based on the GET param feature_name.
We have a use case to get all predictions from all models with a single HTTP request. Should we:
Make feature_name optional, and if nothing is passed, return predictions for all models?
Make users pass a special word like 'all' to feature_name if they want all the predictions?
Maintain two endpoints, forecast and forecast_all?
Something I haven't thought of?
The idea of using an endpoint for /foo/{id} for singular items, and a separate /foo/ to get a collection of all items is extremely common.
I would especially suggest looking into a standard formats for REST collections. HAL is a popular one.
I wrote an article a while back about collections in REST services. Maybe it's also helpful for more context.

Complex requests with REST API

I am wondering if it is possible to adhere to REST principles when creating what will essentially amount to a BI tool.
In my scenario I have high data volume with 100,000's of IDs (frankly more than this but for the sake of this example let's go with that.). These are presented in a traditional table that allows for necessary features when accessing large data sets such as pagination. The user also has the ability to filter by one, or many of these ID's to drill down the data set as they see fit.
It is theoretically possible that the user would want to filter on 100 of the ID's, thus rendering a GET URI incredibly long. Which as I understand it would kind of break the resource identification principle of a REST API. Not to mention could potentially bump into the character limit in a GET request for certain browsers since the ID's may be quite long. Normally I would just use a POST since I can add all of the applied filters in the body and generate a where clause on the server.
Since a POST in a REST API is supposed to
Create a new entry in the collection.
By definition it would appear, at least to me that generating a complex query for something like this would mean that a REST API is not possible. Or does this perhaps mean that I am approaching the solution wrong (totally plausible).
It would seem that in my scenario using a GET simply isn't possible due to the potential length of the parameters. Thus I am forced to use a POST. Though using a POST as I am seems to violate REST style, which isn't the end of the world. I mostly just wanted to double check that I am not missing something and there is not a solution using a GET.
To follow the resources principle, make a search like resource. POST your ids in a body wto this endpoint and it will prepare a list of results for you and redirect you to searchresults/{id}.
See for example: https://gooroo.io/GoorooTHINK/Article/16583/HTTP-Patterns---Bouncer/25829#.W3aBsugzaUk

REST resource with multiple views

We are trying to follow a quite strict idiom for our REST service however we have come across a situation where we have two clients who require different representations of the same resource. One is front-end and they would prefer a very minimal resource with only the fields they require and in a more flattened structure (for performance), the other requires all fields that we have in our data store in a heavily nested structure. What is the idiomatic way for REST services to deal with this given the canonical URL should be the same as they are accessing the same resource. We thought of adding projections to the request but with this the structure would still be quite nested which causes performance issues in the JS client as it will have to walk through the structure and flatten it, something that can be quite costly when the number of resources returned is high.
I would suggest there are two alternatives:
1) If the query field can vary, you could specify the fields (structure) you want as query parameters. This is common in REST APIs. With no specification, you would return a default list of fields. What should be default or not depends on the service, but in general the minimal set makes a better default for performance. In order to avoid listing all fields, something like fields=all could be used. In your case structure might make more sense.
2) You can encode the field request in a custom request headers. Some would argue that this is the more REST-ful approach as you're only modifying the format of the response and not the underlying action invoked, and therefore the URL should be the same.
In practice, most services prefer the first approach as it's considered more approachable.
Personally, I think it's a marginal choice. I prefer to encode the return media (JSON, HTML, XML, etc.) in the Accept header. Any decent developer has tools that make it easy enough to set the headers, but the fields query parameter idiom is, in my experience, far more prevalent and there's a great deal to be said for convention.
Note, if you use the headers approach, you should probably not use the Accept header for the structure/field specification. Add your own header if you go that route.

REST complex web request with GET

I am working on a REST service and so far all the queries are retrieved using a GET request.
Right now we are using a sort of routing rule like this one:
API/Person/{id} GET
http://api.com/person/1
Now, what if I want to ask to the REST API "Give me a Person with FisrtName = 'Pippo'"
I have a complex DTO that I called PersonQueryDTO that can be sent to the REST method to interview the database using the query criterias.
Is this a good way to do it or should I build complex queries in a different way?
For me it's important to keep the REST principles.
If you want to stick with REST principles, then the way to do something like that is to supply additional parameters in the URL e.g.
GET API/Person?FirstName=SomeName
REST is all about identifying resources, API/Person identifies your collection of Person and the additional parameters are nothing but meta data which the service can use internally to determine what sort of result to return.

Exposing database query parameters via REST interface

I have the basics of a REST service done, with "standard" list and GET/POST/PUT/DELETE verbs implemented around my nouns.
However, the client base I'm working with also wants to have more powerful operations. I'm using Mongo DB on the back-end, and it'd be easy to expose an "update" operation. This page describes how Mongo can do updates.
It'd be easy to write a page that takes a couple of JSON/XML/whatever arguments for the "criteria" and the "objNew" parts of the Mongo update function. Maybe I make a page like http://myserver.com/collection/update that takes a POST (or PUT?) request, with a request body that contains that data. Scrub the input for malicious querying and to enforce security, and we're done. Piece of cake.
My question is: what's the "best" way to expose this in a RESTful manner? Obviously, the approach I described above isn't kosher because "update" isn't a noun. This sort of thing seems much more suitable for a SOAP/RPC method, but the rest of the service is already using REST over HTTP, and I don't want users to have to make two different types of calls.
Thoughts?
Typically, I would handle this as:
url/collection
url/collection/item
GET collection: Returns a representation of the collection resource
GET collection/item: Returns a representation of the item resource
(optional URI params for content-types: json, xml, txt, etc)
POST collection/: Creates a new item (if via XML, I use XSD to validate)
PUT collection/item: Update an existing item
DELETE collection/item: Delete an existing item
Does that help?
Since as you're aware it isn't a good fit for REST, you're just going to have to do your best and invent a standard to make it work. Mongo's update functionality is so far removed from REST, I'd actually allow PUTs on the collection. Ignore the parameters in my examples, I haven't thought too hard about them.
PUT collection?set={field:value}
PUT collection?pop={field:1}
Or:
PUT collection/pop?field=1