1
- # PHP JSON API Library #
1
+ [ ![ Build Status] ( https://api.travis-ci.org/DocnetUK/php-japi.svg?branch=2.0 )] ( https://travis-ci.org/DocnetUK/php-japi )
2
+ [ ![ Coverage Status] ( https://coveralls.io/repos/DocnetUK/php-japi/badge.svg?branch=2.0 )] ( https://coveralls.io/r/DocnetUK/php-japi )
2
3
3
- Simple library for building HTTP JSON APIs in PHP.
4
+ # PHP JSON API Library #
4
5
5
- Sure, I know, there are loads of MVC frameworks out there - and a few very popular ones - that can do this for
6
- you and a lot more besides.
6
+ Version 2 of our library for building HTTP JSON APIs in PHP.
7
7
8
- BUT, ` php-japi ` is designed to ONLY do HTTP JSON APIs, so it's small and fast.
8
+ Some major changes in version 2
9
+ - Adopt better code practices, allowing for Dependency Injection
10
+ - Adopt our new "Single Responsibility Controller" approach
11
+ - Decouple Router from JAPI container
12
+ - Use PSR logging
13
+ - Adopt PHP 5.4 minimum version
9
14
10
15
As we expand our Service Orientated Architecture (SOA) at Docnet, we're using this more and more - so I hope it's useful
11
16
to someone else ;)
12
17
13
18
Intended to use HTTP status codes wherever possible for passing success/failure etc. back to the client.
14
19
15
- Data/payload is your responsibility!
20
+ ## Single Responsibility Controller ##
16
21
17
- ## Hello, World! ##
22
+ We've adopted a new (for us) take on routing and controller complexity in 2.0. As such, where previously, you might have
23
+ had multiple actions (methods) on the same class like this:
18
24
19
- Let's assume we want our API to respond on the following URL: ` api.example.com/hello/world `
25
+ - ` BasketController::fetchDetailAction() `
26
+ - ` BasketController::addAction() `
27
+ - ` BasketController::removeAction() `
28
+ - ` BasketController::emptyAction() `
20
29
21
- So, here's the JAPI controller we'll need:
22
-
23
- ``` php
24
- <?php
25
- class Hello extends \Docnet\JAPI\Controller
26
- {
27
- public function worldAction()
28
- {
29
- $this->setResponse(array(
30
- 'message' =>'Hello, World!'
31
- ));
32
- }
33
- }
34
- ```
30
+ Now this would be 4 name-spaced classes, like this
35
31
36
- See the examples folder for a working demo.
32
+ - ` Basket\FetchDetail `
33
+ - ` Basket\Add `
34
+ - ` Basket\Remove `
35
+ - ` Basket\Empty `
37
36
38
- ## Getting Started ##
37
+ This allows for
38
+ - Greater code modularity
39
+ - Smaller classes
40
+ - Much easier Dependency Injection via ` __construct() ` as each "action" is it's own class.
39
41
40
- ### Install with Composer ###
42
+ You can still share common code via extension/composition - whatever takes your fancy!
41
43
42
- Here's the require line for Composer users.. .
44
+ JAPI will call the ` dispatch() ` method on your controller .
43
45
44
- ` "docnet/php-japi": "v1.1.1" `
46
+ ### SOLID Routing ###
45
47
46
- ...or just download and use the src folder.
48
+ The bundled router will accept any depth of controller namespace, like this
47
49
48
- ### Entry Point (index.php) ###
50
+ - ` /one ` => ` One `
51
+ - ` /one/two ` => ` One\Two `
52
+ - ` /one/two/three ` => ` One\Two\Three `
49
53
50
- Assuming:
51
-
52
- - You've got Apache/whatever set up to route all requests to this file
53
- - An auto-loader is present (like the Composer example here) or you've included all files necessary
54
- - Your controllers are not name spaced and you're happy with our default configuration
55
-
56
- then something like this is all the code you need
54
+ When you construct the Router, you can give it a "root" namespace, like this:
57
55
58
56
``` php
59
- <?php
60
- require_once('vendor/autoload.php');
61
- $api = new \Docnet\JAPI();
62
- $api->run();
57
+ $router = new \Docnet\JAPI\SolidRouter('\\Docnet\\App\\Controller\\');
63
58
```
64
59
65
- See the examples folder for a working demo (api.php).
66
-
67
- ## Routing ##
68
-
69
- The standard routing is quite strict, and (at the time ot writing) expects a controller + action pair for all requests.
70
-
71
- e.g. ` api.example.com/hello/world `
72
-
73
- URLs without a 2-part controller + action pair will result in a 404, such as
60
+ Which results in this routing:
74
61
75
- - ` api.example.com `
76
- - ` api.example.com/ `
77
- - ` api.example.com/controller `
78
-
79
- We do conversion to ` StudlyCaps ` classes and ` camelCase ` methods, splitting on hyphens and suffix 'Action' for the
80
- method. e.g.
81
-
82
- - ` api.example.com/hello/world ` becomes ` Hello::worldAction() `
83
- - ` api.example.com/hello-world/long-name ` becomes ` HelloWorld::longNameAction() `
84
-
85
- I seem to recall this is similar to ZF1.
62
+ - ` /one/two ` => ` \Docnet\App\Controller\One\Two `
86
63
87
64
### Static Routes ###
88
65
@@ -92,39 +69,51 @@ and so make calls very slightly faster.
92
69
Add a single custom route
93
70
94
71
``` php
95
- <?php
96
- $api = new \Docnet\JAPI();
97
- $api->getRouter()->addRoute('/goodbye', 'Hello', 'worldAction');
98
- $api->run();
72
+ $router = new \Docnet\JAPI\SolidRouter();
73
+ $router->addRoute('/hello', '\\Some\\Controller');
99
74
```
100
75
101
76
Or set a load of them
102
77
103
78
``` php
104
- <?php
105
- $api = new \Docnet\JAPI();
106
- $api->getRouter()->setRoutes(array(
107
- '/goodbye' => array('Hello', 'worldAction'),
108
- '/testing' => array('SomeController', 'testAction'),
109
- ));
110
- $api->run();
79
+ $router = new \Docnet\JAPI\SolidRouter();
80
+ $router->setRoutes([
81
+ '/hello' => '\\Some\\Controller',
82
+ '/world' => '\\Other\\Controller'
83
+ ]);
111
84
```
112
85
113
- ### Custom Router ###
86
+ ## Installation ##
87
+
88
+ Here's the require line for Composer users (during 2-series development)...
114
89
115
- If you want to write your own Router class? no problem!
90
+ ` "docnet/php-japi": "2.0.*@dev" `
116
91
117
- Perhaps you want to route based on HTTP request methods (GET/POST/PUT/DELETE).
92
+ ...or just download and use the src folder.
93
+
94
+ ## Bootstrapping ##
118
95
119
- There's a Router interface and you can follow and you can change the router through the JAPI object like this:
96
+ Assuming...
97
+
98
+ - You've got Apache/whatever set up to route all requests to this file
99
+ - An auto-loader is present (like the Composer example here) or you've included all files necessary
100
+
101
+ ...then something like this is all the code you need in your ` index.php `
120
102
121
103
``` php
122
- <?php
123
- $api = new \Docnet\JAPI();
124
- $api->setRouter(new MyAwesomeRouter());
125
- $api->run();
104
+ (new \Docnet\JAPI())->bootstrap(function(){
105
+
106
+ $obj_router = new \Docnet\JAPI\SolidRouter();
107
+ $obj_router->route();
108
+
109
+ $str_controller = $obj_router->getController();
110
+ return new $str_controller();
111
+
112
+ });
126
113
```
127
114
115
+ See the examples folder for a working demo (api.php).
116
+
128
117
## Coding Standards ##
129
118
130
- Desired adherence to [ PSR-2] ( https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md ) .
119
+ Desired adherence to [ PSR-2] ( https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md ) . Uses [ PSR-3 ] ( https://github.com/php-fig/log ) logging.
0 commit comments