activitypub icon indicating copy to clipboard operation
activitypub copied to clipboard

Enable mapping of entity bundles and fields to ActivityStreams object types

Open nedjo opened this issue 6 years ago • 2 comments

Each Drupal content entity bundle (node type, media type, etc.) can be mapped to a specific Activity Streams object type.

Notes:

  • Important that we assign sensible defaults. A site admin shouldn't require deep ActivityPub knowledge for basic setup.
    • On module install, programmatically enable and configure ActivityPub for applicable content entity bundles. Ideas:
      • Consult RDF schema where available. For example, types: ''schema:Article' on a content type would map to the Article ActivityPub object type; possibly, a field withproperties:'schema:text' would map to the content property in ActivityStreams.
      • Consider a commonsense default where the bundle label equals an ActivityPub object name. For example, the content type "Event" would map to Event.
      • Examine fields and make a determination. Example: Media type (media entity bundle) using the VideoFile source plugin maps to the Video object type.
  • For field mapping, options should be limited to applicable properties by field type. For example, a date field could be mapped to startTime. But note that the same field might map also to endTime and even duration.
  • Entity property mappings should be automatically assigned where feasible. For example, $node->updated should map to the updated property.
  • Need to respect properties and fields marked as internal, \Drupal\Core\TypedData\DataDefinitionInterface::isInternal().

Possible models

There are many ways this could work.

Relevant models include:

Core RDF module plus contrib RDF UI.

  • Mappings stored as config entities.
  • UI module enables editing of the config entities.

Configuring a content type:

rdf_ui_content_type

Configuring a content type's fields:

rdf_ui_fields

Core JSON:API module plus contrib JSON:API Extras

  • Resources programmatically generated.
  • Resources can be overridden/customized using a UI from JSON:API Extras

Selecting which resources to override:

jsonapi_extras_enabled_resources

Configuring properties and fields:

jsonapi_extras_resource

Group module

  • A plugin for each applicable bundle
  • Plugins can be enabled and configured

A plugin for each entity bundle that can be enabled for a group:

group_plugins

Configuration for a plugin:

group_plugin_install

nedjo avatar Dec 21 '19 01:12 nedjo

Spent some time looking over the options here. The model that stands out is JSON:API. The authors of that module have already tackled many of the hard questions we'll face here. While we won't need nearly all of what's there, we can draw a lot.

A key design feature of JSON:API - and a difference from our use case - is it "just works". While there's a lot of tweaking you could do, there aren't any necessary choices in exposing data for the JSON:API spec, so it's possible to have a default implementation that you just turn on. Only if you need changes do you then need to alter the defaults, which you can do either programmatically - like by writing custom normalizers - or via the config entity and accompanying UI provided by JSON:API Extras.

In our case, we're not just exposing our data; we have to also map it to the specific object types and properties expected in the AP spec. So "it just works" isn't a realistic goal. We need a configuration entity and UI. However, with some tweaks, the basic architecture of JSON:API is still applicable. Because our task is fundamentally similar. Like JSON:API, we:

  • Potentially want to handle any bundle of any content entity type.
  • Want to have available all entity properties and fields.

So like JSON:API we need a solution that's automatically aware of all such.

Following ResourceTypeRepository, we compile a repository of all content entity types and their bundles and fields. This repository does not include mappings, either to AP object types or their properties. That's done via a configuration entity type, parallel to that defined by JSON:API Extras, with the difference that it's defined by our base module. Then the admin UI for working with these config entities is in a dedicated UI module. (This part of the solution is closely parallel to core's RDF module and the contrib RDF UI.)

The admin UI looks a lot like that for JSON:API Extras, with the following differences:

  • Provide more user-friendly names for the resources. Yes, for DX we'll use the same keys, such as comment--comment, but provide the entity type label ("Comment").
  • Path is not applicable.
  • For Operations, rather than "Overwrite", we'll have (like the Group module) "Install" or, if already enabled, "Configure" and "Uninstall".
  • For State, either Installed or Uninstalled.
  • Once installed, a resource can be temporarily disabled by setting the disabled flag or deleted to uninstall.
  • On install of our module, we programmatically create and configure a basic set of these config entities so that, in this limited sense, it does indeed "just work".

nedjo avatar Dec 22 '19 01:12 nedjo

Ah I guess I mixed a bit of this with #6 (sorry). But as I was verbosely talking about there the RDF helps here because it is namespaced linked data, and can even include the schema.org NS properties.

ekes avatar Jan 11 '20 14:01 ekes