Search

I’d really love to see Symphony support a RESTful model for adding/editing/deleting section entries. Any chance this is something that’s being looked at for 3.0? Can it be? It would make Symphony a great prospect for simple data collection from applications. I’ve mentioned a few times on IRC that I’m working on using Symphony 2 to collect crash reports from my cocoa applications, but using HTML forms to submit the data is making me a little uneasy. I could spend hours writing JSON front ends to this stuff (and pushing back proper responses to the client) but if it’s coming, I’ll happily make do with what I have.

No idea whether this is planned, but the current HTML form + Event method is almost exactly a RESTful interface anyway. The HTML page to which you submit the form to is the handler, which accepts a POST array and updates the database, returning its result as XML. Additionally by passing GET parameters to the URL and attaching Data Sources you have a read API returning XML as well.

How are you sending the data from your app… as a POST? How would you prefer to do so?

I’ve used Symphony in this way many times. My fairly crappy Archiving XML with Symphony is a basic example — in one mode the page (API URL) returns XML of existing entries. When I send a POST without an ID, it returns the success or failure of new entry creation. When I send a POST with an ID, it returns the success or failure of an entry update.

With a small PHP script to re-interpret POST values, and an XML-to-JSON XSL template (which already exists) I think we already have everything we need.

It would be pretty cool to have a single endpoint for RESTful API calls. Outside the core I’m thinking an extension with an event filter could expose any events it’s attached to at particular URL ($root/api/) and then do what Nick refers to.

I suppose it depends on what you want to achieve. A simple API may be a single stub onto which a method name is appended (either as a page URL Parameter or on the querystring), but a more complex API may require several pages to namespace the methods.

I quite like the idea of an API “builder”. One could specify the URL structure (much like a Page):

/api/{method}/{response_type}/

And for each combination of parameters, the developer can choose which Events or Data Sources are attached to the page at runtime.

For example:

/api/articles/xml/

Could be configured so when it receives a normal GET: attach a Data Source named “API: Articles” and format the results as XML. Similarly, if a POST was sent, it could be configured to attach only an “API: Articles” Event, and format the output as required.

Alternatively:

/api/comments/json/25/desc/

Could be configured so that when it received a GET it returns the latest 25 comments in descending order, in JSON format.

APIs and their uses are so varied, I’m not sure how it could be genericised to cover all bases. I’m fairly sure a read/insert/update returning semantic XML or JSON is very achievable just using existing Events and Data Sources. For me, the key to a good web API is consistency in the requests and response:

Symphony already has this in abundance with its Events and Data Source response XML. Therefore using Pages with appropriate URL Parameters and copy-of statements may suffice.

For my flash and cocoa stuff I tend to use the raw post data instead of the $_POST variable.

Standard form post data is a long string of key/value pairs just like when you append variables onto the URL but instead they get put in the HTTP request body. The $_POST array contains the decoded key/value pairs.

Raw Post data:

&variable1=test&variable2=anothertest

Instead I like to skip that step and just put a whole XML document in the HTTP request body, and set the HTTP method to POST. You can then read the XML in your Event using the following code: -

// Sample XML
// <variables>
//   <variable1>test</variable1>
//   <variable2>anothertest</variable2>
// </variables>

// Wow a Simple XML document
$postXML = simplexml_load_file('php://input');
// Now we can setup the $_POST array ourselves using the XML
$_POST['variable1'] = (string) $postXML->variable1;

Note: You might need to change how your trigger works because the $_POST array of keys/values will be blank.

@nickdunn, a little off topic but how reliable is that XML to JSON XSL template?

I’ve not used a generic XML-to-JSON template myself, instead favouring to craft the output JSON myself. But you could try one of these:

It’s tempting to make a simple read-only general API extension (then read/write), where you can select which sections are available via the api; it seems like it’d be fairly easy to do as well. You could limit what fields you want to grab by doing something like api/students/lastname,firstname/…

I wonder though, how’d you make it extensible through the admin interface, so you could override what queries it made or how it made them. Maybe if you had control over the query itself, but that seems a little too powerful.

Database Manipulator may help here. It’s a layer on top of Symphony so you can specify select queries in an SQL-like way:

$entries = DatabaseManipulator::getEntries(
    'articles',
    array('title', 'body', 'date'),
    array('published' => 'yes'),
    array('limit' => 25)
);

This will return 25 entries from Articles (title, body, date) where the Published checkbox is ticked. This could be made dynamic by passing these values on the querystring in a more API-like manner.

The issue then arises of security. You would need checks within the PHP such that only specific sections, and specific fields within those sections, can be selected, else your entire section structure is vulnerable.

The alternative is a way to dynamically build a Data Source on the fly. You could pass the handle of the Data Source on the URL, and build its $dsParamORDER, $dsParamLIMIT, $dsParamSORT, $dsParamSTARTPAGE, $dsParamFILTERS and $dsParamINCLUDEDELEMENTS on the fly?

After the initial setup, choosing which sections (and fields) are available through the api, maybe something like /api/users/article/title,body,date/published:yes,date:2009/25

But yes, first checking to see if the developer wants the article section to be accessible, and that the title/body/date fields are accessible too. That DBM extension would be super handy for this. Using the DS method you’re mentioning might be overkill since DBM can handle it, and probably more quickly.

Since there’s no real access control in symphony it’d just be a global api, no need for api tokens at all, atleast until the extension goes to read/write.

The next thing I was going to try to do in symphony was making a simple invoicing ensemble, and the api could be useful for integration.

Edit: I guess you could basically use a slightly modified section-schemas to determine which fields/sections to make available, instead of creating a extra table in the database to do something that you’ve already done. Then just look through the xml to see if it’s available.

I would like to see an iCal-import, much like the dynamic XML-source.

Might be an idea to make that request into another thread where it can be discussed separately away from the REST API stuff. Good idea though.

This thread is very old now, but for completeness I'll add that this has been fleshed out into a full extension: REST API, which provides read and write access to all sections and entries, supporting many output formats such as XML, JSON and YAML. Hoorah!

Create an account or sign in to comment.

Symphony • Open Source XSLT CMS

Server Requirements

  • PHP 5.3-5.6 or 7.0-7.3
  • PHP's LibXML module, with the XSLT extension enabled (--with-xsl)
  • MySQL 5.5 or above
  • An Apache or Litespeed webserver
  • Apache's mod_rewrite module or equivalent

Compatible Hosts

Sign in

Login details