Jump to content

RESTful API in PW?


diogo
 Share

Recommended Posts

after reading this article http://www.searchenginejournal.com/why-arent-you-paying-attention-to-apis-for-your-cms/41155/, I started looking a bit deeper on what it means and how hard would it be for PW to have such an API...

I didn't come to a conclusion, as would be expectable from such a noobie in such things :) but still, I wanted to post here some of the documents I stumbled on to tease you people to have a thought on this.

http://ecmarchitect.com/archives/2009/11/23/1094

http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=cmis

http://rest.elkstein.org/

http://docs.fuelphp.com/general/controllers/rest.html

http://wiki.alfresco.com/wiki/CMIS

http://drupal.org/project/cmis

http://www.elefantcms.com/wiki/RESTful-APIs

http://mambo-manual.org/display/dev/Interacting+with+the+RESTful+API

  • Like 1
Link to comment
Share on other sites

PW is a perfect platform for your RESTful APIs or any kind of web services. Some of my clients keep multiple sites that need to talk and share data with each other at regular intervals, and I always build "RESTful" web services with ProcessWire to accomplish this. PW was designed to make this particularly easy. But I'm not a fan of the terms "REST" or "RESTful", as I think it implies that there's something more than what it is. This is the way we were doing web services before those terms existed, and it is basically the way you would think to do it even if you never heard of it.

If you are dealing with primarily GET requests (which covers most of my needs), then you don't need anything other than ProcessWire and PHP's standard file_get_contents(), json_encode() and json_decode() (or simple_xml) functions. If your needs also involve POST requests (or your PHP doesn't let you load URLs with its file functions), then I recommend grabbing the really simple and easy-to-use Snoopy class too. I don't personally bother with PUT or DELETE requests, or understand why they would be necessary or preferable over authorized GET/POST requests doing the same thing. Let me know if you'd like me to supply any simple code examples of how you might use ProcessWire in this manner.

  • Like 2
Link to comment
Share on other sites

I think there were good intentions behind them and I understand the original purpose, but i've just never come across anyone actually using them in their API. Though I'm sure they are out there. But there's nothing you can't do with them that you can't already do without them, so I think many see them as unnecessary barriers to adoption of their API.

Link to comment
Share on other sites

I have seen PUT and DELETE used few times and at least Wufoo uses them: http://www.wufoo.com...pi/v3/webhooks/ Also interesting discussion on Stackoverflow: http://stackoverflow...delete-post-get. I have never used them on API:s that I have build... but now that I think it my API:s have always been read only.

I'm not sure but wouldn't module doing automatic REST api for your PW application be pretty nice? At least for read access? Granted, that is pretty quick to custom build, but it would be great to have something as streamlined as PW Selector API on REST too :)

EDIT: Something like http://couchdb.apache.org/docs/intro.html has (RESTful JSON API)

Edited by apeisa
Link to comment
Share on other sites

Let me know if you'd like me to supply any simple code examples of how you might use ProcessWire in this manner.

I'm not really planning to do something with it right now, i was just curious after reading that article, and all that followed. But, ya, would be nice :)

I'm not sure but wouldn't module doing automatic REST api for your PW application be pretty nice?

It would! Would also be nice if it would be on the core, and with documentation. I imagined that doing this would be something trivial with PW, but couldn't find anything on the site or on the forums about it... and since it's something that some CMS's make a big fuzz about...

Also, what are your thoughts on CMIS? I'm all for standards implementation, and this looks pretty interesting. Again... this is a muddy area for me, sorry if i'm not making pertinent questions

Link to comment
Share on other sites

I'm not sure but wouldn't module doing automatic REST api for your PW application be pretty nice? At least for read access?

I think it'd be worthwhile for marketing, but not sure how useful it would be unless it can make some assumptions about the service API (like PW-to-PW or something). The reason I question the usefulness is just because outside of a known service API, the read-only aspects don't amount to much more than this:

$data = json_decode(file_get_contents('http://domain/path/to/service?a=b')); 

I'm just not sure a wrapper class adds much value here? But once we know about the service, then a wrapper class seems to start adding value. So perhaps the value comes from defining an interface or abstract class to be extended, rather than adding a layer to something that doesn't need it. While I've built a lot of web services, and built tools to read from a lot of services, I'm not an expert on web service standards by any means. Someone correct me if I'm missing anything obvious.

Also, what are your thoughts on CMIS? I'm all for standards implementation, and this looks pretty interesting. Again... this is a muddy area for me, sorry if i'm not making pertinent questions

I also agree that it looks interesting. I like the ideas behind it for sure. But I've not been able to make much sense of it after half an hour, so I guess I'd say it's a bit muddy for me too. :) Anything makes sense after enough time reading, researching, etc., But my brief exposure gives me the impression that CMIS seems like a complex answer for a simple question (and I admit that's an uninformed opinion). I might feel differently after more time. But initial impressions are that it's something to watch and follow, and put on the roadmap if there is high demand for it someday in the future.

Link to comment
Share on other sites

Ryan, what I had in mind was other way around. Like install module, set which content (templates, parents etc) should be available through API and then you could do this (without creating any templates etc):

These are more or less pseudo-code:

GET /api/news/

GET /api/events/limit-10/

POST /api/fetch/ (and post with variables that build your selector)

etc...

Sure, it won't require much more than one template, which transforms POST/GET request to PW api selectores, validates those and then return JSON.

