Controller¶
The controller receives the request and handles the response. To build an API endpoint we should tell PSX which request methods are available and how the incoming and outgoing data looks. Because of this PSX can automatically validate incoming data and it is possible to generate documentation or other schema formats like i.e. Swagger or RAML based from the controller. In the following we describe the available options.
Annotation¶
It is possible to provide all API information to the controller through annotations.
<?php
namespace PSX\Project;
use PSX\Framework\Controller\SchemaApiAbstract;
use PSX\Record\RecordInterface;
/**
* @Title("Endpoint")
* @PathParam(name="foo_id", type="integer")
*/
class Endpoint extends SchemaApiAbstract
{
/**
* @QueryParam(name="count", description="Count of comments")
* @Outgoing(code=200, schema="PSX\Project\Model\Song")
*/
protected function doGet()
{
$count = $this->queryParameters->getProperty('count');
// @TODO return the result i.e. from a database
return new Song('Wut ueber den verlorenen groschen', 'Beethoven');
}
/**
* @Incoming(schema="PSX\Project\Model\Song")
* @Outgoing(code=201, schema="PSX\Project\Model\Message")
*/
protected function doPost($record)
{
// @TODO work with the record
return new Message(true, 'Successful created');
}
}
The schema must be either a simple POPO class which contains annotations to describe the schema or a json schema file. The model class PSX\Project\Model\Song could look like:
class Song
{
/**
* @Type("string")
*/
protected $title;
/**
* @Type("string")
*/
protected $artist;
public function __construct($title = null, $artist = null)
{
$this->title = $title;
$this->artist = $artist;
}
public function getTitle()
{
return $this->title;
}
public function setTitle($title)
{
$this->title = $title;
}
public function getArtist()
{
return $this->artist;
}
public function setArtist($artist)
{
$this->artist = $artist;
}
}
It is also possible to generate a PHP class based on a json schema.
vendor/bin/psx schema schema.json php
More information at the psx schema (https://github.com/apioo/psx-schema) project. The following annotations are available for the controller:
Annotation | Target | Example |
---|---|---|
@Description | Class/Method | @Description(“Bar”) |
@Exclude | Method | @Exclude |
@Incoming | Method | @Incoming(schema=”PSX\Project\Model\Song”) |
@Outgoing | Method | @Outgoing(code=200, schema=”PSX\Project\Model\Song”) |
@PathParam | Class | @PathParam(name=”foo”, type=”integer”) |
@QueryParam | Method | @QueryParam(name=”bar”, type=”integer”) |
@Title | Class/Method | @Title(“Foo”) |
RAML¶
Instead of annotations it is also possible to provide a schema file which describes the endpoint. At the moment we support the RAML (http://raml.org/) specification.
<?php
namespace PSX\Project;
use PSX\Api\Parser\Raml;
use PSX\Framework\Controller\SchemaApiAbstract;
use PSX\Framework\Loader\Context;
use PSX\Record\RecordInterface;
class Endpoint extends SchemaApiAbstract
{
public function getDocumentation($version = null)
{
return $this->apiManager->getApi(__DIR__ . '/endpoint.raml', $this->context->get(Context::KEY_PATH));
}
protected function doGet()
{
$count = $this->queryParameters->getProperty('count');
// @TODO return the result i.e. from a database
return [
'title' => 'Wut ueber den verlorenen groschen',
'artist' => 'Beethoven',
];
}
protected function doPost(RecordInterface $record)
{
// @TODO work with the record
return [
'success' => true,
'message' => 'Successful created',
];
}
}
RAML definition (endpoint.raml)
#%RAML 1.0
title: Endpoint
baseUri: http://example.phpsx.org
/endpoint/{foo_id}:
uriParameters:
foo_id:
type: integer
get:
queryParameters:
count:
type: integer
responses:
200:
body:
application/json:
type: !include schema/song.json
post:
body:
application/json:
schema: !include schema/song.json
responses:
201:
body:
application/json:
type: !include schema/message.json