Friendly disclaimer: this is a quick and dirty post that I'm putting together as I research API resources to build an API for a project I'm working on, so I'm sorry for being so direct and to the point, and also for the number of levels and bullet points :)
It was written in the order of "here only for the sake of completeness" down to "probably what we're going to use".
TL;DR
- GraphQL should be the way to go only if your frontend sort of requires it. Needs a lot of boilerplate and manual sync between your Eloquent models and GraphQL-related code.
- JSON-API is the most respected standard that could face GraphQL, but on Laravel-land it renders you documentation-less. You'll probably have to write separate documentation on API Blueprint or something like that, and it might take you some time as well. You can also discover how to get Blueprint generated through a specific package (that bridges JSON-API with Dingo), but... good luck on that.
- Handwritten RESTful API... Do I need to comment on that? It's handwritten. Certainly not a good option for a medium or big API.
EOF
.
Prologue: basic API requirements we had
- should have built-in documentation, that's not dependent on the developer to manually write it (think PHPDocs that magically autocomplete in your IDE)
- it needs to be blazing fast, as it will be used on a speed-sensitive user interface
- here the features of field-selection from GraphQL or JSON-API come to my mind
- obviously, a simple cache layer might also be helpful
Research and comparisons
API type option 1: GraphQL
Short conclusion. Doesn't seem trivial to be built, as there's a lot of boilerplate to be written that repeats information from Eloquent: GraphQL Types, Queries, and Mutations. That happens on both packages found, and neither of them helps by having a boilerplate-generator.
Helpful Packages
- By Folkore Atelier
- By Rebing, based on Folklore's
API type option 2: RESTful
Subtype 1: JSON-API
Conclusion: also not that trivial to work with, but seems simpler than GraphQL. However, documentation might be a weak point.
Helpful packages
Nil's Laravel5-json-api
- Implements
include
,fields
,sort
,page
- Almost boilerplate-free with generic controllers
- However, you still need to configure Transformers, although they don't repeat much information from the Eloquent model
- No support for documentation generation. At all.
Laravel5-json-api-dingo
Good points
Theoretically, brings together the best of both packages, including Dingo's features (Dingo is discussed later) such as Auth, Versioning, Rate limiting, Docs and Routes into laravel5-json-api (called L5JA from now on).
Bad points
- it's not clear how documentation could be generated, as Dingo depends on annotations and L5JA is ideally based on a generic controller implementation. There might be other integration issues, as the examples do not clearly define how to bring both packages together, besides a basic routing sample.
- support also seems to be lacking behind.
cloudcreativity's Laravel-json-api
This one has very long documentation; while seems complete, it might take a while to read everything and implement (took me a while reviewing the docs to see what features were available). And there are at least two empty pages, with a simple "todo" note.
Good points
- also sort of boilerplate-free with generic controllers, and basic code generation for the other things (Adapters, Schemas)
- Adapters and Schemas will still need some filling and manual sync with the Eloquent model, though
- Also sports first-class validation rules for the API (which might end up being duplicated on your code, just like Eloquent details....)
- seems to have a decent Auth infrastructure
Bad points
- no clear mention on the docs about the selection of fields, and missing docs for sorting and "sparse fieldsets" (if that what I called "selection of fields"?) (issue on the topic)
- filtering must be hand-written as well, there's no automatic API to turn filter parameters into Eloquent queries (much like GraphQL queries are built... sad).
- also, no mention about documentation generation. There's an old issue that states Swagger can't work together with JSON-API, and the main developer doesn't have time to dedicate to that (we all know how open-source is born and dies, right? Free developer time during the lifecycle of a related project...)
Subtype 2: Plain "bring-your-own-standard" JSON API
Conclusion: the easiest to be built in our case, as we might end up needing only a couple of read-only endpoints. Might need some boilerplate to allow for field selection or advanced querying capabilities, but generates Blueprint documentation files and might even generate HTML docs with other generators.
Helpful Packages
Dingo
Good points
- complete feature-set: auth, rate limiting helpers, errors, routing, doc generator (through Blueprint files)
- Blueprint files can be used with a number of parsers to, then, generate HTML documentation or similar. Options and related resources are listed at the bottom of this post.
Bad points
Well... you'll have to write all your controllers and actions by hand. And define all your filters, if any. And whatnot.
Restler
This is actually unrelated to Laravel, but Eloquent can be easily made to work with it, so it's worth mentioning as a companion project to your main Laravel application.
Good points
- complete feature-set, including Swagger documentation based on PHP Doc blocks and method parameters (that are also used for automatic request validation)
Bad points
Got abandoned:
- stopped on PHP 5.4 support, while could have a great usage of PHP 7 first-class types
- stopped on an old version of Swagger, missing some of its features - probably one of the reasons the package got abandoned, as Swagger is sometimes referred as a very complicated beast to deal with.
Sample implementation
Once upon a time, I started working on an API Server build with an Eloquent extension (also sort of abandoned) and Restler. It included some base controllers that made CRUD actions only a couple of lines away.
Other useful resources
- Apiary - complete toolset (needs clarification!) to define, document and work on APIs.
- Apimatic's transformer - UI and API that can translate to/from almost any doc format. Could be integrated in the API generation pipeline.
- Dredd - parses Blueprint/Swagger docs and automatically runs tests to ensure the Backend complies with the defined documentation.
- Blueman [probably outdated] - Generates Postman collections based on Blueprint files
- PHPDraft - basic HTML generator from Blueprint files
- Laravel Blueprint docs - generates integrated documentation inside your Laravel project, using its routing, and Blade templates for further customization.
Top comments (4)
I'm happy to see my JSON API implementation on the list.
Nice write up.
I can certainly add Swagger doc generation and it was on the works at some point but was unsure if community needed and so my effort to build it.
Somewhere during this research (I think it's in Dingo docs) I saw something I completely agree: documenting your API is as important as having it working. APIs don't autocomplete not even in the best IDE, so your end user must be able to read how the API works.
I'm not sure how PITA is to implement Swagger exports, but I guess Blueprint is a much easier target format and might be a good middle-ground there.
Finally, maybe the way to go is to simply show more love for the Dingo integration, as they already do stuff like that :)
BTW, how did you end up seeing my this article? haha
Yeah I totally agree documentation is a must, but I didn't want to be way too opinanted it because there wasn't a clear winner a couple of years ago. Swagger/OpenAPI is the clear winner for non GraphQL APIs now.
IMHO for PHP zircote/swagger-php is the best option to document using annotations in php doc-blocks without the need of writing the JSON yourself.
I'm still working on API development, currently under NodeJS and Java platforms, so I'm following all API posts and GraphQL posts here at dev.to :)
Hahaha cool you ended up here :)
From past experience Swagger seemed really a PITA to get implemented, although being very powerful. Might be just a false impression, tho.
For my current case I ended up going with Postman. Started using it quickly to verify development, then wrote a test or two, then saw docs there... 🤷🏼♂️
Thanks for the input!