Link to comment
Share on other sites

Ryan, what I had in mind was other way around. Like install module, set which content (templates, parents etc) should be available through API and then you could do this (without creating any templates etc):

So what you are talking about here is a known service API? One where the system of access URLs, expected input/output data are known ahead of time? In this case, I totally agree on the value of a wrapper for it. It's the general purpose, unknown service REST wrapper that I question the value of.

Btw, ProcessPageSearch has a service API, and I've wondered about re-introducing this as a distributable template that people can install and use on their front end as a read-only web service with authentication. We could easily build the wrapper class for accessing it from PHP which would mimic use of $pages.

Link to comment
Share on other sites

Btw, ProcessPageSearch has a service API, and I've wondered about re-introducing this as a distributable template that people can install and use on their front end as a read-only web service with authentication.

http://processwire.c...ndpost__p__3373

Well, that is actually pretty much what I was looking for - I had already forgotten that gem... Of course it would be great to have it as read only web service (with or without authentication - with authentication it could use PW access management also to decide what content should be available).

Link to comment
Share on other sites

CMIS

I also agree that it looks interesting. I like the ideas behind it for sure. But I've not been able to make much sense of it after half an hour, so I guess I'd say it's a bit muddy for me too. :) Anything makes sense after enough time reading, researching, etc., But my brief exposure gives me the impression that CMIS seems like a complex answer for a simple question (and I admit that's an uninformed opinion). I might feel differently after more time. But initial impressions are that it's something to watch and follow, and put on the roadmap if there is high demand for it someday in the future.

I'm not sure about this CMIS business. It think it's more in the realm of enterprise content (document) management systems and their repositories. Of course it would be neat to have the capability to integrate PW with some cmis enabled repositories, like Alfresco, but it seems pretty pretty complex and the reward questionable.

An interesting set of slides on the subject is this:

http://www.slideshare.net/alfresco/tech-talklivealfrescodrupal

All very nice but it does seem a little "enterprisy" to me.

Link to comment
Share on other sites

but it seems pretty pretty complex and the reward questionable.

I'm glad it's too complex for you guys too :) i felt a little dumb while reading those docs... but still, I really value any effort of making different tools be able to communicate and work together.

I have a look at ProcessPageSearch, and see if I can get a sense of it.

Link to comment
Share on other sites

  • 2 years later...
  • 2 weeks later...

yes ryan, sure there is much ado about..  it's a neat concept  once understood it assists machine communication.   personally i like it for its clearly defined concept.  yesterday i made pixels jump on node/express.io from GET-signals coming from a lampp.  any inter-communication can be done.  it  really is easy once understood 

Link to comment
Share on other sites

  • 3 weeks later...

In addition to the Service Pages module mentioned by diogo, there is also a rest helper for processwire made by clsource.

I am using it in a new project that implements bidirectional communication between mobile devices and a PW powered site. It is working great so far. I extended clsource's code to support basic HTTP Authentication.

  • Like 1
Link to comment
Share on other sites

  • 1 year later...

Here is what I have done so far:

PUT and DELETE is - as already said - very important to tell what should happen with the resource. Which can be compared to CRUD

  • GET - Show content
  • POST - Create content
  • PUT - Update content
  • DELETE - Remove content
<?php namespace ProcessWire;

ini_set('display_errors', 1);
error_reporting(E_ALL);

ob_start();
$method = $_SERVER['REQUEST_METHOD'];
$json = ['message'=>'NONE'];
//$request = explode("/", substr(@$_SERVER['PATH_INFO'], 1));

switch ($method) {
    case 'PUT':
        if($user->hasPermission('page-edit', $page)) {
            $pageFields = json_decode(file_get_contents('php://input'));
            foreach ($pageFields as $field => $value) {
                echo $field . " " . $value;
                $page->$field = $value;
                //$json[$field] = [$page->${field}];

            }
            $page->setOutputFormatting(false);
            $page->save();

            $json = ['message'=>'RESOURCE UPDATED'];
        } else {
            $json = ['message'=>'NOACCESS'];
        }
        break;
    case 'POST':
        if($user->hasPermission('page-create', $page)) {
            $pageFields = json_decode(file_get_contents('php://input'));
            $title = $sanitizer->text($pageFields['title']);
            if(!$page->children('title != '.$title)) {
                // create new page, if not already there
                $p = new Page();
                $p->template = $pageFields['template'];
                $p->parent = $page;
                $p->name = $sanitizer->pageName($pageFields['title'], true); // URL name

                $p->of(false); // turns off output formatting

                $p->title = $title;
                $p->save();
            }
            http_response_code(201);
            $json = ['message'=>'CREATED'];
        } else {
            $json = ['message'=>'NOACCESS'];
        }
        break;
    case 'GET':
        $json = [];
        $additionalFields = [
            'created' => $page->created.'000',
            'modified' => $page->modified.'000',
            'createdUser' => $page->createdUser->name,
            'modifiedUser' => $page->modifiedUser->name
        ];
        foreach ($fields->find('*') as $field) {
            $json[$field->name] = htmlentities($page->{$field->name});
        }
        foreach ($additionalFields as $field => $value) {
            $json[$field] = $value;
        }
        break;
    default:
        //handle_error($request);
        break;
}
//ob_clean();

header('Access-Control-Allow-Origin: *');

$content = json_encode($json);

//EDIT: My bad! POST is create, PUT is Update

 

 

 

  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...