From 8d74f7d867f54afdb9ad7c5ef7b3962af41e048d Mon Sep 17 00:00:00 2001 From: Johannes Schobel Date: Tue, 31 Jan 2017 16:02:31 +0100 Subject: [PATCH] refactoring and @Exception annotation --- CHANGELOG.md | 6 +- README.md | 146 +++++++++++++++++- .../Models/Annotations/Exception.php | 25 +++ .../Models/Annotations/Exceptions.php | 22 +++ .../DingoDocs/Models/Endpoint.php | 16 ++ .../views/partials/main/exception.blade.php | 23 +++ .../partials/main/exception_line.blade.php | 4 + .../views/partials/main/route.blade.php | 68 +++----- .../views/partials/main/transformer.blade.php | 2 +- 9 files changed, 264 insertions(+), 48 deletions(-) create mode 100644 src/JohannesSchobel/DingoDocs/Models/Annotations/Exception.php create mode 100644 src/JohannesSchobel/DingoDocs/Models/Annotations/Exceptions.php create mode 100644 src/resources/views/partials/main/exception.blade.php create mode 100644 src/resources/views/partials/main/exception_line.blade.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 1739d43..c4502c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,8 +2,10 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). -## 2016-08-24 -##### Initial Commit +##### 2017-01-30 +- Docs +- Added the @Exceptions (and @Exception) Annotation +##### 2016-08-24 (Initial Commit) - @Group - @Transient - @Authentication diff --git a/README.md b/README.md index c8be274..48a5aa2 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,148 @@ # dingodocs -Automatically generate an API documentation for your Laravel Dingo/API application +Automatically generate an API documentation for your Laravel Dingo/API application. + +## Installation +Install the package via Composer: +``` bash +$ composer require johannesschobel/dingodocs +``` + +Then publish the `config` file using the following command: ``` bash php artisan vendor:publish --provider="JohannesSchobel\DingoDocs\DingoDocsServiceProvider" --tag="config" -``` \ No newline at end of file +``` + +If you want to customize the output of your API Doc file, you may want to publish the `resource` files as well: +``` bash +php artisan vendor:publish --provider="JohannesSchobel\DingoDocs\DingoDocsServiceProvider" --tag="resources" +``` +## Getting Started +The package tries to enable developers to automatically generate an API doc file without burdening the developers to +much. For example, the package tries to read required information from annotations or even from parameters of the +method to be called. + +### Available Annotations +Currently, the package provides features for the following Annotations: + +#### Name +A name for the given Endpoint of your API. + +#### Description +A description (long text) for the Endpoint of your API. + +#### HTTP METHOD +Respective HTTP Method (`GET`, `POST`, ...) to call the Endpoint. + +#### Authentication +If you need to be authenticated in order to call the Endpoint. + +#### Group +A name to group Endpoints together (e.g., used within the navigation bar to the left of the generated file). + +#### Role +The Role a requestor needs to have in order to call the Endpoint. + +#### Exceptions +The Exceptions an Endpoint may throw including HTTP Status and further descriptions. + +#### Request +A sample request to call the Endpoint. + +#### Response +A sample Response to be returned from the Endpoint. + +#### Transformer +The Transformer (as well as its includes) which are provided by this Endpoint. + +#### Transient +Indicates, whether this Endpoint is listed in the resulting API Doc. + +## Commands +Simply call +```bash +php artisan dingodocs:generate +``` +to generate the API doc. The generated file is then stored within the `public` folder of your application. + +## Example +Consider the following example, which illustrates how to use this package: + +```php +// namespace and lots of use statements here + +/** + * Class FaqController + * @package App\Http\Controllers + * + * @Group("Faqs") + * @Authentication + * @Role("Group") + */ +class FaqController extends ApiBaseController +{ + /** + * Get all Faqs + * + * Returns all Faqs. + * + * @param Request $request + * @return Response the result + * + * @Authentication("false") + * @Transformer("\App\Transformers\FaqTransformer") + */ + public function index(Request $request) { + $faqs = Faq::all(); + + return $this->response->collection($faqs, new FaqTransformer()); + } + + /** + * Get one Faq + * + * Returns one Faq entry. + * + * @param Faq $faq to be displayed + * @return Response the result + * + * @Transformer("\App\Transformers\FaqTransformer") + * @Exceptions({ + * @Exception("403", description="If the user is not logged in."), + * @Exception("400", description="If some other things happen."), + * }) + */ + public function show(Faq $faq) { + $user = authenticate(); // imagine, that this method will return a USER object or null! + if(is_null($user)) { + // do a fancy exception handling here! + } + + // do another exception handling here.. + + return $this->response->item($faq, new FaqTransformer()); + } + + /** + * Store a new Faq + * + * Add a new Faq entry to the database. + * + * @param Request $request the request to be stored to the database + * @return Response the result + */ + public function store(FaqRequest $request) { + $faq = new Faq(); + $faq->name = $request->input('name'); + $faq->save(); + + return $this->response->created(); + } +} +``` + +As one can see, some annotations may be placed at `Class`-level, while others may be placed at `Method`-level. However, +method-annotations overwrite class-annotations (cf. the `@Authentication` annotation in the example). + +Note that the package will try to resolve the `FaqRequest` parameter from the `store` method. Furthermore, all +validation rules (e.g., `name => required|string|max:255`) are parsed and automatically appended to the docs. \ No newline at end of file diff --git a/src/JohannesSchobel/DingoDocs/Models/Annotations/Exception.php b/src/JohannesSchobel/DingoDocs/Models/Annotations/Exception.php new file mode 100644 index 0000000..e564191 --- /dev/null +++ b/src/JohannesSchobel/DingoDocs/Models/Annotations/Exception.php @@ -0,0 +1,25 @@ + + */ + public $value = []; + + public function getExceptions() { + return $this->value; + } +} \ No newline at end of file diff --git a/src/JohannesSchobel/DingoDocs/Models/Endpoint.php b/src/JohannesSchobel/DingoDocs/Models/Endpoint.php index 3a853a1..d0fdc4a 100644 --- a/src/JohannesSchobel/DingoDocs/Models/Endpoint.php +++ b/src/JohannesSchobel/DingoDocs/Models/Endpoint.php @@ -9,6 +9,7 @@ use Illuminate\Support\Facades\Validator; use Illuminate\Support\Str; use JohannesSchobel\DingoDocs\Models\Annotations\Authentication; +use JohannesSchobel\DingoDocs\Models\Annotations\Exception; use JohannesSchobel\DingoDocs\Models\Annotations\Transformer; use JohannesSchobel\DingoDocs\Models\Annotations\Transient; use JohannesSchobel\DingoDocs\Parsers\RuleDescriptionParser; @@ -211,6 +212,21 @@ public function getValidator() return config('dingodocs.defaults.transformer'); } + /** + * Get the Exceptions for the route + * + * @return Exception | null + */ + public function getExceptions() { + $annotation = $this->findMethodAnnotationByType('Exceptions'); + if(isset($annotation)) { + return $annotation; + } + + dingodocs_msg('I', $this->route, 'does not provide information for their Exceptions!'); + return null; + } + public function getQueryParameters() { $annotation = $this->findMethodAnnotationByType('QueryParameters'); diff --git a/src/resources/views/partials/main/exception.blade.php b/src/resources/views/partials/main/exception.blade.php new file mode 100644 index 0000000..8b6f249 --- /dev/null +++ b/src/resources/views/partials/main/exception.blade.php @@ -0,0 +1,23 @@ +
+
+

