openactive / modelling-opportunity-data

OpenActive Modelling Opportunity Data specification
https://www.openactive.io/modelling-opportunity-data/
Other
6 stars 6 forks source link

Proposal: Allow urlTemplates for scheduled events #72

Closed ldodds closed 5 years ago

ldodds commented 6 years ago

A scheduled Event is an event that has an eventSchedule property that defines how often individual instances of an event will take place.

At the moment there is no way for a data consumer to provide a link to an individual instance of one of those Events.

Proposer

This has some up in discussions with Bookwhen. But its also essential part of ensuring that scheduled events can be bookable

Bookwhen are currently testing a url template property.

Use Case

Why is this not covered by existing properties?

The individual Events that are described by an eventSchedule do not have URIs.

Some publishers might choose to include individual events in their feed, but other than this happening (and a consumer being able to correct identify the Event instance based on time/date), there's no reliable way for a consumer to identify the URI for this type of Event.

Please provide a link to example data

Example use of eventSchedule which includes a proposed urlTemplate property in Bookwhen data. Note this is not currently conformant with the eventSchedule but illustrates usage:

          {
            "type": "Event",
            "duration": "PT1H",
            "beta:urlTemplate": "https://bookwhen.com/hulafit/e/ev-s51e-{YYYYMMDDHHMISS}?r=oa",
            "eventSchedule": {
              "type": "Schedule",
              "startDate": "2014-09-01",
              "endDate": "2014-11-10",
              "frequency": "weekly",
              "byDay": [
                "https://schema.org/Monday"
              ],
              "startTime": "18:15",
              "endTime": "19:15",
              "interval": 1
            }
          }

Proposal

Based on the recommendations on identifying resources in the modelling specification, this proposal requires adding two new properties:

  1. urlTemplate - to provide a URI template to allow a consumer to generate a url property for an Event that falls within an eventSchedule
  2. idTemplate - as above, but for generating an id property

The first allows an Event to be linked to on the web. The second allows a consumer to lookup the Event in an API.

Both of these will be properties of an Event

Template processing

RFC 6570 formally defines URI templates, including different levels of template processor. There are a list of existing implementations

A Level 1 processor only does simple variable substitution. A Level 4 processor provides additional macros to provide more flexibility.

For the initial proposal we recommend that templates required only Level 1 processing. This limits the scope of the types of URIs that can be generated, but is simple to implement.

Variable naming and binding

A variable in an RFC 6570 URI template must conform to the following syntax:

     varname       =  varchar *( ["."] varchar )
     varchar       =  ALPHA / DIGIT / "_" / pct-encoded

This is consistent with un-prefixed Schema.org property names, e.g. startDate.

An Event described according to the standard model is a hash of name-value pairs. e.g. identifier, startDate, etc.

Any property of the Event can be used as a variable in a URI template specified using urlTemplate and idTemplate

Processing model

The logical processing model for expanding a URL template is to:

  1. Create an initial set of name-value pairs by taking the properties of the scheduled Event, excluding the urlTemplate, idTemplate and eventSchedule properties
  2. Identify an individual instance of that Event using the rules defined in eventSchedule. This will generate two new properties: startDate and endDate (depending on the detail provided in the schedule)
  3. Add these new properties to the initial set of properties from the Event. This gives a final set of name-value pairs
  4. Provide the template and final set of properties to the template processor
  5. The URI generated by the processor is added to the Event description as either an id or url property depending on the template

Worked example

The following Event description describes an Event that runs every Wednesday starting at 6pm

          {
            "type": "Event",
            "identifier": "abc123",
            "urlTemplate": "https://example.org/events/{startDate}",
            "idTemplate": "https://api.example.org/events/{identifier}/{startDate}",
            "eventSchedule": {
              "type": "Schedule",
              "startDate": "2018-04-01",
              "endDate": "2018-12-31",
              "repeatFrequency": "P1W",
              "byDay": "http://schema.org/Wednesday"
              "startTime": "18:00",
              "endTime": "19:00"
            }
          }

