orbitjs / orbit

Composable data framework for ambitious web applications.
https://orbitjs.com
MIT License
2.33k stars 134 forks source link

First class support for jsonapi.net filters, pagination and sorting #901

Closed sandreas closed 2 years ago

sandreas commented 2 years ago

Hello,

awesome library, thanks. One thing that I'm missing is first class support for jsonapi.net filters, sorting and pagination:

They implemented every feature a little different to the well known approaches, but in my opinion it is one of the most elegant ways to query resources.

My questions:

Example for manually including options:

const api = new JSONAPISource({
    schema: new Schema({
        models: {
// ...
        }
    }
});
const options = {
            sources: {
                api: {
                    settings: {
                        params: {
                            sort: '-purchaseDate',
                            page: {
                                size: 50
                            }
                        }
                    }
                }
            }
        };
const itemReference = await api.query(q => q.findRecords('file'), options);
SafaAlfulaij commented 2 years ago

You can build a custom source on top of JSON:API source, I believe.

bradjones1 commented 2 years ago

Much of what you're looking for is already supported. See

https://orbitjs.com/docs/next/querying-data#queries

with the examples. The docs are a work in progress, but sorting, filtering, and pagination are all supported out of the box.

sandreas commented 2 years ago

@SafaAlfulaij @bradjones1 Thanks for the answers, I have to investigate this, but I think that there is no out of the box support for the more complex filter urls like:

?filter=not(equals(lastName,null))
?filter=any(chapter,'Intro','Summary','Conclusion')
/blogs?include=owner.articles.revisions&filter=and(or(equals(title,'Technology'),has(owner.articles)),not(equals(owner.lastName,null)))&filter[owner.articles]=equals(caption,'Two')&filter[owner.articles.revisions]=greaterThan(publishTime,'2005-05-05')
dgeb commented 2 years ago

@sandreas You're correct that the filtering specifically defined by jsonapi.net is not supported out-of-the-box in @orbit/jsonapi, except at the direct level of specifying settings.params within options. While I don't plan to add jsonapi.net-specific customizations to orbit's core packages, I would really like to make it possible to override the implementation in @orbit/jsonapi to more cleanly to support customizations just like this.

I'm working in this area right now as I prep v0.17 for release, so thanks for providing these use cases.

sandreas commented 2 years ago

I'm working in this area right now as I prep v0.17 for release, so thanks for providing these use cases.

@dgeb Awesome, thank you! Keep up the good work. For a full set of even more use cases, see https://www.jsonapi.net/usage/reading/filtering.html

bradjones1 commented 2 years ago

@sandreas Sorry I misunderstood your original question. I am handling this locally, for the time being, doing something like overriding the URL builder:

https://gist.github.com/bradjones1/18ff9ebdb85455f781a2a212577653ce

See also https://github.com/orbitjs/orbit/issues/559#issuecomment-519108480

dgeb commented 2 years ago

PR #911 greatly improves the built-in handling of standard json:api options. fields is now supported as a request option, and all the options will use serializers as appropriate if fields and types should be specially formatted (e.g. dasherized) for your API. Perhaps the easiest way to review the variety of available options is to browse the updated tests for JSONAPIURLBuilder.

And, as @bradjones1 pointed out above, overriding the JSONAPIURLBuilder is the recommended way to handle custom options. Once v0.17 is released, it would be great to start publishing packages with some standard overrides such as for jsonapi.net and Drupal.

Please let me know if you have any trouble using the new options.

bradjones1 commented 2 years ago

Thanks @dgeb - that's awesome. I don't see any docs updates in the PR; is this something that you're already working on or should I take a stab at updating the docs? My TypeScript is pretty shoddy but I'd like to help as I can in order to repay a little bit of the effort I'm benefiting from.

dgeb commented 2 years ago

@bradjones1 thanks for asking! I've been planning to update the guides with a section that goes in depth on using and customizing the JSONAPISource. If you want to get a start on that, it would be much appreciated. Also very useful, and perhaps easier to tackle, would be expanded inline API docs for the JSONAPIRequestOptions interface. Each option should ideally be documented like partialSet is.

Thanks in advance for any help you can provide with the docs!

sandreas commented 2 years ago

Thanks guys, I'll try it in the next weeks for a new project. Awesome! Greatly appreciate it.

symbioquine commented 2 years ago

Really excited to see this issue!

It would be nice for JSONAPIURLBuilder and especially SyncQueryOperators were to be extensible without needing to copy/modify almost the entire implementation (of those things) to do so.