There seem to be a variety of PHP frameworks that claim RESTful design patterns.
I'm looking for a framework that does a very good job providing a solid solution to these three items (or their equivalence).
1. Resource Requests
The first thing to do is be able to handle URL to resource resolution.
/path/to/resource = controller.action()
2. Request Methods
The second thing is to handle different types of request methods.
GET /path/to/resource = controller.get()
POST /path/to/resource = controller.post()
Perhaps with a fallback to a universal handler if no request method matches.
GET /path/to/resource = controller.action()
PUT /path/to/resource = controller.action()
POST /path/to/resource = controller.action()
3. Response Formats
Last, I have seen people attach formats to the end of URL's to help the framework know what type of response is expected.
/path/to/resource.html
/path/to/resource.json
Other ways people pass the response format in the header or as a URI param (?format=json).
These are three items that have to be covered. However, they don't have to be handled the same way I just showed - those are just examples.
I have been researching for a similar framework, but there doesn't seem to be much going on in the PHP world. Here is a related question about PHP REST frameworks.
Recess looks interesting, and I found the new REST controllers and routers of the Zend Framework pretty useful. I also started implementing an easier approach on top of the Zend components. Basically you register a bunch of view renderers (HTML, JSON and a simple form of XML are supported out of the box, via accept header parsing or overwriting it with a format=? parameter) and body parsers (Web Foms, and JSON are enabled) and based on this interface:
interface Feathry_Rest_Resource
{
public function index($params = null);
public function get($id, $params = null);
public function post($data, $params = null);
public function put($data, $id = null, $params = null);
public function delete($id, $params = null);
}
Where each method returns a plain array or object (with a toArray method) you can create a RESTful resource.
The advantage is, that your resources are entirely decoupled from any Representation.
They don't even have to know that they are being used via HTTP as long as they follow
the interface.
It is still very alpha, and there didn't seem to be much interest in it, but it does work so maybe you want to give it a try.
Recess has an interesting approach using annotations to define the routing.
If you're using PHP 5.3, then Tonic is a very lightweight framework with a focus on REST. It also uses a similar style to Recess using docblocks for the routing.
Personally I use Zend Framework with a custom version of their Zend_Rest_Route.
Each of these also go some way to providing some handling of the response formats, allowing you to provide content negotiation based not only on the method you describe, but by using the Accept header field to determine which formats the client will understand. My personal approach in ZF was to work with a data structure (basically an ArrayObject) with custom serializers for JSON, XML, YAML, etc. and have the controller determine the best output format to use.
Related
(There is a TL;DR: at the bottom)
I have a PDF produced via MVC pattern. I am working with an existing code, which was a bit of a mess, but now I am seeing a pattern emerge.
Currently, I have a Controller class, and inside I have many many separate functions, roughly one function per page. Each function does something like this:
function showPage()
{
//get some data from repository
$data1 = $this->repository->getData1();
$data2 = $this->repository->getData2();
//pass that data to the PDF API class, aka "the view"
//and the class takes care of creating PDF pages
//with the appropriate data
$this->pdfApi->showView($data, $data2);
}
The above achieves a clean separation between Repository (which only returns data), the PDF API service (which receives the data and doesn't need to care or maintain data retrieval constructs. And Controller which pretty much just asks for Data, and passes it to PDF API. And all was well until I came across this problem:
Problem
Most every page has a "footer" with a message, and a "Proposal Number" that needs to be displayed on the page. Sometimes it also has other pieces of data. Since PDF API class has no data in itself, someone has to pass that data to PDF API. I have been passing the above to pieces of information every time as part of function parameters but it became inconvenient -- there are too many parameters to pass and they are cluttering up the code.
Try at Solution
To reduce the clutter in parameter passing, In my Controller I have created pulled data (via Repository) for variables such as $footerText and $proposalNumber and then used them I populate PDF API's own class properties. Side-effect of this is that now my PDF API has the relevant bits of data embedded directly in the API (which I consider to be undesirable, since data layer now imposes into API class)
So far I have resisted the temptation to just pass the entire Repository object to PDF API because that will do very much the same - mix data layer and API Layer, plus, API layer will have unrestricted access to Data, which can also be undesirable.
Actual Problem
When I want clean layer separation, my code is cluttered with multiple function parameter passing.
When I pass the entire Repository to my API class, I mix data and API layers, and API layer gets too much freedom to use Repository class.
Can I somehow achieve layer separation without the clutter or "mixing layers" issues identified above?
If you like to see code, here is some code below of my various unsuccessful tries :)
TL;DR: My various unsuccessful tries to keep layers separate or to reduce clutter proved to be unsuccessful
//in Controller - Exhibit 1
//Separation achieved with only data parameter passing tying layers together
//but, too much clutter -- too many parameters
//maximum layer separation but lots of annoying data passing
$data1 = $this->repository->getData1();
....
$data24 = $this->repository->getData24();
$this->pdfApi->showView($data1, $data2, $data3, ... );
//in Controller - Exhibit 2
//Layers are mixed - my data is now tied into API
//in constructor
$data1 = $this->repository->getData1();
....
$data24 = $this->repository->getData24();
$this->pdfApi->setData1($data1);
$this->pdfApi->setData24($data24);
//inside function (API already has data as part of its own vars):
$this->pdfApi->showView();
//in Controller - Exhibit 3
//layers are mixed -- entire Repository got into my API
//in constructor
$repo = new Repository();
$this->pdfApi->setRepository($repo);
//inside function (API has full Repository access gets its own data and more):
$this->pdfApi->showView();
I think the Exhibit 1 is most correct.
//inside Controller
$data = array(
'data1' => $this->repository->getData1(),
//...
'data24' => $this->repository->getData4()
):
$this->pdfApi->showView($data);
I say this because a popular framework, ZF2, which I use, also ascribes to the same pattern.
//inside Controller
$data = array(
'message' => 'Hello world',
);
$view = new ViewModel($data);
In my case the View is the PDF API
I am a bit familiar with PHP MVC. Say, I have a controller like so:
class Customers{
public function method1( param1, param2, param3, ..., param_n ){
}
}
In my bootstraping page, I can grab a browser URL like so:
$url = explode('/', filter_var(rtrim( $_GET['url'], '/' ), FILTER_SANITIZE_URL));
I do $controller = $url[0] and $method = $url[1]. Any other elements in $url after the second index are parameters and can be collected into an array variable, say $params. Then I route to the relevant controller method and parameters like so:
call_user_func_array([$controller, $method], $params);
PLEASE NOTE: Above code is for illustration purposes. I always do checks in real-life situations. Those checks are not shown here, so do not use the above examples for serious projects.
Now, I want to implement a RESTful API using MVC pattern. What I already know:
No browser is involved, so $_GET['url'] is out of it.
The endpoint is obtained from $_SERVER['REQUEST_URI']
The method is obtained from $_SERVER['REQUEST_METHOD']
How do I route to an endpoint, for example, customers/{12345}/orders to get the orders of a particular customer with id 12345?
How can I do this?
The quickest way to achieve what you want would be to just use FastRoute. But where is fun in that :)
That said, I am a but confused about the premise of yours. Is it a REST API, which will be consumed by some other code (like in a phone or a 3rd party web app), or is it a proper website, where you just want to get pretty URLs?
Because if it's the former case, then making fancy URL parsing is completely pointless. Instead of messing round with URLs, you should be reading this article. Real REST API does not need a fancy URL parsing.
I will assume that what you are actually makingis a proper website, but with pretty URLs.
First you would have to implement a routing mechanism, which takes a list of regexp patterns, matches them agains your provided URL (which you could be extraction from $_GET['url'] or maybe $_SERVER[REQUEST_URI] (your code actually wouldn't care from where the URL was gathered ... you shouldn't be accessing superglobals inside functions/classes).
A simple version of this is explained in this answer. I am to lazy to rewrite it all =P
The second (and highly optional) part is creating code, that would take a human-readable route notation (like: /users/{id|[0-9]+}as an example) and turning it into the regular expression, which can be consumed by your routing mechanism.
If you decide to have the human-readable notations, then there are two major directions:
inline notations (see the example above or FastRoute)
config file (probably JSON or YAML) with notations
As for "how the end result might look like", you can probably look at the code sample here. That would illustrate one of the available option for the router's public interface.
TL;DR
Your question is vague and it is hard to understand what exactly would be helpful for you.
We are developing an application in Symfony (2.7) that deals with third party entities and usually needs to transform (or fill) objects from one subsystem to another.
Take this example where we need to fill $destinationObject with data stored in $sourceObject:
$sourceObject;
$destinationObject = new DestinationObject();
$destinationObject->setProperty01($sourceObject->getProperty01());
$destinationObject->setProperty02($sourceObject->getProperty02());
$destinationObject->setProperty03($sourceObject->getProperty03());
$destinationObject->setProperty04($sourceObject->getPropertyWithDifferentName());
$intermediateValue = explode('/',$sourceObject->getProperty04());
$destinationObject->setProperty05($intermediateValue[0]);
$destinationObject->setProperty06($intermediateValue[1]);
Manual method (or no method) leads to duplicated code, copy&paste practices, etc.
So my question is:
Where is the propper place to implement this kind of "transformations"?
My ideas so far:
Doing it as a model method like $destinationObject->loadFromSourceObject($sourceObject) is a bad idea (entity coupling)
I don't like the idea of building an utility class full of static methods
...
EDIT: Also, there's a common situation where in $destinationObject we need to load data from both $sourceObjectFromClassA and $sourceObjectFromClassB, so SourceObjectToDestinationObjectTransformer understood as a method returning a new created DestinationObject is not a valid option. I mean, something like this may be needed (bad code coming warning, just for exemplification purpose):
$destinationObject = new DestinationObject();
$destinationObject->loadFromSourceClassA($sourceObjectFromClassA);
$destinationObject->loadFromSourceClassB($sourceObjectFromClassB);
Alright so I'm trying to make some sense of all these patterns.
Alright, so I'm coding an applicantion in CodeIgniter which needs to be able to send data about a car and a customer to different types of companies using SOAP, maybe XML, comma-separated and so on.
But they all need the same thing.
I wanna make it as dynamic as possible and make sure it's easy to write tests.
So the service should take a couple of things:
a handler
applicants [1-2]
params
object
I started up creating different classes
Gr8Exp
NordCar
SwePerf
each implementing the interface iServiceRequest
interface iServiceRequest{
/**
* Send the request to the company server.
*/
function sendRequest();
/**
* Saves the response into the database.
*/
function saveResponse();
/**
* Prepares the request to the company, setting info from form and shit.
*/
function prepareRequest();
/**
* Soap, XML, CSV, JSON
* #param type $method
*/
function setRequestHandler(iServiceRequestHandler $handler);
}
Then they need to structure up the Soap, XML, CSV, JSON request depending on what handler i put in.
After those who needed to be validated (not all did) I used:
interface iAdaptServiceRequest{
/**
* Structure the array information and put it into an object structure in the right place.
*/
function structure(array $info);
/**
* Make all the checks for the function
*/
function validateInfo();
}
But I'm stuck, It worked really good when I just used SOAP request; but now. Since I need to format them differently, use a different handler for each type of request or company I don't know what to do.
I could put them i different folders and recreate the class in the different folders. But that's not a good practice since I'm duplicating code all over.
In the end I want to run some chaining like this:
$result = $m->prepareRequest()->sendRequest()->saveResponse();
Any suggestions??
IMHO:
-- create/use a front controller.
-- The front controller determines which request handler to use (JSON, SOAP, XML, etc).
-- The request handler generates a common "Request" object that behaves the same across all interfaces, basically putting variables into a common named format inside a "Request object"
-- It determines which service to send the request to and sends the request object there
-- The service processes the request object and generates a response object
-- The controller creates an appropriate (JSON/SOAP/XML) View object to process the response object into the correct view type and the View outputs your response as that type.
I would use something like yours: $result = $m->prepareRequest('JSON')->sendRequest()->saveResponse();, but specifing what format of data I'm sending.
The method prepareRequest(string $type) would check the format and call another method to convert your data to the respective format.
Something like this:
function prepareRequest(string $type){
if ($type == 'json'){
$this->convert2json();
}
if ($type == 'xml'){
$this->convert2xml();
}
// And so on
}
There is often confusion about the MVC or Observer pattern. This is not a situation in which this pattern is applicable. In the MVC pattern are the View and Model related to one another. The View must update itself based on information of the subject. A view and the underlying tables in a database are a good example. That is not what you want here.
The design pattern which suits this problem is the Builder pattern. The Builder pattern consists of four cooperating classtypes:
1. a Builder,
2. a ReaderManager,
3. a ConverterManager, and
4. a DataObject.
The ReaderManager is using the Interpreter pattern. Conversion can be done using the State pattern. What is the output of the ReaderManager (some DataObject) is the input for the ConversionManager. That can be done using an abstract class instead of an interface (my preference for data focused classes). The Builder connects the ReaderManager with the ConverterManager and takes care of the transport of data.
Some years ago I wrote about design patterns. The builder pattern was one of the patterns I described and this is the link to that page:
http://www.loekbergman.nl/InsideArchitecture/TheProcess/DesignPatterns/Builder
It shows a UML diagram of the pattern.
In the next link you can download a jar with some examples of design patterns. One of them the builder pattern:
http://www.loekbergman.nl/InsideArchitecture/DownloadsAndLicense
I have written this code several years ago, therefor do I give you this code without warranty. (Is that the correct term in this context?)
In the code you can see a folder with the name specifications. That is another example of the Interpreter pattern. (In the Builder pattern there is of course also an example of this pattern).
To be complete is here the link to the MVC - pattern:
http://www.loekbergman.nl/InsideArchitecture/TheProcess/DesignPatterns/Observer
and the Interpreter pattern:
http://www.loekbergman.nl/InsideArchitecture/TheProcess/DesignPatterns/Interpreter
I have been looking at APIs and developing a REST API for a project that we are working on.
The API only accepts connections from one source in JSON format, I understand that bit fine.
If understand the majority of what is being said, however I don't understand the 3rd code example down and where the routing information would go.
The example they have provided is:
$data = RestUtils::processRequest();
switch($data->getMethod)
{
case 'get':
// retrieve a list of users
break;
case 'post':
$user = new User();
$user->setFirstName($data->getData()->first_name); // just for example, this should be done cleaner
// and so on...
$user->save();
break;
// etc, etc, etc...
}
The part I am unsure on is how to accept the original request i.e. /get/user/1 - how do you route that to the correct part of the script.
If there has been another SO question (I have searched for quite some time) or any further educational examples please do point me in the right direction.
Update
I have found a few routing PHP classes out there, but nothing thats just small and does what it says on the tin, everything seems to do routing + 2000 other things on top.
I now have all the classes I need for this project named as I wish to access them from the URI i.e.:
/data/users
/data/users/1
/hash/users
/hash/users/1
/put/users/1?json={data}
So all of these should use the users class, then one of the data, hash or put methods passing anything additional after that into the method as arguments.
If anyone could just explain how that bit works that would be a huge help!
Thanks :)
From the outset it looks like the website you've pointed out does not include a router or a dispatcher. There are plenty of PHP5 frameworks around which include a route and/or a dispatch or some description. (http://en.wikipedia.org/wiki/Comparison_of_Web_application_frameworks#PHP)
A router would be a class which have a list of predefined routes these could be really basic or quite complex, all depends on want you want to do. A good REST router IMO would look something like this:
:module/:controller/:params
And then the router would then router to the correct action based on the HTTP request (GET, POST, PUT, DELETE, OPTIONS)
public function getAction($id) {
// Load item $id
}
In your case, you will need a redirect rule that will send the request to something like this
index.php?user=id. Then you can process the get request.
The best solution I found for php REST architecture (including routing) is:
http://peej.github.com/tonic/