Skip to content

Commit

Permalink
Merge 30f2d96 into 689084b
Browse files Browse the repository at this point in the history
  • Loading branch information
byjg committed Oct 17, 2017
2 parents 689084b + 30f2d96 commit efe3240
Show file tree
Hide file tree
Showing 9 changed files with 148 additions and 96 deletions.
112 changes: 52 additions & 60 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ The quick guide is:
For example, if you want to process the HTTP method POST you have to do:

```php
namespace Sample
<?php
namespace Sample;

class MyClass extends \ByJG\RestServer\ServiceAbstract
{
Expand All @@ -38,7 +39,7 @@ class MyClass extends \ByJG\RestServer\ServiceAbstract
The usual url for call this class is (see more in Routing below):

```
http://yourserver.com/1.0/Sample.MyClass/1234.json # Or .xml or .csv
http://yourserver.com/Sample.MyClass/1234 # Or .xml or .csv
```

### Processing the request
Expand All @@ -64,7 +65,8 @@ The main goal of the RestServer ByJG is work with the objects in your native for
JSON, XML or CSV is done by the platform. See below some examples:

```php
namespace Sample
<?php
namespace Sample;

class MyClass extends \ByJG\RestServer\ServiceAbstract
{
Expand Down Expand Up @@ -132,12 +134,13 @@ handle this specific action. Some examples below:

### Routing

RestServer ByJG uses the Nikic/FastRoute project to do the routing. Yout need copy the file web/app-dist.php as route.php
RestServer ByJG uses the Nikic/FastRoute project to do the routing. Yout need copy the file web/app-dist.php as app.php
into the root of your public folder accessible throught the web.

The app-dist.php file looks like to:

```php
<?php
require_once __DIR__ . '/../vendor/autoload.php';

\ByJG\RestServer\ServerRequestHandler::handle();
Expand All @@ -149,31 +152,32 @@ There some pre-defined routes as you can see below but you can change it any tim

The pre-defined routes are:

| Pattern | Exeample |
|----------------------------------------------------------------|------------------------------------------|
| /{version}/{module}/{action}/{id:[0-9]+}/{secondid}.{output} | /1.0/MyNameSpace.Module/list/1/2345.json |
| /{version}/{module}/{action}/{id:[0-9]+}.{output} | /1.0/MyNameSpace.Module/list/1.json |
| /{version}/{module}/{id:[0-9]+}/{action}.{output} | /1.0/MyNameSpace.Module/1/list.json |
| /{version}/{module}/{id:[0-9]+}.{output} | /1.0/MyNameSpace.Module/1.json |
| /{version}/{module}/{action}.{output} | /1.0/MyNameSpace.Module/list.json |
| /{version}/{module}.{output} | /1.0/MyNameSpace.Module.json |
| Pattern | Exeample |
|---------------------------------------------|---------------------------------|
| /{module}/{action}/{id:[0-9]+}/{secondid} | /MyNameSpace.Module/list/1/2345 |
| /{module}/{action}/{id:[0-9]+} | /MyNameSpace.Module/list/1 |
| /{module}/{id:[0-9]+}/{action} | /MyNameSpace.Module/1/list |
| /{module}/{id:[0-9]+} | /MyNameSpace.Module/1 |
| /{module}/{action} | /MyNameSpace.Module/list |
| /{module} | /MyNameSpace.Module |

All variables defined above will be available throught the $_GET. The variables output, module and version having a special
All variables defined above will be available throught the $_GET. The variables module and action having a special
meaning into the system:

- **output** will be define the output. Can be "json", "xml" or "csv"
- **module** will be the full namespace to your class. You have to separate the namespaces with "period" (.). Do not use back slash (\);
- **vesion** have a symbolic version for your rest server.
- **action** will match a specific action inside your class

#### Customizing your route file
Creating the pattern:

The processRoute accepts 5 parameters:
* $moduleAlias
* $routePattern
* $version
* $defaultOutput
* $routeIndex
- {variable} - Match anything and sets to "variable".
- {variable:specific} - Match only if the value is "specific" and sets to "variable"
- {variable:[0-9]+} - Match the regex "[0-9]+" and sets to variable;

all matches values can be obtained by

```php
$this->getRequest()->get('variable')
```

#### Creating Module Alias

Expand All @@ -182,78 +186,66 @@ Instead to pass the full namespace class you can create a module alias.
Just add in the route.php file the follow code:

```php
<?php
\ByJG\RestServer\ServerRequestHandler::handle([ 'somealias' => 'Full.NameSpace.To.Module' ]);
```

In the example above if the parameter "module" matches with the value "somealias" will be mapped to the class "\Full\NameSpace\To\Module"

#### Creating your own routes

You can override the default route values and create your own.
You can override the default route values and create your own. See an example:

```php
<?php
\ByJG\RestServer\ServerRequestHandler::handle(
null,
[
'somealias' => 'Namespace.to.My.Class',
'another' => 'Another.Namespace.To.Class'
],
[
[
[
"method" => ['GET'],
"pattern" => '/{module}/{action}/{id:[0-9]+}.{output}',
"handler" => '\ByJG\RestServer\ServiceHandleOutput'
]
"pattern" => '/{module:somealias}/{action}/{id:[0-9]+}',
"handler" => \ByJG\RestServer\HandleOutput\JsonHandler::class
],
[
"method" => ['POST'],
"pattern" => '/{module:another}/{action:name}/{field}',
"handler" => \ByJG\RestServer\HandleOutput\JsonHandler::class
],
]
);
```

#### Versioning your rest service

You can define a version to yout rest service and create a EOL for changes in the services that breaking the interface. Just set in the "route.php" file the follow line:

```php
\ByJG\RestServer\ServerRequestHandler::handle(null, null, '2.0');
```

This will populate the variable "version".

#### Set the default output format
**Available Handlers**

The basic ServiceHandleOutput can output the objects in Output::JSON, Output::XML or Output::CSV.
Normally this is set in the route, but you can ommit from the route and set a default output here.

```php
\ByJG\RestServer\ServerRequestHandler::handle(null, null, null, Output::JSON);
```

#### Define a different route handler than index.php and route.php

The default filename for route process is 'index.php' or 'route.php'.
If you use a different one you have to set it here.

```php
\ByJG\RestServer\ServerRequestHandler::handle(null, null, null, null, 'acme.php');
```
- JsonHandler
- XmlHandler
- HtmlHandler
- JsonCleanHandler

Note: you have to configure your webserver to support this file.

## Install

Just type: `composer install "byjg/restserver=~1.1"`
Just type: `composer install "byjg/restserver=2.0.*"`


## Running the rest server

The follow examples assumes that the handle is in the "index.php"
You need to setup your restserver to handle ALL requests to a single PHP file. Normally is "app.php"

#### PHP Built-in server

```
php -S localhost:8080 index.php
php -S localhost:8080 app.php
```

#### Nginx

```
location / {
try_files $uri $uri/ /index.php$is_args$args;
try_files $uri $uri/ /app.php$is_args$args;
}
```

Expand All @@ -263,7 +255,7 @@ location / {
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ ./index.php [QSA,NC,L]
RewriteRule ^(.*)$ ./app.php [QSA,NC,L]
```

----
Expand Down
36 changes: 36 additions & 0 deletions src/HandleOutput/BaseHandler.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

namespace ByJG\RestServer\HandleOutput;

use ByJG\RestServer\ServiceAbstract;

abstract class BaseHandler implements HandleOutputInterface
{
protected $options = [
'header' => [],
'build-null' => true,
'only-string' => false
];

public function option($option, $value)
{
$this->options[$option] = $value;
}

public function writeHeader()
{
foreach ($this->options['header'] as $header) {
header($header);
}
}

public function writeOutput(ServiceAbstract $instance)
{
$serialized = $instance
->getResponse()
->getResponseBag()
->process($this->options['build-null'], $this->options['only-string']);

return $this->getFormatter()->process($serialized);
}
}
12 changes: 12 additions & 0 deletions src/HandleOutput/HandleOutputInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@
interface HandleOutputInterface
{

/**
* @param $option
* @param $value
* @return $this
*/
public function option($option, $value);

/**
* @return void
*/
Expand All @@ -32,4 +39,9 @@ public function writeOutput(ServiceAbstract $class);
* @return Handler
*/
public function getErrorHandler();

/**
* @return \ByJG\Serializer\Formatter\FormatterInterface
*/
public function getFormatter();
}
19 changes: 9 additions & 10 deletions src/HandleOutput/HtmlHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,25 @@

namespace ByJG\RestServer\HandleOutput;

use ByJG\RestServer\ServiceAbstract;
use ByJG\Serializer\Formatter\PlainTextFormatter;
use Whoops\Handler\PrettyPageHandler;

class HtmlHandler implements HandleOutputInterface
class HtmlHandler extends BaseHandler
{

public function writeHeader()
public function __construct()
{
header('Content-Type: text/html');
$this->option('header', [
'Content-Type: text/html'
]);
}

public function writeOutput(ServiceAbstract $instance)
public function getErrorHandler()
{
$serialized = $instance->getResponse()->getResponseBag()->process();
return (new PlainTextFormatter())->process($serialized);
return new PrettyPageHandler();
}

public function getErrorHandler()
public function getFormatter()
{
return new PrettyPageHandler();
return new PlainTextFormatter();
}
}
13 changes: 13 additions & 0 deletions src/HandleOutput/JsonCleanHandler.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace ByJG\RestServer\HandleOutput;

class JsonCleanHandler extends JsonHandler
{
public function __construct()
{
$this->option('build-null', false);
$this->option('only-string', false);
parent::__construct();
}
}
22 changes: 9 additions & 13 deletions src/HandleOutput/JsonHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,25 @@

namespace ByJG\RestServer\HandleOutput;

use ByJG\RestServer\ServiceAbstract;
use ByJG\RestServer\Whoops\JsonResponseHandler;
use ByJG\Serializer\Formatter\JsonFormatter;

class JsonHandler implements HandleOutputInterface
class JsonHandler extends BaseHandler
{

public function writeHeader()
public function __construct()
{
header('Content-Type: application/json');
// header('Access-Control-Allow-Origin: *');
// header("Access-Control-Allow-Headers: X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Request-Method");
// header("Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT, DELETE");
$this->option('header', [
'Content-Type: application/json'
]);
}

public function writeOutput(ServiceAbstract $instance)
public function getErrorHandler()
{
$serialized = $instance->getResponse()->getResponseBag()->process();
return (new JsonFormatter())->process($serialized);
return new JsonResponseHandler();
}

public function getErrorHandler()
public function getFormatter()
{
return new JsonResponseHandler();
return new JsonFormatter();
}
}
19 changes: 9 additions & 10 deletions src/HandleOutput/XmlHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,25 @@

namespace ByJG\RestServer\HandleOutput;

use ByJG\RestServer\ServiceAbstract;
use ByJG\Serializer\Formatter\XmlFormatter;
use Whoops\Handler\XmlResponseHandler;

class XmlHandler implements HandleOutputInterface
class XmlHandler extends BaseHandler
{
public function writeHeader()
public function __construct()
{
header('Content-Type: text/xml');
$this->option('header', [
'Content-Type: text/xml'
]);
}

public function writeOutput(ServiceAbstract $instance)
public function getErrorHandler()
{

$serialized = $instance->getResponse()->getResponseBag()->process();
return (new XmlFormatter())->process($serialized);
return new XmlResponseHandler();
}

public function getErrorHandler()
public function getFormatter()
{
return new XmlResponseHandler();
return new XmlFormatter();
}
}
Loading

0 comments on commit efe3240

Please sign in to comment.