Crnk does too much for us
See original GitHub issueSorry, this is a bit lengthy.
So, you may have noticed from some of my other comments, that we created a (big) API starting back then with katharsis. Crnk has evolved a lot since then. But many improvements and features don’t work for us. In fact, we need to work around them.
I’d like to see a more layered or modular approach to features that can be turned off and on.
Some of my wishes would be:
- Do not parse parameters that where passed in the URL. I’ll use the raw ones from the request (
Map<String, Set<String>>
). - Do not make any assumptions or restrictions on filter parameter shape or semantics. jsonapi.org spec does make recommendations, but they are only recommendations, and Crnk’s default behavior is not happy with a filter like
GET /comments?filter[post]=1
(correct me if I’m wrong). - Allow me to do things, that don’t comply with jsonapi spec, at least parameter-wise. We need data aggregating endpoints (building sums, averages etc) and therefore require parameters that allow us to ‘group by’ different criteria. Crnk should never drop any parameters but provide means to access non-compliant ones too.
crnk-jpa is indeed a very cool thing, if you can make do with the offered functionality. Unfortunately, we can’t. And crnk itself imposes restrictions and conventions, that make sense for crnk-jpa, but not if you have different things in mind. I get the impression that quite some crnk-core functionality is optimized towards crnk-jpa.
Right now I’m in the situation where all parameters get parsed, some throw a parsing exception which I have to ignore, and in the end, I have to pull parameters from the raw map because it’s the only way to really get everything that was passed (eg. grouping parameters). Performance wise it may not be a big issue, but if feels terribly wrong to do so. I am kind of writing a miniature framework inside crnk framework, to get what we need. Which is time consuming and also brittle.
Just recently I tried to add support for page[size] and page[number] parameters, instead of the default offset and limit params.
That worked fine enough, even though I had do do very, very similar things as the OffsetLimitPagingBehavior
(shared base class maybe?).
Yet, if a URL like ‘/api/persons?filter[name]=earl&page[size]=10&page[number]=0’ was requested, then the next
link will be rendered as
‘/api/persons?filter[name][EQ]=earl&page[size]=10&page[number]=1’. Note the added ‘[EQ]’. While this is fine within the crnk world, it breaks my own parameter handling.
Summing up, I have two questions:
-
Would you consider to ‘do less’ in crnk, and give framework users more control over which things they want to use?
-
If there are no plans to work on 1) - which behavior / classes could be changed such that I get the flexibility I need? With which classes should I start and can I make crnk use them over the default ones easily?
Thanks for reading this! Looking forward to your answers.
Issue Analytics
- State:
- Created 5 years ago
- Reactions:1
- Comments:9 (9 by maintainers)
QuerySpec serialize/deserializer have been merged to have everything at one place, which in turn allows to more easily implement more customized url/parameter handling as requested here. And paging can be configured globally. There are a few smaller follow-ups:
https://github.com/crnk-project/crnk-framework/issues/307 https://github.com/crnk-project/crnk-framework/issues/306 https://github.com/crnk-project/crnk-framework/issues/291
Probably worthwhile to close this in favor of smaller more targeted tickets.
Well,
filter[person][hasChildren]=true
was an overly simplified example. A better example would befilter[person][hasSilverSpoons]=true
.Which, according to your reasoning should be something like
filter[person][apartment][inventory][spoons][material]=silver
.We do have cases where we need to filter on data that is 4 hops (and more) away from the root object. While the latter approach is certainly not wrong, it was our design decision to rather use
filter[person][hasSilverSpoons]=true
. We even have filters that aren’t expressible through a relationship chain at all! This is where your suggested approach ultimately stops working. Not every relationship should / can be modeled bidirectionally. Which shouldn’t prevent one from defining a filter (where you will have to start with a DB query on a totally different table). Our API is not only used by our own app, we also have customers that communicate with our API directly. So a simplification of otherwise complex filter criteria is definitely important for us. Therefore… is an assumption which doesn’t hold true. We have plenty such parameters.
And didn’t mean to say that crnk should also start using
FilterDefinition
objects (although I am very happy with that idea), I was just trying to explain why the type-from-resource-deduction doesn’t work well for us and how we infer the type.I’m happy to hear you’re open for change!