The initial set of properties will be:

type: "Event"
identifier: "abc123"

Interpreting the eventSchedule we can determine that there will be a specific instance of this Event taking place at 6pm on Wednesday 25th April.

Adding the start and end times gives the following final set of properties:

type: "Event"
identifier: "abc123"
startDate: "2018-04-25T18:00:00" 
endDate: "2018-04-25T18:00:00"

Passing the values of urlTemplate and idTemplate properties to a template processor, with the above set of properties will produce (ignoring URI escaping):

url: "https://example.org/events/2018-04-25T18:00:00"
id:  "https://api.example.org/events/abc123/2018-04-25T18:00:00"

Questions

  1. Should we allow for additional features from RFC 6570? If so, which Level? Most implementations implement up to Level 4
  2. Should we allow for more flexibility, e.g. by providing additional "implicit properties", e.g. to break down the individual time components of the startDate, e.g. startDate.YYYY?
ldodds commented 6 years ago

@drchristhorpe we need to move this forward as part of the booking work. Otherwise a user can't check the current availability of events that have schedules.

Can you review and give me some feedback on this proposal?

ldodds commented 6 years ago

Further thinking from me:

nickevansuk commented 6 years ago

@ldodds this processing model looks like a great start!

I know "implicit properties" e.g. startDate.YYYY would be favoured by Bookwhen, as it reduces the amount of work for them, however they could implement a route which returns a 301 redirect from https://bookwhen.com/openactive/events/s51e/2018-04-25T18:00:00 to https://bookwhen.com/hulafit/e/ev-s51e-{20180425180000}, which I suspect might be the purer route to go down.

So for the sake of a redirect I'd actually suggest keeping this simple for now (Level 1 and no implicit properties), as that reduces the overall cost of implementation to the ecosystem as a whole, and a redirect recommendation in the implementation guidance provides an easy route for systems to conform.

Given that a) we are now improving types to make the parent and child types distinct (e.g. EventSeries and Session) and b) there is already an inheritance from EventSeries -> Session for all properties in EventSeries, do we need the initial set first step of the processing model to copy all properties? (Or should we make clear that any intermediary is not expanded to copy all properties if they are creating subEvents?)

There is no need to have e.g. identifier available for substitution as it can be included in the template string directly for that specific event. So really only var that will require substitution is the startDate (assume it's unlikely that endDate is required).

Basically this radically simplifies this to only processing and substituting startDate, which makes it simple for implementers all round.

It might be better to have these templates be properties of the Schedule rather than the Event holding the schedule

The property binding doesn't allow for multi-values properties (e.g addressing into, or collapsing arrays) or structured properties. However I'm not clear this is a problem as we'd reasonably expect the URLs to be templated based on the id, url, identifier, startDate, endDate of the parent.

We should add some wording to make it explicit that the Event that is generated from the eventSchedule should have a subEvent/superEvent relationship with its parent Event. And also consider what type it might have, e..g Session depending on #63 discussion.

ldodds commented 6 years ago

+1 on just building identifier into the template. +1 on recommending redirects to deal with more complex use cases. In general with an identifier, start time, end time and duration, there should be enough context.

I'm in favour of keeping the initial set though, as it means that publishers could use custom properties if necessary as another means to populate URLs. In practice someone may also need startDate and enddate, or startDate and duration to generate an id or a redirectable URL.

It's straight-forward to implement though: take the object hash with the eventSchedule property, remove the schedule and that's the initial set.

nickevansuk commented 6 years ago

Maybe i’m missing something here...

The only “dynamic” properties will be startDate and endDate, which are generated from the schedule, as all other properties will be known at the time that the feed is created and so can be baked into the urlTemplate?

So what value is there in allowing for the substitution of any other properties?

ldodds commented 6 years ago

No you're right. Will remove it.