Exceptions

+
+ +
+ This route may throw the following Exceptions. +
+ + + + + + + + + + @foreach($route->getExceptions()->getExceptions() as $exception) + @include('dingodocs::partials.main.exception_line', compact($exception)) + @endforeach + +
HTTP StatusDescription
+
\ No newline at end of file diff --git a/src/resources/views/partials/main/exception_line.blade.php b/src/resources/views/partials/main/exception_line.blade.php new file mode 100644 index 0000000..4c65baa --- /dev/null +++ b/src/resources/views/partials/main/exception_line.blade.php @@ -0,0 +1,4 @@ + + {!! $exception->value !!} + {!! $exception->description !!} + \ No newline at end of file diff --git a/src/resources/views/partials/main/route.blade.php b/src/resources/views/partials/main/route.blade.php index c2fee5d..0e1e17e 100644 --- a/src/resources/views/partials/main/route.blade.php +++ b/src/resources/views/partials/main/route.blade.php @@ -2,40 +2,32 @@
-

{!! $route->getShortDescription() !!}

+

{!! $route->getShortDescription() !!}


-

{!! $route->getLongDescription() !!}

+

{!! $route->getLongDescription() !!}

-
+
@if($route->getAuthentication() != null) @include('dingodocs::partials.main.authentication', compact($route)) @endif
-
+
@if($route->getRole() != false) @include('dingodocs::partials.main.role', compact($route)) @endif
- -
-
-
-
- @include('dingodocs::partials.main.method', compact($route)) -
-
+
+ @include('dingodocs::partials.main.method', compact($route)) +
-
-
- @if( $route->getTransformer() != null ) - @include('dingodocs::partials.main.transformer', compact($route)) - @endif -
-
+
+ @if( $route->getTransformer() != null ) + @include('dingodocs::partials.main.transformer', compact($route)) + @endif
@@ -46,15 +38,15 @@ @endif
-
- @if($route->getQueryParameters() != null) - @include('dingodocs::partials.main.queryparameter', compact($route)) +
+ @if(! empty($route->getValidator())) + @include('dingodocs::partials.main.validator', compact($route)) @endif
-
- @if(! empty($route->getValidator())) - @include('dingodocs::partials.main.validator', compact($route)) +
+ @if($route->getQueryParameters() != null) + @include('dingodocs::partials.main.queryparameter', compact($route)) @endif
@@ -65,27 +57,17 @@
@endif +
+
+ @if(! empty($route->getExceptions())) + @include('dingodocs::partials.main.exception', compact($route)) + @endif +
-
-
- -
- @if(! empty("")) -
-

HTTP Status Codes

- - - - - - - - + - -
CodeDescription
- @endif
+
diff --git a/src/resources/views/partials/main/transformer.blade.php b/src/resources/views/partials/main/transformer.blade.php index dff1e86..9e1d75a 100644 --- a/src/resources/views/partials/main/transformer.blade.php +++ b/src/resources/views/partials/main/transformer.blade.php @@ -1,5 +1,5 @@ @if( count($route->getTransformer()->getTransformer()->getAvailableIncludes()) > 0 ) -
+

Transformer includes