Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

We've moved the forum!

Please use forum.silverstripe.org for any new questions (announcement).
The forum archive will stick around, but will be read only.

You can also use our Slack channel or StackOverflow to ask for help.
Check out our community overview for more options to contribute.

General Questions /

General questions about getting started with SilverStripe that don't fit in any of the categories above.

Moderators: martimiz, Sean, Ed, biapar, Willr, Ingo, swaiba

Interface between SilverStripe and parallel services


Go to End


4 Posts   1625 Views

Avatar
jbothma

Community Member, 5 Posts

14 March 2012 at 8:22pm

Hi

I'm working on a system which uses SilverStripe with a whole bunch of custom data objects, and several other services that communicate with portable devices on some proprietary protocol rather than HTTP

Right now the code in SS digs around the database of the other service, and the other service digs around the SS database directly.

Is there a common way people create better interfaces between two PHP systems, particularly where SS is one of those? I guess the obvious approach is a REST interface over HTTP to silverstripe, and whatever makes sense depending on the other service implementation? While it'd be nice to manipulate SS objects directly from the outside, i guess it's quite nasty...

I'm quite a newbie to SS, so does anyone with experience of a system under load know - should I expect SS to handle a request over a REST interface to update an existing object and write it about 10 times per second? Of course to really know, I should prototype and try it, but it's also nice to know what to expect :)

Avatar
dhensby

Community Member, 253 Posts

14 March 2012 at 9:35pm

Silverstripe has in built api access to data objects, just use the restful server: http://api.silverstripe.org/2.4/sapphire/api/RestfulServer.html

I'm not sure about teen writes a second via silverstripe, though. I find ss takes about half a second to execute requests.

Dan

Avatar
jbothma

Community Member, 5 Posts

14 March 2012 at 11:04pm

Edited: 14/03/2012 11:06pm

Thanks! Looks like RestfulServer is really really handy. I found it shortly after my first post, sorry I missed it before.

I added the following to one of my classes

	static $api_access = true;
	
	public function Bob() {
		return "bobob";
	}

and when I try to call Bob with a POST to http://localhost/api/v1/Terminal/3/Bob

I get

HTTP/1.1 413 Request Entity Too Large
Date: Wed, 14 Mar 2012 09:55:18 GMT
Server: Apache/2.2.20 (Ubuntu)
Vary: Accept-Encoding
Connection: close
Content-Type: text/html; charset=iso-8859-1

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>413 Request Entity Too Large</title>
</head><body>
<h1>Request Entity Too Large</h1>
The requested resource<br />/sapphire/main.php<br />
does not allow request data with POST requests, or the amount of data provided in
the request exceeds the capacity limit.
<hr>
<address>Apache/2.2.20 (Ubuntu) Server at localhost Port 80</address>
</body></html>
You don't have access to this item through the API.

It's interesting that the message is "You don't have access to this item through the API." and it's main.php that's complaining.

I'm using SS 2.4.5

also, the only mention I can find of that error message is in www/sapphire/api/RestfulServer.php:

	protected function permissionFailure() {
		// return a 401
		$this->getResponse()->setStatusCode(401);
		$this->getResponse()->addHeader('WWW-Authenticate', 'Basic realm="API Access"');
		$this->getResponse()->addHeader('Content-Type', 'text/plain');
		return "You don't have access to this item through the API.";
	}

I'm testing with the default admin user and it does get the data responses when I go a GET to the object, but calling the method is failing.

Has anyone had luck with calling methods via RestfulServer?

Avatar
jbothma

Community Member, 5 Posts

15 March 2012 at 12:28am

Edited: 15/03/2012 12:39am

I worked out how to be able to call methods via the rest API :)

According to http://groups.google.com/group/silverstripe-dev/browse_thread/thread/ecf5e500c5c996a6?pli=1 I needed to add a static

	static $allowed_actions = array(
		'Bob',
	);

However, adding that to the array returned by extraStatics() for my extension of the Member class didn't work.

It turns out 'allowed_actions' isn't in the array of $decoratable_statics in DataObjectDecorator.php meaning the method name won't be found when RestfulServer postHandler checks whether the method is allowed.

Adding 'allowed_actions' => true, to $decoratable_statics fixes that, so I can call methods defined in extensions, e.g.

	public function WithdrawCredit() {
		$this->owner->Credits -- ;
		$this->owner->write();
	}

Whether this sort of action ascribes to RESTful philosophy, I'm not sure yet :) It does tidy up my system :D

I fixed the 413 error by adding curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Length: 0')); to the client.

Does anyone know whether omitting allowed_actions from decoratable_statics was a mistake, or is it a bad idea for some reason?

Is there a good reason why api_access is not a mergeable decorator?

If this is a bug, should I bother with a 1 line patch?

The issue of performance is still open, and I'll post results if I benchmark some time.

Thanks for the half second response Dan.

No doubt performing authentication, lookup and write will be more work than the existing hack, but I'm getting really tired of the inherited hacks.

If anyone can share other approaches to interfacing with SS on the same machine (for now at least) that'd be very interesting.

JD