servant icon indicating copy to clipboard operation
servant copied to clipboard

Full query string helpers

Open divarvel opened this issue 3 years ago • 2 comments

The goal of this PR is to adress a use-case that is not currently covered by servant: query strings with dynamic parameter names.

QueryParam and its friends are super useful, but extract the parameter name from a type-level string, so while this is useful in many cases, it cannot cover every use-case. A typical use-case would be implementing a search filter where filters are not static and can't be enumerated ahead of time.

I'll propose two helpers, directly derived from a use case that came up at work:

  • one is an escape hatch that extracts the whole query string as a [(ByteString, Maybe ByteString)] value. It cannot fail and provides raw access to the query string: QueryString :> Get '[JSON] [Book].
    This was the first version that i implemented for my concrete use-case at work, to get things going.
  • the other one is a bit more constrained and implements a pattern commonly known as deep objects. It builds upon the convention of using [] for a list of parameters: books?filter[search]=value&filter[author][name]=value. The corresponding type would be DeepQuery "filter" BookQuery :> Get '[JSON] [Book].
    This is based on what's currently used for my use-case at work.

Raw query string capture

  • [x] Servant.API
  • [x] Servant.Server
  • [x] Servant.Server Specs
  • [ ] Servant.Server Docs
  • [x] Servant.Client
  • [x] Servant.Client Specs
  • [ ] Servant.Client Docs

Deep object query parsing

I'm not sure where FromDeepQuery should go. I've provided an instance from FromHttpApiData a => Map Text a as an example of what's possible. Related tests should be added as well.

  • [x] Servant.API
  • [x] Servant.Server
  • [x] Servant.Server Specs
  • [ ] Servant.Server Docs
  • [x] Servant.Client
  • [x] Servant.Client Specs
  • [ ] Servant.Client Docs

divarvel avatar Aug 28 '22 09:08 divarvel

Considering the limitations of what we already have, these additions are most welcome. Ping me if you ever want to pair on a Cookbook addition for this.

tchoutri avatar Aug 28 '22 10:08 tchoutri

I'm not using haskell at work any more and I don't have time to revive this PR myself, but I still think it's a worthwhile addition to servant and am available to help anyone who wants to get it over the finish line.

divarvel avatar Jan 10 '24 10:01 divarvel

:tada: :tada: :tada: :tada:

tchoutri avatar Apr 23 '24 19:04 tchoutri

@tchoutri Since this PR broke backwards compatibility, we need to do a major version bump. Do we do that now, or just before the release? The advantage of doing it now is that then we don't have to remember that this PR changed the interface.

ysangkok avatar Jun 28 '24 17:06 ysangkok

@ysangkok yep let's do it right away. If you can't do it in the next 10 hours I'll do it in my morning. :)

tchoutri avatar Jun 28 '24 18:06 tchoutri