Designing a URL-based query syntax for GraphQL
blog.logrocket.com
blog.logrocket.com
It also conveniently leaves out automatic persisted queries which would replace queries with hashes, or regular persisted queries, where we'd have a limited set of allowed queries on the server-side that it accepts.
I think ultimately when I think of sending GET requests for GraphQL, I'm immediately more worried about the URL length limit. The risk being that at some point in the future we may run over this limit and get into a lot of unexpected trouble.
Also, this article assumes that you can only stringify GraphQL a single way, with spaces. However a not as commonly known detail in the spec is that any commas are treated the same as whitespaces. Hence, this is a valid query:
{item(id:4){id,name,author(id:4){id,name}}
Which isn't far off from reading a complex query string IMO, works with any existing GraphQL API via GET if the API already accepts GET requests, and isn't a special format that'll need to be learned supporting the full syntax. /?
query=
posts(
ids: [1, 1499, 1178],
order: $order
)@posts.
id|
date(format: d/m/Y)|
title<
skip(if: false)
>|
--props&
order=title|ASC&
props=
url|
author.
name|
url
All-in-all this seems like a very roundabout way to achieve HTTP-level caching for queries.Reasoning about the query as a literal string instead of _data_ is where I think this went off the rails. I probably would have just added middleware to allow for base64 encoded queries and then gone that route. A query can get deterministically hashed into a string of chars.
I just present the query in readable form together with the output, letting the user choose between copy / paste the URL or copy / paste the readable form.
Example:
http://arnorthwind.agorapide.com/RQ/dt/Order/WHERE%20Shipped...
will present the alternative form
Order
WHERE ShippedDate = Today
SELECT OrderId, ShippedDate, CustomerId, Customer.CompanyName, OrderDetail.Sum.Sum() AS SumOrder
together with options for choosing Yesterday, 2 days ago and so on.See more examples at http://arnorthwind.agorapide.com/
Odata v4 with json payloads is more or less how most would define the payload manually, it has all the benefits of GraphQL (retrieving a tree of objects, selecting required attributes), is fully compatible with Rest (retrieves are GETs, mutations can be POST, PUT, DELETE), has a true query language with filtering, aggregations, expressions, joins, paging, sorting, which are all part of the url so you can cache it like a normal Rest GET, has batches so you can update multiple objects in one transactions, and supports subscriptions so you can receive updates instantaniously...
It‘s not great that paging, sorting and filtering aren‘t speced in graphql, so something better could be appealing.
If OData had something along the lines of urql graphcache and a good pattern for composing 1 screen query from component fragments I‘d be interested, but I‘m not going to write it.
Also, as people like to point out, GraphQL is really some kind of RPC, which is actually pretty handy. Most ad hoc HTTP api‘s are as.well, but once you enter a more well defined spec, do you still have that flexibility to just "get things done"?
I understand why OData isn't seen more.
For example compare graphql.org www.odata.org. It's a huge difference. The GraphQL landing page is up front on what it does and how it can help you. OData has this:
> OData (Open Data Protocol) is an ISO/IEC approved, OASIS standard that defines a set of best practices for building and consuming RESTful APIs.
What is this supposed to tell me? To me it doesn't sound like OData is a committee based REST api and that's not a pro in my book.
There were other things that led me to not consider it as a viable option: - the OData format doesn't look clean and nice, OData fields and function calls - the framework support in python is practically nonexistent
And I still don't know which problems it actually tries to solve. If you could tell me, I'm more than happy to listen.
You can use Rest resources like database tables, with filtering, sorting, paging, do RPC style requests like GraphQL with Odata actions, or do data replication with odata subscriptions.
Biggest benefits to me are: 1) is a Rest protocol, instead of something on top of Http like Soap or GraphQL, 2) sql like resource access helps random access to data in different apps using standard reporting tooling like Excel and PowerBi, and 3) rich metadata which helps clients understand what they can do with the Odata resource (filterable, sortable, pageable, countable, etc).
GET queries are already part of the specification, or rather the "Serving over HTTP" recommendations (?) and it’s well supported. The only difference is they don‘t look as nice.
Non devs do not care one bit about the query params, and devs don't write them by hand so who cares?
Transmitting and displaying text in two dimensions has been a solved problem since the teleprinter was invented in the 1920s.
This is so obviously wrong.