OK I know there's PhpDocumentor for generating documentation from php code. It seems it hasnt been updated in a long time (but maybe they figure its mostly feature complete).
While this might be good for documenting things for other programmers, it doesn't seem well suited for documenting the external "API" of a web service. IE, if I've got a nice MVC structured project, PhpDocumentor might be great for documenting all the models and internal libraries and such for other developers on that project, but how do I document the web service it provides?
I am thinking something where you could document the methods on the controllers using tags like:
/**
#service /device/add
#access POST
#return JSON
*/
which in the generated docs would show that you need to do a POST request, it returns JSON data and the URL to access it is http://whatever.com/device/add. Obviously there would be a global config file for the documentation that defines what the base url is for these service calls.
At this point I am thinking I will just implement something myself using reflection on the phpdoc blocks (or using Annotations with the addendum library) and have the docs accessible dynamically right in the application.
You might prefer DoxyGen (or PHPxRef) to PhpDocumentor .
"While this might be good for documenting things for other programmers, it doesn't seem well suited for documenting the external "API" of a web service".
Why not put DoxyGen (or whatever) comments only into the API functions which are externally visible?
Give a description of each and use #param [in], #param [out] and #return.
Wouldn't that achieve what you want? Or did I miss something?
I think what your asking (documenting an API (especially if its RESTful)) would be to use a WADL. Granted its not going to be generated from source (no tools for that in PHP), but a WADL is excellent for documenting a service.
You can have sample payloads in all sorts of media types, all the response codes and how you handle them -- really everything you need.
Related
Goal
I've been tasked with versioning a pretty large PHP Lithium API.
The end result I'm looking for is to use namespacing to separate the versions.
For example, normally a lithium route that looked like this:
Router::connect('/{:controller}/{:action}/{:id:\d+}');
Could have the following URL, map to the following PHP call:
http://www.fungames.com/game/view/2
app\controllers\Game::View($gameId)
But I would like to create the following mapping:
Router::connect('/{:version}/{:controller}/{:action}/{:id:\d+}');
Such that the following two calls could be made:
http://www.fungames.com/v1/game/view/2
app\controllers\v1\Game::View($gameId)
http://www.fungames.com/v2/game/view/2
app\controllers\v2\Game::View($gameId)
Problem
Unfortunately, the Lithium documentation doesn't make much mention of API versioning. There's a brief mention here as an example of continuation routes. But that approach would required making if statements in my controllers to version my API, and I personally consider that a poor approach.
TLDR
What is the best way to achieved namespaced API versioning when using the PHP Lithium Framework?
API versioning is a really broad topic, and while Li3 gives you all the necessary tools to implement any approach you choose, the actual implementation is up to you. Having said that, the routing layer is fairly sophisticated and will get you very, very far. See this gist on routing configuration examples.
Combining this with Request::get() which allows you to match on any request parameters including headers (you can pass get()-compatible values as $params in Router::connect() — see examples here),
and Request::detect(), which allows you to implement custom matching logic, you can send any configuration of values down to the controller/dispatch layer. This allows you to segment your versions by differently namespaced controllers (with fallback to the default), prefixed actions, or pass a namespace/class path for a different model.
Yet another approach, and one that I would recommend in the general case, is implementing a set of transaction managers/mappers for any endpoints that need to be versioned, and using them as an intermediary between your controller and your model, then use routing to switch between them.
This approach is made easier if you evolve your API using, i.e. content types, since you can choose a mapper based on that. This is also nice since version numbers are strongly discouraged by REST's creator.
Anyway, hope that helps.
As part of an App i'm developing there's a requirement to create a conversion between our RESTful JSON API and a number of other formats. The intention is to allow output from our API to be converted to make further requests to API's that use different formats such as SOAP, or other REST based API's with different requirements.
A few examples of the kind of things I think this might need to do:
manipulate the JSON output to use different keys (and maybe only a subset of
data
convert to an XML packet/document
convert to a valid SOAP request
output data as a specific filetype/structure (such as csv)
I'm interested really in what approaches should I be looking at here. It would seem to me that this should be a fairly common request so i'm interested if there are specific libraries I should look at, or existing services perhaps. If such a service doesn't exist then ideally I want to create a common structure whereby the 2 disparate services can be mapped using a universal set of tools that are just then configured to work together. This will be within a Laravel PHP application so any Composer compatible library would work.
Following on from my comment:
"I am not aware of any such library to do this, but as a rough guide I think you probably want to create some kind of adapters which all use a common interface. These adapters can then be written to deal with the conversion you are trying to achieve via some open-source library. Manipulating the output might be a good excuse to use the decorator pattern :) Sorry I could not be of much more help."
An example of what I think you are after is the following:
An interface for your adapters
interface DataConvertor
{
public function convert(DataInterface $data);
}
An interface for the data you are passing around (the data will be an object also with a common interface to work from).
interface DataInterface
{
/**
* returns a json string
*/
public function asJson();
}
Then you can create your adapter for use with some 3rd party library.
class SomeThirdPartyNameAdapter implements DataConvertor
{
public function convert($data)
{
//some logic here to make my data object with a known asJon method
//suitable for use for some 3rd party library, and use that library.
$rawJson = $data->asJson();
//manipulate this as needed ($compatibleData)
$thirdPartyLib = new ThirdPartyLib();
return $thirdPartyLib->thirdPartyMethod($compatibleData);
}
}
Obviously this is just a rough guide and there may be other parts of this you can make abstract (e.g. have the adapters implement the DataConvertor interface but also extend some abstract class to inherit some functionality, or other method to add to your interface).
Hope this helps
Carl is right that a great approach is to create some adapters using a common interface. Then you can provide implementations that convert JSON to XML or JSON to a CSV, etc.
However I would strongly recommend looking into Mule ESB as a solution as well. http://www.mulesoft.org/
It's a Java based, open source project that allows you to do pretty quick and efficient integrations. For example, you could create a "flow" (a Mule term) that makes a RESTful call and then converts the data and pumps it out to a specific destination (CSV, SOAP call, XML, etc.)
The real selling points of Mule (things that have worked great for me):
Very easy to deploy. It works similar to something like Tomcat, where you can deploy a package and it runs on a server.
Tons and tons and tons of boilerplate code already done for you.
Free and stable. They have tons of high profile customers so it's pretty battle tested and we've been able to get their free version working in production with no trouble.
I am trying to code the process of creating Zend_Form objects using Doctrine2 ClassMetadatas so that form generation for my client database application is easier.
I needed somewhere to store the element labels, descriptions, and etc. using custom phpdoc tags seemed a good idea. But it seems ClassMetadataInfo doesn't provide 'annotations' outside what it's expecting.
Thats sensible I guess, but im struggling to find a way to get it to parse the entire phpdoc block.
I've looked at using getReflectionClass() and parsing it myself, but id loose out on the great caching. The Doctrine2 parser works really well for what it does, but I can't make heads or tails of it!
Being able to use the phpdoc short description as an element label, and long description as the description would be rather handy for my form<>model friendships.
Anyone else pondered on this?
Dotrine2 provides both an AnnotationDriver (which is used by the ORM) and an AnnotationReader (used by the driver and which provides more abstract method).
Take a look at the source
Doctrine\ORM\Mapping\Driver\AnnotationDriver
Doctrine\Common\Annotations\AnnotationReader
In case anyone finds this answer: The latest version of Doctrine as of now includes a more advanced annotation reader, including caching mechanisms (which you probably want). Take a look at the doctrine documentation for some nice examples of usage.
I'm looking for some thin layer on top of handling HTTP requests that can easily do routing to different backends, based on the uri / rest verb / actual service location / .... This layer should also handle encoding into whatever the requested format is (xml / json / returning binary data / etc.).
The most important point though is to make it pluggable into some backend - whether it's a message queue, job dispatcher, external process, or something completely different. They should be handled with minimal wrapper for the needed message translation.
So basically, that would be a customisable request dispatcher with some magic on top. Does something like that exist as a separate application now?
Edit: Almost forgot - it would be great if it was written in PHP... but if something else matches the description, I'd have a look too.
Don't know about PHP, but if Java and/or Python are acceptable options for you, you should take a look at RESTx, which was designed for the simple and fast creation of RESTful services. RESTx is fully open source, GPLv3 licensed.
I agree that many frameworks are all about object creation and mapping, which often can be very annoying and get in the way. RESTx, however, is about the data, the automatic conversion of content types and so on. With RESTx you can write custom components in either Java or Python. These components can take care of access to databases, custom APIs, legacy data, cloud services, etc. RESTx examines the code and automatically produces a self documented, discoverable, RESTful API. It's all links you can follow. Take a look at how to take a tour of the server with a web browser.
The key is that you can POST parameter sets to those components which are then stored and accessible under a new URI. You access the URI, the parameters get applied to the component and you get the output back. Thus, you can rapidly create new RESTful web services and resources. You can access other resources easily from within your component's code and it doesn't cause an additional HTTP request.
I'm the lead developer for RESTx, so if you have any questions about it, please contact me on the forums (links to those are on our web site).
Zed Shaw of Mongrel fame is attempting to do just this. He's creating Mongrel2 (still in development), essentially a universal frontend for web application backends. It allows you to plug in any program that can send and receive 0MQ or HTTP messages like a reverse proxy.
It also uses a sane configuration file system: SQLite. No more messing around with Apache config files with weird syntax.
It's written in C, so it may not be as easy to deploy as a language like PHP, but it certainly scales very well.
If you're not satisfied with Mongrel2, it's relatively easy to roll your own. I've used nodejitsu's node-http-proxy for one of my own projects. It's simple and fast. Plus, you can write your routing rules using regular old if statements.
I'm new to StackOverflow so it won't let me embed more than one hyperlink, haha.
If I have a REST based service written in the Symfony [symfony-project.org] framework (i.e. PHP), is there any decent tools/frameworks out there that will parse my code and generate API documentation?
The Java based framework enunciate has documentation capabilities similar to what I need, you can view an example of this here: http://enunciate.codehaus.org/wannabecool/step1/index.html.
I understand the premise of REST based services are supposed to be self evident, however I was after something that would generate this documentation for me without the need to manually write up all my endpoints, supported formats, sample output etc.
Thanks
Not sure if you've seen Swagger before. They seem to have a PHP compatible version, though I can't really vouch for it personally. It does some automatic API documentation generation comparable to enunciate, though it does look like it requires some heavy manual documentation via PHP comments. That being said, I think the manual effort will be the same or less than making your own via wiki pages, and the output is much, much nicer.
Just as a factoid, it looks like Enunciate has indefinite plans to eventually support other platforms, but the relevant Jira ticket is currently Open waiting for a sponsor to take on the work.
From the ENUNCIATE-356 Jira ticket:
The first step to supporting other languages is to decouple the Enunciate model from the Java model. This work is being tracked and logged at ENUNCIATE-584. Unfortunately, it never made it out of the investigate phase because of how heavy it is. Unless a sponsor for the work is found, I don't anticipate taking that heavy load on anytime soon.
Edit:
Found a similar question where someone mentions a GitHub project dedicated to Swagger+Symfony2. This other question is the same, but no additional information.
To my knowledge there is no way to automate the documentation of media types.
If you are using a media type like XHTML then a web crawler like Google sitemap may produce some useful output to show the relations between your resources.