Advanced filtering of events

Story

As an application user I want to be able to filter my events according to various criteria So I can find events I'm interested in.

As an API consumer I want to be able to filter resources So I can find those interesting to me.

Usage

const events = await hydraClient.get("/api/events");
const filter = events
    .hypermedia
    .links.ofType("http://schema.org/SearchAction")
    .withTemplate()
    .first();
if (!!filter) {
    const query = filter.expandTarget(_ =>
        _.withPropertyOf("http://schema.org/name").havingValueOf(".*test.*"));
    let data = await hydraClient.getResource(query);
    for (const member of data.members) {
        // do something with the _member_, i.e. display it
    }
}

Details

The application should be able to filter events with various criteria, so the user can narrow number and relevance of the events displayed. This should cover at least a scenario, where user filters events matching multiple specific filtering criteria without diving into details on how those criteria should be joined (i.e.: alternatives vs logical sum, or more complicated cases like precedence and grouping). Communication would look like this:

GET /api/events
HTTP 200 OK
{
    "@context": "/api/context.jsonld",
    "@id": "/api/events",
    "@type": "Collection",
    "manages": {
      "property": "rdf:type",
      "object": "schema:Event"
    },
    "totalItems": 1,
    "members": [
        {
            "@id": "/api/events/1",
            "eventName": "Event 1",
            "eventDescription": "Some event 1",
            "startDate": "2017-04-19",
            "endDate": "2017-04-19"
        }
    ],
    "search": {
        "@type": "IriTemplate",
        "template": "http://example.com/api/events{?eventName}",
        "variableRepresentation": "BasicRepresentation",
        "mapping": [
            {
                "@type": "IriTemplateMapping",
                "variable": "eventName",
                "property": "http://schema.org/name",
                "required": false
            }
        ]
    }
}
GET /api/events?eventName=.*test.*
HTTP 200 OK
{
    "@context": "/api/context.jsonld",
    "@id": " /api/events?schema:eventName=.*test.*",
    "@type": "Collection",
    "totalItems": 1,
    "members": [
        {
            "@id": "/api/events/1",
            "eventName": "Test event",
            "eventDescription": "Some event having a search phrase",
            "startDate": "2017-04-19",
            "endDate": "2017-04-19"
        }
    ]
}

There may be requirement of the client to send more complicated queries using different methods as there are some formal limitations to query strings or URL length. This requirement will be raised in another use case and won't be discussed with this one.

Considerations

Is explicit page number or page size considered a filter

Having a possibility of explicitely defining which page (how many members to skip and limit response to) might cover some desktop applications, where grids of data are divided into multiple parts with a pager and a page-size options available.

From technical point of view, this behavior could be achieved with special purpose virtual predicates (i.e.: imaginatory limit and offset). The argument against is that these are not direct properties of resources being filtered. Supporting argument would be that similar approach is used in i.e. MS SQL pagination queries, where the row (which can be a one-to-one relation to an entity in our cases) is extended with a special purpose ROW_NUMBER value on which filtering in the WHERE block can be performed.

results matching ""

    No results matching ""