You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
First off, many thanks to the devs working on Gin. It's a top notch library for putting REST APIs together in Go.
A new RFC is out there for an HTTP QUERY method. It is basically GET but allows for a request body. The RFC can be found here.
TL;DR: the QUERY verb allows for the use of mime-types other than application/x-www-form-urlencoded for a HTTP request that fetches data.
Topics covered:
Why the QUERY verb is useful.
The semantic problems of using POST for retrieval requests.
The limitations of the application/x-www-form-urlencoded mime-type.
A suggestion on the API change.
Why QUERY is Useful
From a REST perspective, this method is pretty useful. A perfect example is for list and search endpoints. These endpoints often include filtration which can quickly grow in complexity. This is especially true when hitting endpoints that proxy requests to technologies like Elastic Search (properly secured and validated of course). JSON, other serialization methods, or a DSL are often used to form complex queries on equally complex data sets. Using the request body simplifies things. More on why in the coming sections.
The Problems with POST
Right now we are using POST for these types of requests. While it works, it confuses the purpose of that REST verb. It is much cleaner to have POST always mean "create new things" instead of a hybrid meaning that requires the end user to guess based on the endpoint name.
On the topic of endpoint naming, using POST to do a GET like operation with data that is of a mime-type other than application/x-www-form-urlencoded used in query parameters often means including something very close to a verb in the URL path. That is widely considered an anti-pattern. The QUERY verb allows for a verb free URL path. Semantic correctness prevents confusion. The easier it is to be semantically correct, the clearer a REST API can be for it's consumers.
The Limits of Query Parameters
As previously mentioned application/x-www-form-urlencoded can take you only so far. It is just a key-value data structure. It has no depth beyond that. While there have been attempts to make it more useful, those approaches are neither universally accepted, nor are they as robust as other mime types like JSON, XML, or YAML. It is true that you can serialize data and encode against a query parameter in the URL. However, that doesn't solve the semantics problem. It also does nothing to provide standardized information about how the data is serialized. In the case where different serializations might be supported, having that clearly indicated within the headers constitutes a more standardized way to communicate that information.
A Suggested API Change
It's super simple. Just add another router method. We already have GET, PUT, POST, DELETE, etc. Just add QUERY with similar characteristics to GET. The Gin Context object should already include the request body.
It might look like this:
router:=gin.Default()
router.QUERY("/some/url/path/:here", func (c*gin.Context) {
complexQuery:=&ComplexQueryStruct{}
_=c.BindJSON(complexQuery) // error handling left out to keep it brief.result:=aSearchOperation(c, complexQuery)
c.JSON(200, result)
})
If there is interest, I'd be willing to whip up a PR.
Once again, thanks for the wonderful library that Gin is, and thanks for your consideration.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
First off, many thanks to the devs working on Gin. It's a top notch library for putting REST APIs together in Go.
A new RFC is out there for an HTTP QUERY method. It is basically GET but allows for a request body. The RFC can be found here.
TL;DR: the QUERY verb allows for the use of mime-types other than
application/x-www-form-urlencodedfor a HTTP request that fetches data.Topics covered:
application/x-www-form-urlencodedmime-type.Why QUERY is Useful
From a REST perspective, this method is pretty useful. A perfect example is for list and search endpoints. These endpoints often include filtration which can quickly grow in complexity. This is especially true when hitting endpoints that proxy requests to technologies like Elastic Search (properly secured and validated of course). JSON, other serialization methods, or a DSL are often used to form complex queries on equally complex data sets. Using the request body simplifies things. More on why in the coming sections.
The Problems with POST
Right now we are using POST for these types of requests. While it works, it confuses the purpose of that REST verb. It is much cleaner to have POST always mean "create new things" instead of a hybrid meaning that requires the end user to guess based on the endpoint name.
On the topic of endpoint naming, using POST to do a GET like operation with data that is of a mime-type other than
application/x-www-form-urlencodedused in query parameters often means including something very close to a verb in the URL path. That is widely considered an anti-pattern. The QUERY verb allows for a verb free URL path. Semantic correctness prevents confusion. The easier it is to be semantically correct, the clearer a REST API can be for it's consumers.The Limits of Query Parameters
As previously mentioned
application/x-www-form-urlencodedcan take you only so far. It is just a key-value data structure. It has no depth beyond that. While there have been attempts to make it more useful, those approaches are neither universally accepted, nor are they as robust as other mime types like JSON, XML, or YAML. It is true that you can serialize data and encode against a query parameter in the URL. However, that doesn't solve the semantics problem. It also does nothing to provide standardized information about how the data is serialized. In the case where different serializations might be supported, having that clearly indicated within the headers constitutes a more standardized way to communicate that information.A Suggested API Change
It's super simple. Just add another router method. We already have GET, PUT, POST, DELETE, etc. Just add QUERY with similar characteristics to GET. The Gin Context object should already include the request body.
It might look like this:
If there is interest, I'd be willing to whip up a PR.
Once again, thanks for the wonderful library that Gin is, and thanks for your consideration.
All reactions