zircote / swagger-php Goto Github PK
View Code? Open in Web Editor NEWA php swagger annotation and parsing library
Home Page: http://zircote.github.io/swagger-php/
License: Apache License 2.0
A php swagger annotation and parsing library
Home Page: http://zircote.github.io/swagger-php/
License: Apache License 2.0
If I run phar file without -e option (which shouldn't be mandatory), I get
PHP Notice: Undefined variable: excludePath in phar:///swagger.phar/bin/swagger on line 114
Swagger says in its wiki complex datatypes can/must have the fields
But when I use the line
@SWG\Property(name="number",type="int",required=true,description="Some reason the number field exists")
the annotations parser throws the following message:
[INFO] Skipping unsupported property: "required" for @Swagger\Annotations\Property, expecting "name", "type", "description", "allowableValues", "items" in ModelClass->number in /some/path/to/ModelClass.php on line 18
Could you change this behaviour? In my eyes, this is a bug.
Hello, I'm running into another issue implementing swagger-php in a Codeiginiter build (although I believe this issue appear in other php frameworks as well.)
Here are the basics, I have a number of controllers, each of which is a class, ie: class Users extends MY_Controller
. Controllers might contain methods that map to different endpoints. The endpoints are defined in a routes file. This creates the need to declare multiple resources in the same class... however this causes unexpected results - they often overwrite each other - the last one taking precedence. Furthermore, the same resource might have functions in different controllers, but adding the same resource declaration to multiple classes again casuses un-expected results.
Here is some example code:
/**
* @Resource(
* apiVersion="1",
* swaggerVersion="1.1",
* resourcePath="/users", // also contains resourcePaths for /posts
* basePath="http://localhost:8888/myapp/"
* )
*/
class Posts extends MY_Controller {
// @api path="/poasts"
function list_all() { }
// @api path="/users/{user_id}/posts"
function list_by_user($user_id) { }
// @api path="/posts/{post_id}"
function show($post_id) { }
// @api path="/posts/create"
function create() {}
}
/**
* @Resource(
* apiVersion="1",
* swaggerVersion="1.1",
* resourcePath="/users", // second class declared with resourcePath = 'users'
* basePath="http://localhost:8888/myapp/"
* )
*/
class Users extends MY_Controller {
function create() { }
}
$routes['posts'] = 'posts/list_all';
$routes['posts/(:num)'] = 'posts/show/$1';
$routes['users/(:num)/posts'] = 'posts/list_all/$1';
$routes['signup] = 'users/create';
// note above that @resourcePath posts/1 and users/123/posts
// both share the same class
Any thoughts. Is it possible to support a setup like this?
I was thinking of a few possible solutions:
Then, swagger-php would build apis for each resource by either:
From my experience this would solve the issue, although I'm not sure it's the best approach. Any thoughts?
Thanks for your hard work on swagger-php!
Hello, I'm trying to use swagger-php with Codeigniter. Codeigniter doesn't take advantage of php namespace, use, etc. methods. Thus swagger-php does not cooperate well.
I've successfully got things installed, and running to the point where I get errors that the annotation "@Api" in class Demo\Models\Demo was never imported
- along with lots of other exceptions that I believe are from not being able to namespace and use files properly.
Any suggestions?
Thanks,
-Matt
For example the documenation at: http://zircote.com/swagger-php/annotations.html
@swg\allowableValues, must be @swg\AllowableValues.
But the same goes for several other examples.
I'm currently working for a company that uses Symfony 2 for its API. They also use the JMSSerializerBundle to serialize the response, but to also support different views for an entity:
http://jmsyst.com/libs/serializer/master/cookbook/exclusion_strategies#creating-different-views-of-your-objects
Let me explain this better with the following example for Doctrine entities. A entity Car has a OneToMany association with the enity Part. With the API "/cars/1.json" I want to ->find() Car entity with ID one that also fetched al its childs like the Part entity. The Car entity can be put in the serializer and it will be returned. The controller for "/cars/1.json" will set the groups "Car" and "CarDetails". Because the Car entity has properties with @ser\Groups("Car") annotation and the Part entity has properties with the @ser\Groups("CarDetails") annotation, they will be returned both in the response.
But lets say we want to show a list of cars with the API call "/cars.json". Then we only want to display the car name and some other fields, but not all parts. So the controller action that handles that call with set only the group "Car" on the serializer, so only the entities and their properties that have this group will be returned.
At the moment the discoverer of swagger-php doesn't support this. It would be awesome if besides the responseClass attribute a responseGroups attribute could be added that can contain multiple values. A groups attribute could be added to a model property, to include this property of this model only if the API controller action has this Model ID as responseClass but also corresponding responseGroups.
Because models are reused in Swagger UI over mulitple APIs and we want to use the same model with different views, I'm not sure yet about how to implement this.
I hope you understand the issue and have some genius input on this :) Let me know what you think!
I think the correct data when I look at the pet store api-docs.json is per @swg\Resource one entry in the api-docs.json. Right now it adds ALL operations.
Another thing with the path:
@swg\Resource(apiVersion="1.0", swaggerVersion="1.1", resourcePath="/cars") would give:
cars.json in the output directory, which is okay. But the path in api-docs.json must be relative I think to the current directory of api-docs.json.
I have the following API:
http://company.com/api/cars.json
The resource files generated to the web/resources folder. So in Swagger UI I have the URL at the top of the page like:
http://company.com/resources/api-docs.json
The current situation calls the cars resource at http://company.com/api/cars.json, but that would be the actual API path and not the documentation. I would suspect a call to http://company.com/resources/cars.json. In other words, the current directory of api-docs.json.
I have a suggestion for a documentation improvement. It's the same style like Doctrine does with @Orm. If you put this at the top of PHP file "use Swagger\Annotations as SWG", than that's the only use statement you will ever need for all Swagger annotations in that file. This also avoids conflicts with other classes that might have a general name like "Operation".
Your annotations will look like:
@SWG\Api( path="/search/pets.{format}", description="Operations about pets", @SWG\Operations( @SWG\Operation(
Let me hear if you like it!
Swagger UI support HTML in the description since about a month which is great! I would very like to document a POST operation to explain what the posted object must look like. For example like below, but swagger-php can't parse this correctly:
* @SwaggerOperation(
* nickname="postContact",
* value="Creates a new contact",
* notes="Crates a new contact. Example:
* <pre>
* {
* "Id": 1,
* "Initials": "A.C.F.",
* "FirstName": "Anna",
* "Insertion": "",
* "LastName": "Foo",
* "DateOfBirth": "1940-01-19NET00:00:00"
* "Gender": "F"
* }
* </pre>",
* responseClass="Contact",
* multiValueResponse=false
* )
See http://php.net/manual/en/directoryiterator.getextension.php#refsect1-directoryiterator.getextension-notes for more information.
I would prefer removing the use of DirectoryIterator::getExtension
It is currently used in Swagger::getFiles
With the latest version resources.json is not created. I this by design or is this an issue?
I would like know if you will add "produces" and "consumes" to your lib ?
In https://github.com/zircote/swagger-php/blob/master/bin/swagger#L34 the word "vendor" is hardcoded. Composer allows for installation to directories other than "vendor" using the following syntax:
{
"require": {
"zircote/swagger-php": "master-dev",
"lncd/OAuth2": "*"
},
"require-dev": {
"phpunit/phpunit": "3.7.*",
"phpunit/php-invoker": "*"
},
"config": {
"vendor-dir": "Vendor"
}
}
(where "Vendor" could be any directory name). In CakePHP "Vendor" is the default folder, which in *nix is a different directory to "vendor". By removing the explicit call to "vendor/autoload.php" this issue would be removed.
I haven't found something like a discussion board for this library, so forgive me for creating this "issue"…
In a web service I am creating (and documenting with Swagger obviously) I have a number of classes (of the model type) that inherit from other base model classes.
This works perfectly for the actual REST api, but not so well for the documentation of it.
When I tell Swagger the return format for a particular call is one of the inheriting classes, only the annotated properties of that class are packed into the JSON, but not the even more important properties of the parent class.
One workaround I currently see is to put all the annotations of the parent class into the inheriting classes as well (only the annotations, not the properties). But I dislike this, it increases the amount of confusing comment lines and makes changes harder to integrate.
Is there any way swagger-php might be able to get to the annotations of the parent class and evaluate them as well before creating the JSON output?
Alternatively, do I lack some insight into the concept and there is a much better way to handle such situations?
Thanks in advance for any helpful statements.
The fixture located at tests/SwaggerTests/Fixtures2 does not work anymore if the Class Pet is abstract. The properties defined in the class Pet are not inserted into the model of Dog.
It looks like the parser does not recognize the doc comment belongs to a class declaration if the «abstract» keyword is in between those two.
Fixes side-effects caused by running arbitrary php code. (Like a travis-setup.php #67)
Prevents crashes when the superclass isn't loaded via an Autoloader
This works fine while in development - but reflection is an expensive thing to be doing across a codebase.
It'd be nice if there was something that provided a cached version of this, to save it having to reflect the whole codebase each time.
My observation right now without looking at any Swagger code is that the @var annotation of a property is taken literally. So @var integer will display the "integer" in the model/entity information.
But the swagger spec has only these data types:
byte
boolean
int
long
float
double
string
Date
So mapping must be added:
PHP => Swagger
--------------------
bool => boolean
integer => int
\DateTime => Date
Swagger-codegen is very picky about data types, so it's important that for example integer is exactly "int".
With the recent implementation of JSON_UNESCAPED_SLASHES and JSON_PRETTY_PRINT, the library cannot be used with PHP 5.3.
Could you add a check for the PHP version and only implement those options if greater than 5.4?
Thanks
David
While i played around a bit with swagger-php i asked myself how one would handle changing hosts for the api. on the one hand you have developers and their local installations, staging environments and finally the production environment - at least for my, they have different hostnames.
On the other hand, i'd like to see a global api-version which is used for all resources - to avoid this updating mess where at least one change got lost for whatever reason.
So the Idea would be, extending Swagger
s Constructor with a few arguments:
I first try to add those later on top, but because of the discoverServices()
call inside the Constructor it has to be this early. The Signature of Parser
has to change a bit, since it has to accept a Swagger
-Instance .. but i guess that is no big deal.
Let me know what you think about this, i'd like to prepare another PR for that.
I've got a mighty big stack trace here. Interestingly, this only started happening today, all was well with generating docs on Friday. What can I do?
PHP Fatal error: Maximum function nesting level of '100' reached, aborting! in /var/www/web_platform/app/Vendor/zircote/swagger-php/library/Swagger/Swagger.php on line 690
PHP Stack trace:
PHP 1. {main}() /var/www/web_platform/app/Vendor/zircote/swagger-php/bin/swagger:0
PHP 2. Swagger\Swagger::discover($path = './', $excludePath = '/var/www/web_platform/app/Vendor') /var/www/web_platform/app/Vendor/zircote/swagger-php/bin/swagger:144
PHP 3. Swagger\Swagger->__construct($path = './', $excludePath = '/var/www/web_platform/app/Vendor', $cache = NULL) /var/www/web_platform/app/Vendor/zircote/swagger-php/library/Swagger/Swagger.php:256
PHP 4. Swagger\Swagger->discoverServices() /var/www/web_platform/app/Vendor/zircote/swagger-php/library/Swagger/Swagger.php:109
PHP 5. Swagger\Swagger->inheritProperties(...) /var/www/web_platform/app/Vendor/zircote/swagger-php/library/Swagger/Swagger.php:694
I have two API operations.
/cars.json (all cars)
As responseClass I have List[Car]. But it is defined in Swagger UI literally as List[Car].
/cars/5.json (car with ID 5)
When I added this operation with responseClass="Car", then the responseClass list of the previous operation was parsed as suspected.
So the model must first be found without a List context I think... which means a bug.
Currently the responseClass attribute is required for an operation. If you don't want to define a responseClass, than responseClass="void" is a workaround, but maybe it's even nicer to have it as optional attribute.
For a DELETE operation, even if you DO define a responseClass (what doesn't make any sense because of a 204 response code), than the same notice occurs.
It seems there is no sorting on the paths in the resources.json file at the moment. It would be much beter if this was sorted alphabetically to get a nicer view in Swagger UI.
Hello
I have "ressources.json" + "pet.json" generate with swigger-php. thank !
When i use swagger-ui, i have nothing.
Swagger-php generate ,"basePath":"http:\/\/127.0.0.1\/myapprest"
: swagger-ui example is ,"basePath":"http://127.0.0.1/myapprest"
.
Swagger-php generate ,"res":"/pet"
, but swigger-ui use ,"resourcePath":"/pet"
Swagger-php not write ,nickname=""
, but swigger-ui fail is missing ...
what version of swagger-ui use?
Ami44
See my comment in: 9bbd73a
I would like to describe a model outside its class defined file (Example : dynamic class response).
It means, I should be able to list model properties like following
/**
* @Model(
* id="PetResponse,
* @Properties(
* @Property(name="status",type="int"),
* @Property(name="statusLabel",type="string"),
* @Property(name="tags",type="array", items="$ref:Tag")
* )
* )
*/
I create a new Swagger\Annotations\Properties
file like Swagger\Annotations\Parameters
.
But I do not know how to implement the discoverClassAnnotations()
part to keep the normal Property
work in parallels of @Properties(Property)
.
I look for implement it, but I would like to have your feeling about it. Would you have some advices?
Can you provide some guidance for the following question? This is an issue of not understanding some of the methods in the package. Anything helps, thanks.
http://stackoverflow.com/questions/16159693/swagger-php-and-cakephp
Linked to #54
Currently, only the last declared Model is used.
Hello,
I appreciate this may be a problem with Doctrine instead of Swagger but whenever I try to run Swagger from the CLI I get the following error:
~/Github/swagger-example » php docs.php alexbilbie@macbook-pro
== extension: xcache ==
=> not installed, requires a PHP version < 5 (5.4.9 installed)
== extension: memcache ==
=> Command 'wget http://pecl.php.net/get/memcache-2.2.6.tgz > /dev/null 2>&1' failed !%
All docs.php contains at the moment is the following:
<?php
include 'vendor/autoload.php';
use \Doctrine\Common\Cache\PhpFileCache;
$path = '/Users/alexbilbie/Github/swagger-example';
$cacheDir = 'cache';
$swagger = new Swagger\Swagger($path, null, new PhpFileCache($cacheDir, '.cache'));
Do you have any ideas?
Thanks
When I annotate the following, the parameters are ignored.
* @SWG\Api(
* @SWG\operations(
* @SWG\Operation(
* @SWG\Parameters(
* @SWG\Parameter(
* ),
* @SWG\Parameter(
* )
* )
* )
* )
* )
I tracked the problem to this line:
https://github.com/zircote/swagger-php/blob/master/library/Swagger/Annotations/Operation.php#L101
Here, the $value
variable is an array, not an instance of Parameters.
I have two classes with the same @swg\Resource path. They both have operations with this path as the base. But one class has operations with deeper paths.
The are collected nicely into the same resource file, but they are not sorted alphabetically and shortest first.
At the moment I'm building a REST API in Zend Framework 2 with the PhlyRestfully module.
The response is in JSON+HAL. For example a list of resources is enclosed in the "_embedded" key.
http://phlyrestfully.readthedocs.org/en/latest/halprimer.html
I am trying the following command after installing Composer.
C:/>php swagger.phar --project-dir "E://nnn//orchard_WS//" --project-path "vectorapi_2" --output-path "E://nnn//orcha
rd_WS//vectorapi_2_output" --include-path "Zend:/usr/local/shar/pear,Rediska:/usr/local/share/pear"
An Error has occured:
DirectoryIterator::__construct(E:\nnn\zircote-swagger-php\E://nnn//orchard_WS//,E:\nnn\zircote-swagger-php\E://nnn//orchard_WS//): The filename, directory name, or volume label syntax is incorrect. (code: 123)
Swagger-UI now supports param type form - swagger-php should not produce a warning for the param type "form" any more.
I have an API that request an certain entity as request data. As response I return another entity/class. I want to let swagger-ui (1.1.4) display the properties of the request model. But currently this model will only become available in the models array in the json file if it's in some API defined as responseClass.
I think it would be better to scan the whole project and search for @SwaggerModel with maybe an extra annotation to define in which APIs it should be added to the JSON file.
Like to hear your ideas about this.
The status query parameter at http://petstore.swagger.wordnik.com/#!/pet/findPetsByStatus_get is an ENUM kind of field.
The JSON for that is:
{
"name": "status",
"description": "Status values that need to be considered for filter",
"paramType": "query",
"defaultValue": "available",
"allowableValues": {
"valueType": "LIST",
"values": [
"available",
"pending",
"sold"
]
},
"required": true,
"allowMultiple": true,
"dataType": "string"
}
But is it possible to define this with swagger-php annotations?
This phing based process should encompass the following:
swagger.phar
buildUsing the CLI version of Swagger (bin/swagger -p /path/to/api/v1/ -o /path/to/output), the generated JSON files are wrong.
The output for api-docs.json
{
"apiVersion": "0.2",
"swaggerVersion": "1.1",
"basePath": "path",
"apis": [
{
"path": "/resources/diary.{format}",
"description": "Operations about diary"
},
{
"path": "/resources/user.{format}",
"description": "Operations about user"
}
]
}
The 'resources' folder is added to every resource, while the binary Swagger file creates the api-docs.json and all of the resources in the same folder, as visible here:
https://github.com/zircote/swagger-php/blob/master/bin/swagger#L147-L154
The bug originates from: https://github.com/zircote/swagger-php/blob/master/library/Swagger/Swagger.php#L484-L518 where the path is hardcode prefixed with 'resources', but the binary file does not create a resource folder nor does it try to write the resource json files into a subfolder.
I have been using swagger-php along with swagger-ui for a few months now, but always had the models "hard-coded" as json files because of no pure class representation internally. I recently started working with model generation, but the properties seem to not match the spec. They may be fine in the php array in the swagger obj, but the json output has them as a numeric array of json objects. See below output, generated from the tests/SwaggerTests/Fixtures/Models/Pet.php file. This seems to happen with dev-master and 0.6.*@dev.
"Pet": {
"id": "Pet",
"description": null,
"extends": null,
"properties": [
{
"name": "tags",
"type": "Array",
"description": null,
"allowableValues": null,
"items": {
"type": "Tag"
}
},
{
"name": "id",
"type": "long",
"description": null,
"allowableValues": null,
"items": null
},
{
"name": "category",
"type": "Category",
"description": null,
"allowableValues": null,
"items": null
},
{
"name": "status",
"type": "string",
"description": "pet status in the store",
"allowableValues": {
"valueType": "LIST",
"values": [
"available",
"pending",
"sold"
],
"min": null,
"max": null
},
"items": null
},
{
"name": "name",
"type": "string",
"description": null,
"allowableValues": null,
"items": null
},
{
"name": "photoUrls",
"type": "Array",
"description": null,
"allowableValues": null,
"items": {
"type": "string"
}
}
]
}
I added it manually to the .json resource file and Swagger UI supports it, but swagger-php doesn't discover it.
I have the following:
A result class with property:
/** * @var array * @SWG\Property(name="facetSets", type="array", items="$ref:FacetSet") */ protected $facetSets;
The facet set class has the property that references a facet class:
/** * @var array * @SWG\Property(name="facets", type="array", items="$ref:Facet") */ public $facets;
But the Facet class is not discovered as model.
Hi, for some reason, if I'm using generation docs on-the-fly, basePath directive is ignored in Resource definition.
I also, have tried change this option via setDefaultBasePath but no luck :(
Here is example of my doc controller:
<?php
use Swagger\Swagger;
/**
* @RoutePrefix("/doc")
*/
class DocController extends ControllerBase
{
private function getSwagger()
{
$config = $this->getDI()->getShared('config');
$path = '..';
$exclude = '../vendor:../app/library:../app/migrations:../app/config:../public';
$swagger = Swagger::discover($path, $exclude);
$swagger->setDefaultBasePath($config['swagger']['basePath']);
$swagger->flushCache();
return $swagger;
}
/**
* @Get(".json")
*/
public function indexAction()
{
$this->response->setHeader("Content-Type", "application/json");
$resources = $this->getSwagger()->getResourceList();
$resources = str_replace('/resources/', '/doc/', $resources);
$this->response->setContent($resources);
}
/**
* @Route('/{resource}\.json')
*/
public function detailsAction($resource)
{
$this->response->setHeader("Content-Type", "application/json");
$resource = $this->getSwagger()->getResource('/' . $resource);
if (!$resource === false) {
$this->response->setContent($resource);
}
}
}
Thanks, and sorry for my bad english
Hiya!
First off, I'm really enjoying Swagger PHP so far - thanks so much for writing it! I'm experiencing a rather annoying quirk though: When installing it via Composer and implementing the autoloader, I have to delete the bin
and tests
dirs in Doctrine Common as well as the tests
dir in Swagger PHP to actually make it work - the Composer autoloader seems to load these directories too, which causes errors en masse.
I'm using Swagger PHP to document an API I've written on top of the Garden framework which also implements an autoloader - could this cause a clash? I'm still very much learning the ropes with PHP and autoloading in particular so I'm not at all sure what's going on. Any help would be greatly appreciated!
Kasper
Expand annotation awareness to not be method specific but also closures and no class structure implementations similar to
Example:
<?php
require_once dirname(__DIR__) . '/vendor/autoload.php';
/**
* @SwaggerResource(
* basePath="http://silex.local/api",
* swaggerVersion="1.0",
* apiVersion="1"
* )
* @Swagger (
* path="/pets",
* value="Gets collection of pets",
* description="This is a long description of what it does"
* )
* @SwaggerProduces (
* 'application/json',
* 'application/json-p',
* 'application/xml',
* )
*
*/
$app = new Silex\Application();
/**
*
* @PUT
* @SwaggerPath /{petId}
* @SwaggerOperation(
* value="Updates the existing pet designated by the {petId}",
* responseClass="pet",
* multiValueResponse=false,
* tags="Pet"
* )
* @SwaggerError(code=400,reason="Invalid ID Provided")
* @SwaggerError(code=403,reason="User Not Authorized")
* @SwaggerError(code=404,reason="Lead Responder Not Found")
* @SwaggerParam(
* description="ID of the route being requested",
* required=true,
* allowMultiple=false,
* dataType="integer",
* name="petId",
* paramType="path"
* )
* @SwaggerParam(
* description="pet being updated",
* required=true,
* allowMultiple=false,
* dataType="pet",
* name="pet",
* paramType="body"
* )
*
* @ResponseTypeInternal Model_Pet
*
*/
$app->match('/pets/{petId}', function () {
/*
* Edit a pet
*/
})->method('PUT');
$app->run();
I would like to seek feedback to determine if there is interest in providing a WADL format for the docs in addition to the swagger format.
Comments welcomed...
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.