Case Studies for Use of JSON-LD in Client-side JS Apps

We encourage users to post events happening in the community to the community events group on https://www.drupal.org.
ethanw's picture

Following conversations with linclark at DrupalCon Munich, here are some examples of client-side applications and functionality that would interface with a Drupal 8 JSON-LD API. The goal of these use cases is to identify key requirements client-side application development might make on a JSON-LD REST API in Drupal. Specifically a focus here is where the linked data aspects of JSON-LD will be important (as opposed to just JSON serialization of internal PHP data structures).

In addition these use cases should demonstrate API-level requirements and required contrib functionality, such as integration with the theme layer (e.g. server-side attribute rendering), recursive embedding of linked resources within “parent” resources (including the full JSON-LD user object within a node object for node author, for example). It is understood that such functionality may not be provided by core, but that a core API should make such functionality possible in contrib.

Case 1: The Class Roster

This case is an example of a client-side filtering application. Teachers are able to access a page via their PC or mobile device and see a list of all students in a class. They can filter this list based on various criteria: name, grade-level, and completion of any of the recent assignments. Similarly, they can pull up a list of all submissions for a recent assignment and filter by student name, student grade level, or a set of taxonomy terms placed on the assignment by TAs or others.

The second interface is probably the best example of use of linked data. I may make some pretty pictures for this later, but the general flow of the application will be something like this:

  1. User requests initial HTML page via HTTP.
  2. Drupal loads initial data set (if any) and renders basic single-page app: includes script file for libraries and custom js for app, renders JSON array of initial data set in same format as REST API would return, and includes templates for rendering data server-side. Likely bootstrap data would include:
    • Students in class for page requested.
    • Taxonomy terms used on page for listing.
  3. Application starts. Collections for holding sets of entities in client memory are created, as well as views for rendering those entities and a parent view for the application interface.
  4. If there is any bootstrapped data, it is loaded into the appropriate collections and rendered.
  5. Any collections not bootstrapped are then fetched from the server. For example, if client-side app provides a way for users to switch the assignment they are looking at within the app, a reload of the assignment submission collection would be required. Fetching involves the following steps:
    1. Client sends request to REST endpoint for JSON-LD (or any JSON variant, by default) serialized list of assignment submissions.
    2. Server responds.
    3. Collection iterates over all responses, creating a new model object for each one and passing the JSON for each individual entity to it’s respective model for parsing.
    4. Model’s .parse() method is run for each model JSON. This can be a custom function, or provided by an extension layer (such as the Backbone module for Drupal). In our case
      .parse() for an assignment might involve checking to see if the user object of the assignment submission author had been loaded yet, and, if not, loading based on the URL specified in the linked data reference for author, and creating a new model to hold that user as a property of the assignment object. (Note: this is an example of where “embedded rendering” is useful. If the client can request a list of all assignments with all references entities rendered into the JSON array to a recursion level 1 deep, the client can make fewer calls to the API. It is debatable what is the best practice.)
    5. When a model is created and added to the collection, it triggers various change events, which result in it being rendered and added to the display of the collection in our app.
  6. Interaction begins. In the case in which there is the ability to filter based on tag, and tags were bootstrapped, our application view will have rendered a widget into the App ui for choosing a term to filter on. When a term is used, we use the URL, UUID or other linked data reference locator to filter all out assignments by taxonomy term. The point of note here is that we can use information gained through the call to one resource, taxonomy terms, to filter another resource, assignment submissions, without needing to know much about the specific architecture of the Drupal system since we have a good system for linking and referencing entities.
  7. A user might then choose to mark a grade or add a tag for a given item. This is done through binding user events to the appropriate changes in model state, then triggering a “save” operation through either a “save” link, or automatically when certain attributes of a model change. JSON-LD is serialized on the client side and sent back to the REST back end with a PUT verb (can be overridden). Server then returns a partial resource object with any changed attributes and additional information.

That is somewhat off the cuff, but hopefully gives a good sense of the general flow for a common Backbone app.

Case 2: CreateJS/In-place Editing

In-place editing is an interesting case study because it has a number of very specific requirements, especially in its current implementation where we need to integrate with the Drupal theme layer in ways which may preclude using existing in place editing options like CreateJS without modification/overriding some components.

The general case is that a content administrator needs to be able to edit a page by simply clicking on elements as they are displayed within the page. They can then make changes to page content such as title, body text, attachments, embedded media, etc. Changes may be either saved incrementally or save may be triggered by clicking a “save” button after a bunch of changes have been made.

An important consideration is that it is quite likely that some fields, such as embedded media elements, may need to be sent back to the server for rendering. In addition to this there may need to be two versions of rendered fields: fields rendered as they will be displayed, and fields rendered in such a way that they can be edited. An example of this might be a body field with various input filters which transform youtube URLs into embed tags. @wimleers can speak more to this. Currently the editor needs to load the actual form for each field from the endpoint as well, since many Drupal modules use form_alter to attach critical behavior to entities. It’s worth noting that if WSCCI is going to make Drupal RESTful, this approach of using form alters for any substantial functionality will need to stop. This would include moving from form validation to entity/model validation.

The current flow of the in-place editing with a client-side framework pushing information back to a REST backend, using JSON-LD as the serialization and CreateJS for the clientside interface, would be something like this:

  1. User requests page.
  2. Page is sent with RDFa serliazed into HTML and CreateJS scripts included.
  3. CreateJS parses RDFa in HTML and creates model object, with bindings between HTML DOM elements and JS model objects so that changes to interface result in corresponding changes to model data.
  4. User clicks body, uses custom CreateJS embed youtube widget to change the URL of an embedded video. (There are lots of questions here: can we keep the input filter system for doing this if we have in-place editing, or would we need to build JS widgets to munge the actual embed codes?)
  5. User clicks on image field, chooses new image from asset library for post.
  6. User clicks on entityreference field, is presented with dropdown
    created via a collection and special view loading all candidates.
  7. User clicks save.
  8. Updated model data is sent to server.
  9. Server validates, saves and sends back response, including updated rendered HTML for any entities that were changed and could not be rendered on the client.

I’m less clear on this one, so am hoping that Henri and Wim can clarify a bit more. But the main take-aways I see are that the JSON-LD response system would need to be quite extensible, and we’d need to be able to include some un-orthodox properties on some fields.

Also, issues of validation and form processing need to be rethought pretty fundamentally.

In all these cases, there are work-arounds, but I’m hoping that these two cases sketch out the general ways in which a JSON-LD REST API might be used by client side apps.

What are other good case studies/examples?

Web Services and Context Core Initiative

Group organizers

Group notifications

This group offers an RSS feed. Or subscribe to these personalized, sitewide feeds:

Hot content this week