Skip to content

Commit

Permalink
refactoring and @exception annotation
Browse files Browse the repository at this point in the history
  • Loading branch information
johannesschobel committed Jan 31, 2017
1 parent a4ad372 commit 8d74f7d
Show file tree
Hide file tree
Showing 9 changed files with 264 additions and 48 deletions.
6 changes: 4 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
146 changes: 144 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -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"
```
```

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.
25 changes: 25 additions & 0 deletions src/JohannesSchobel/DingoDocs/Models/Annotations/Exception.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

namespace JohannesSchobel\DingoDocs\Models\Annotations;

/**
* Class Exception
* @package JohannesSchobel\DingoDocs\Models\Annotations
* @Annotation
*/
class Exception
{
/**
* The HTTP status code of the exception
*
* @var string
*/
public $value = 500;

/**
* The description of the exception
*
* @var string
*/
public $description = '';
}
22 changes: 22 additions & 0 deletions src/JohannesSchobel/DingoDocs/Models/Annotations/Exceptions.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

namespace JohannesSchobel\DingoDocs\Models\Annotations;

/**
* Class Exceptions
* @package JohannesSchobel\DingoDocs\Models\Annotations
* @Annotation
*/
class Exceptions
{
/**
* A List of all Exceptions
*
* @var array<\JohannesSchobel\DingoDocs\Models\Annotations\Exception>
*/
public $value = [];

public function getExceptions() {
return $this->value;
}
}
16 changes: 16 additions & 0 deletions src/JohannesSchobel/DingoDocs/Models/Endpoint.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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');
Expand Down
23 changes: 23 additions & 0 deletions src/resources/views/partials/main/exception.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<div class="panel panel-danger">
<div class="panel-heading">
<h3 class="panel-title">Exceptions</h3>
</div>

<div class="panel-body">
This route may throw the following Exceptions.
</div>

<table class="table table-striped table-condensed">
<thead>
<tr>
<th width="10%">HTTP Status</th>
<th width="90%">Description</th>
</tr>
</thead>
<tbody>
@foreach($route->getExceptions()->getExceptions() as $exception)
@include('dingodocs::partials.main.exception_line', compact($exception))
@endforeach
</tbody>
</table>
</div>
4 changes: 4 additions & 0 deletions src/resources/views/partials/main/exception_line.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<tr>
<td><code>{!! $exception->value !!}</code></td>
<td>{!! $exception->description !!}</td>
</tr>
68 changes: 25 additions & 43 deletions src/resources/views/partials/main/route.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,40 +2,32 @@
<div class="row">
<div class="col-md-9">
<div>
<h2 id="{!! $route->getID() !!}" class="text-info">{!! $route->getShortDescription() !!}</h2>
<h3 id="{!! $route->getID() !!}" class="text-info">{!! $route->getShortDescription() !!}</h3>
<hr />
<h3>{!! $route->getLongDescription() !!}</h3>
<h4>{!! $route->getLongDescription() !!}</h4>

<div class="row">
<div class="col-md-7">
<div class="col-md-8">
@if($route->getAuthentication() != null)
@include('dingodocs::partials.main.authentication', compact($route))
@endif
</div>
<div class="col-md-5">
<div class="col-md-4">
@if($route->getRole() != false)
@include('dingodocs::partials.main.role', compact($route))
@endif
</div>
</div>



<div class="row">
<div class="col-md-6">
<div class="row">
<div class="col-md-12">
@include('dingodocs::partials.main.method', compact($route))
</div>
</div>
<div class="col-md-8">
@include('dingodocs::partials.main.method', compact($route))
</div>

<div class="row">
<div class="col-md-12">
@if( $route->getTransformer() != null )
@include('dingodocs::partials.main.transformer', compact($route))
@endif
</div>
</div>
<div class="col-md-4">
@if( $route->getTransformer() != null )
@include('dingodocs::partials.main.transformer', compact($route))
@endif
</div>
</div>

Expand All @@ -46,15 +38,15 @@
@endif

<div class="row">
<div class="col-md-6">
@if($route->getQueryParameters() != null)
@include('dingodocs::partials.main.queryparameter', compact($route))
<div class="col-md-8">
@if(! empty($route->getValidator()))
@include('dingodocs::partials.main.validator', compact($route))
@endif
</div>

<div class="col-md-6">
@if(! empty($route->getValidator()))
@include('dingodocs::partials.main.validator', compact($route))
<div class="col-md-4">
@if($route->getQueryParameters() != null)
@include('dingodocs::partials.main.queryparameter', compact($route))
@endif
</div>
</div>
Expand All @@ -65,27 +57,17 @@
</div>
@endif

<div class="row">
<div class="col-md-8">
@if(! empty($route->getExceptions()))
@include('dingodocs::partials.main.exception', compact($route))
@endif
</div>

</div>
</div>

<div class="col-md-3">
@if(! empty(""))
<div class="well well-sm">
<h4>HTTP Status Codes</h4>
<table class="table table-striped table-condensed">
<thead>
<tr>
<th width="20%">Code</th>
<th width="80%">Description</th>
</tr>
</thead>
<tbody>
</div>

</tbody>
</table>
</div>
@endif
</div>

</div>
</section>
2 changes: 1 addition & 1 deletion src/resources/views/partials/main/transformer.blade.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
@if( count($route->getTransformer()->getTransformer()->getAvailableIncludes()) > 0 )
<div class="panel panel-info">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Transformer includes</h3>
</div>
Expand Down

0 comments on commit 8d74f7d

Please sign in to comment.