Bright Content Design Document: Web Triggers

Many Web publishing systems with plug-in architectures use classic call-backs for plug-ins. A good example is the Weblog engine [http://pyblosxom.sourceforge.net/ PyBlosxom]. Plug-ins register call-back as a Python callable such as cb_start (called when the engine is initialized), cb_prepare (called at the beginning of each HTTP request to the engine). WSGI opens up a more flexible alternative approach in such systems. We call these Web triggers (see below for notes on the name).

All events to be handled by plug-ins are exposed as URL such as:

/brightcontent/trigger/...

The URL prefix should be flexible. This is probably a matter of signaling to the chosen dispatcher (e.g. Routes) which URL patterns are reserved for Web triggers. Each plug-in listens for a particular URL pattern for each event that it cares about. Events are propagated through the plug-ins by having something make an HTTP call back to the bright content server using a trigger URL. Some events might be triggered by the core BC engine itself (e.g. one should be triggered upon launch of the Web server, so that plug-ins can initialize themselves). Others might be called from other plug-ins, or even client-side tools.

The actual invocation of the URL can be made either by the equivalent of urlopen('http://example.com//brightcontent/trigger/event') or using a tool such as [http://pythonpaste.org/module-paste.recursive.html Paste recursive] to mock up such a URL invocation. If the invocation is exposed to tools over the network it may open up a security issue, which is discussed below:

Use-case/example

For example:

The above example is a bit contrived: in many cases a good comment plug-in would handle the 3 tasks of spam detection, bad content database update and spam comment removal, but there's no reason the plug-in should not manage its own flow-of control via triggers, and the advantage of this is that third parties could register plug-ins that extend the comments plug-in in new ways, by listening for the triggers.

In general, there would be a core set of triggers launched by the BrightContent engine, but the community is free to set their own trigger conventions.

The above example also skirts some questions of URL and HTTP convention. In a real-world comments system a better scheme might be URLs such as something such as /brightcontent/plugins/comments/new-comment/ (generally invoked thought HTTP PUT). HTTP POST to /brightcontent/plugins/comments/check-comment/... for spam checking, and which results in an addition to the store only if found to be spam-free.

Security

Since a trigger may be accessed via HTTP, a trigger may provide a public interface to custom features. With this in mind HTTP Auth can be used to secure a trigger resource. For example, consider a stats plug-in at the resource:

/brightcontent/trigger/stats/entries_by_author/elarson

This plug-in might find all the entries (including comments) made by an author. This type of request might be resource intensive or contain private information. The trigger could then be protected using HTTP Authentication when requested from a domain outside of a set of trusted clients. If the resource is requested internally by the BrightContent engine, the security measures could be ignored or enforced.

We strongly recommend that the specification for every plug-in documents its security implications if invoked by a trigger over the network.

Configuration

The base URL for triggers should be the base URL for the Weblog, and there should be a new config parameter for the trigger path component, e.g.

trigger = trigger

In the Bright Content section of the INI file.

What about REST?

We believe that the Web triggers idea is very RESTful. The chain of WSGI modules that "listen" for the URL *is* the Web resource represented by the URL, and all the ideas of REST apply as usual. For example, if the WSGI handlers are expected to modify state based on the event, it should be invoked using HTTP POST to the URL rather than GET.

Why call them "Web triggers"?

People tend to think of DBMS technology when they think of the term "trigger". But if you boil it down even in DB terms, a trigger is is just a marker to invoke an action automatically upon an event. It's like the [http://en.wikipedia.org/wiki/Observer_design_pattern Observer design pattern]. In this case we are using Web technology as much as possible, which means that a Web invocation is the best way to signal an event. The combination of the agreed convention for the event URL and the WSGI components designed to perform some action upon seeing this event constitutes a "trigger" by means of the "Web".

Other examples of plug-in approaches

Listed in part for skimming of ideas and in part for "ewww, we don't want that" reaction :-)

FtNotes: Bright_Content:Design:Web_Triggers (last edited 2006-12-19 20:40:42 by EricLarson)