├── .gitignore ├── .travis.yml ├── CHANGES.md ├── LICENSE.txt ├── README.md ├── composer.json ├── demo ├── HelloWorldController.php └── index.php ├── phpci.yml ├── phpcs.xml ├── phpdoc.dist.xml ├── phpdox.xml ├── phpmd.xml ├── phpunit.xml.dist ├── src ├── Api.php ├── Controller.php ├── ControllerDocumentation.php ├── ControllerReflector.php ├── Documentation.php ├── Exception.php ├── Injector │ ├── ControllerReflectorInjector.php │ ├── LoggerInjector.php │ ├── RequestInjector.php │ ├── ResponseInjector.php │ ├── RouterInjector.php │ ├── StatusInjector.php │ └── WriterFactoryInjector.php ├── ReflectionController.php ├── Request.php ├── Response.php ├── Router.php └── Status.php └── tests ├── ApiTest.php ├── ControllerDocumentationTest.php ├── ControllerReflectorTest.php ├── ControllerTest.php ├── DocumentationTest.php ├── ExceptionTest.php ├── Injector ├── ControllerReflectorInjectorTest.php ├── InjectorTestTrait.php ├── LoggerInjectorTest.php ├── RequestInjectorTest.php ├── ResponseInjectorTest.php ├── RouterInjectorTest.php ├── StatusInjectorTest.php └── WriterFactorInjectorTest.php ├── ReflectionControllerTest.php ├── RequestTest.php ├── ResponseTest.php ├── RouterTest.php ├── StatusTest.php └── TestCase.php /.gitignore: -------------------------------------------------------------------------------- 1 | composer.lock 2 | composer.phar 3 | /vendor 4 | /bin 5 | phpunit.xml 6 | build/cache.properties 7 | /reports 8 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | php: 3 | - 5.5 4 | - 5.6 5 | - 7.0 6 | - hhvm 7 | - nightly 8 | 9 | matrix: 10 | fast_finish: true 11 | allow_failures: 12 | - php: hhvm 13 | - php: nightly 14 | 15 | sudo: false 16 | 17 | before_script: 18 | - travis_retry composer self-update 19 | - travis_retry composer install 20 | 21 | script: 22 | - composer test 23 | 24 | notifications: 25 | slack: danielmason:mwiobPacEYneLE6a9iBAZvVB 26 | -------------------------------------------------------------------------------- /CHANGES.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | ## [Unreleased] 4 | 5 | ## [1.0.0] - 2016-02-17 6 | ### Changed 7 | - Now uses Formatters 1.0.0 8 | - My email is now listed as @ayeayeapi.com. Hopefully this will keep important Aye Aye related stuff out of the noise 9 | of my older inbox. 10 | - New license will be MIT 11 | - Updated badges in README 12 | 13 | ### Removed 14 | - References to old tests had been left in composer.json 15 | - Build folder contained scripts for building in Jenkins. This has all been moved to composer.json scripts 16 | 17 | ## [1.0.0-rc.2] - 2016-02-17 18 | ### Added 19 | - Added this file 20 | - Tests now lint first 21 | - Report script creates detailed artifacts for PHPCS, PHPLOC, PDEPEND, PHPCPD 22 | - Injector traits to help with DI while keeping things simple. 23 | - ReflectionController and ControllerReflector used to simplify Router and provide DI. 24 | - Reader Factory now decodes Request bodies 25 | 26 | ### Changed 27 | - Higher quality PHP DocBlocks for all classes and methods 28 | - Tests no longer use TestData 29 | - Response body is now returned as an array instead of object 30 | 31 | ### Removed 32 | - `->getData()` in Response was unnecessary, use `->getBody()` instead. 33 | - `->setStatusCode()` in Controller and Response breaks DI and was unnecessary, use `->setStatus()` instead. 34 | - Router and LoggerInterface are no longer part of the API constructor. Use the setters provided by the injectors 35 | instead. 36 | 37 | ## 1.0.0-rc.1 - 2015-09-02 38 | ### Added 39 | - 1.0.0 release candidate 40 | 41 | [Unreleased]: https://github.com/AyeAyeApi/Api/compare/1.0.0...HEAD 42 | [1.0.0]: https://github.com/AyeAyeApi/Api/compare/1.0.0-rc.2...1.0.0 43 | [1.0.0-rc.2]: https://github.com/AyeAyeApi/Api/compare/1.0.0-rc.1...1.0.0-rc.2 44 | 45 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Daniel Mason 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 6 | documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 7 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit 8 | persons to whom the Software is furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the 11 | Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 14 | WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 15 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 16 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Aye Aye API 2 | 3 | [![PHP >= 5.5](https://img.shields.io/badge/php-%3E%3D%205.5-8892BF.svg)] 4 | (https://php.net/) 5 | [![License: MIT](https://img.shields.io/packagist/l/ayeaye/api.svg)] 6 | (https://raw.githubusercontent.com/AyeAyeApi/Api/master/LICENSE.txt) 7 | [![Version](https://img.shields.io/packagist/v/ayeaye/api.svg)] 8 | (https://packagist.org/packages/ayeaye/api) 9 | [![Build Status](https://img.shields.io/travis/AyeAyeApi/Api/master.svg)] 10 | (https://travis-ci.org/AyeAyeApi/Api/branches) 11 | 12 | Aye Aye API is a micro framework for building API's written in PHP. It's designed to be easy to use, fast to 13 | develop with and to scale from tiny micro-services to world devouring titans. 14 | 15 | ## Installation 16 | 17 | Create a project and include Aye Aye. 18 | 19 | ```bash 20 | composer init --require="ayeaye/api ^1.0.0" -n 21 | composer install 22 | ``` 23 | 24 | ## Quick Start Guide 25 | 26 | When working with Aye Aye, you will do almost all of your work in Controller classes. 27 | 28 | Here's our ubiquitous Hello World controller: 29 | 30 | ```php 31 | go()->respond(); 71 | ``` 72 | 73 | First we grab composer's autoloader, and our controller (which we haven't added to the autoloader). We instantiate our 74 | HelloWorldController, and pass it into the constructor of our Api object. This becomes our initialController, and it's 75 | the only one Aye Aye needs to know about, we'll come onto why later. 76 | 77 | Finally the `->go()` method produces a Response object, with which we can `->respond()`. 78 | 79 | We can test this using PHP's build in server: 80 | 81 | ```bash 82 | $ php -S localhost:8000 index.php & 83 | 84 | $ curl localhost:8000/aye-aye # {"data":"Aye Aye Captain"} 85 | $ curl localhost:8000/aye-aye?name=Sandwiches # {"data":"Aye Aye Sandwiches"} 86 | ``` 87 | 88 | Notice how the string has been converted into a serialised object (JSON by default but the format can be selected with 89 | an `Accept` header or a file suffix). 90 | 91 | That tests our endpoint, but what happens if you just query the root of the Api. 92 | 93 | ```bash 94 | $ curl localhost:8000 # {"data":{"controllers":[],"endpoints":{"get":{"aye-aye":{"summary":"Yo ho ho","parameters":{"name":{"type":"string","description":"Optional, defaults to 'Captain'"}},"returnType":["string"]}}}}} 95 | ``` 96 | 97 | Lets take take a closer look at that returned string. 98 | 99 | ```json 100 | { 101 | "data": { 102 | "controllers": [], 103 | "endpoints": { 104 | "get": { 105 | "aye-aye": { 106 | "summary": "Yo ho ho", 107 | "parameters": { 108 | "name": { 109 | "type": "string", 110 | "description": "Optional, defaults to 'Captain'" 111 | } 112 | }, 113 | "returnType": [ 114 | "string" 115 | ] 116 | } 117 | } 118 | } 119 | } 120 | } 121 | ``` 122 | As you can see, it is an explanation of how our controller is structured. We didn't write anything more than what was 123 | expected of us, and it makes sense to both the back end developers, and the consumers of your Api. 124 | 125 | Don't forget to close the server down when you're done. 126 | 127 | ```bash 128 | $ fg 129 | ^C 130 | ``` 131 | 132 | ## Why should you use it? 133 | 134 | Developing in Aye Aye is simple, clean and logical. Aye Aye processes requests and gives them to the appropriate 135 | endpoint on the appropriate controller. That endpoint is simply a method, that takes a set of parameters and returns 136 | some data. Aye Aye will work out where to find those parameters in the request, and it will format the data on return. 137 | It even supports multiple data formats and will automatically switch based on what the user requests. 138 | 139 | There's no fluff. You don't need to learn new database tools, or logging interfaces (assuming you know [PSR-3] 140 | (https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md), and you should) or 141 | authentication methods. Aye Aye only provides routing, request parsing and response handling. You can use whatever 142 | you like for the rest. 143 | 144 | If you follow [PSR-4](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader.md), then 145 | your API will look a lot like your directory structure, making maintenance a breeze. 146 | 147 | Aye Aye knows about itself. It knows what endpoints and what sub-controllers are available on any given controller, and 148 | by reading the documentation in the doc-block comments, it can tell users what those end points do. You only need to 149 | write your documentation once, and Aye Aye will read it and tell your users what those end points do, and what 150 | parameters they take. 151 | 152 | By default it can read and write data as json (the default) and xml, though more formats can easily be added. It also 153 | reads GET, POST and HEADER, and parametrises url slugs. Data from these sources is passed into your methods for you. 154 | 155 | ## Quick Start explained 156 | 157 | The most important and powerful feature of Aye Aye is it's controllers. Controllers do two things. They provide 158 | endpoints, and access to other controllers. 159 | 160 | Controllers are classes that extend `AyeAye\Api\Controller` 161 | 162 | Endpoints are methods on the controllers that are named in this way `[verb][name]Endpoint(...)` 163 | 164 | - The `[verb]` is the http verb, the endpoint is waiting for. 165 | - The `[name]` is the name of the endpoint. 166 | - `Endpoint` is literally the word "Endpoint". It helps us know what we're dealing with. 167 | 168 | You can define any parameters you like for the method, and Aye Aye will automatically populate them for you. 169 | 170 | Controllers can also reference other controllers with methods named like this `[name]Controller()` 171 | 172 | These should return a controller object, and it's how Aye Aye navigates the Api. 173 | 174 | ### The hello world controller 175 | 176 | Above we wrote a controller to say hello. 177 | 178 | ```php 179 | logArray($context); 16 | } 17 | 18 | public function logArray($array, $indent = ' ') 19 | { 20 | foreach($array as $key => $value) { 21 | if(!is_scalar($value)) { 22 | echo $indent.$key.':'.PHP_EOL; 23 | $this->logArray($value, $indent.' '); 24 | continue; 25 | } 26 | echo $indent.$key.': '.$value; 27 | } 28 | } 29 | } 30 | 31 | $initialController = new HelloWorldController(); 32 | $api = new Api($initialController); 33 | $api->setLogger(new EchoLogger); 34 | 35 | $api->go()->respond(); 36 | 37 | -------------------------------------------------------------------------------- /phpci.yml: -------------------------------------------------------------------------------- 1 | setup: 2 | composer: 3 | action: "install" 4 | 5 | test: 6 | php_unit: 7 | coverage: "reports/html" 8 | php_loc: 9 | directory: "src" 10 | php_mess_detector: 11 | path: "src" 12 | rules: 13 | - "codesize" 14 | - "design" 15 | - "cleancode" 16 | - "naming" 17 | - "unusedcode" 18 | allow_failures: true 19 | zero_config: true 20 | -------------------------------------------------------------------------------- /phpcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Used for maintaining standards in Aye Aye Api 4 | 5 | ./src 6 | ./tests 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /phpdoc.dist.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | reports/documentation 5 | utf8 6 | 7 | TODO 8 | FIXME 9 | 10 | 11 | 12 | reports/documentation 13 | 14 | 15 |