Acme-CPANModulesBundle-Import-MojoliciousAdvent-2017
view release on metacpan or search on metacpan
devdata/https_mojolicious.io_blog_2017_12_08_day-8-mocking-a-rest-api view on Meta::CPAN
<pre><code>$ perl test-api.pl get /servers
[
{ "ip": "10.0.0.1", "os": "Debian 9" },
{ "ip": "10.0.0.2", "os": "Debian 8" }
]
</code></pre>
<p>So now I can write a bunch of JSON in my script and it will be exposed
as an API. But I'd like it to be easier to make lists of things: REST
APIs often have one endpoint as a list and another as an individual item
in that list. We can make a list by composing our individual parts using
Mojolicious templates and the <code>include</code> template helper:</p>
<pre><code class="hljs"><span class="hljs-comment"># test-api.pl</span><span class="hljs-comment">
</span><span class="hljs-keyword">use</span> <span class="hljs-function">Mojolicious::Lite</span>;
any '<span class="hljs-string">/*path</span>' => <span class="hljs-keyword">sub </span>{
<span class="hljs-keyword">my</span> ( <span class="hljs-type">$c</span> ) = <span class="hljs-type">@_</span>;
<span class="hljs-keyword">return</span> <span class="hljs-type">$c</span>-><span class="hljs-type">render</span>(
template => <span class="hljs-type">$c</span>-><span class="hljs-type">stash</span>( '<span class="hljs-string">path</span>' ),
<span class="hljs-function">format</span> => '<span class="hljs-string">json</span>',
devdata/https_mojolicious.io_blog_2017_12_08_day-8-mocking-a-rest-api view on Meta::CPAN
[
<%== include 'servers/1' %>,
<%== include 'servers/2' %>
]
@@ servers/1.json.ep
{ "ip": "10.0.0.1", "os": "Debian 9" }
@@ servers/2.json.ep
{ "ip": "10.0.0.2", "os": "Debian 8" }
</code></pre>
<p>Now I can test the list endpoint again:</p>
<pre><code>$ perl test-api.pl get /servers
[
{ "ip": "10.0.0.1", "os": "Debian 9" }
,
{ "ip": "10.0.0.2", "os": "Debian 8" }
]
</code></pre>
<p>And also one of the individual item endpoints:</p>
<pre><code>$ perl test-api.pl get /servers/1
{ "ip": "10.0.0.1", "os": "Debian 9" }
</code></pre>
<p>Currently we handle all request methods (<code>GET</code>, <code>POST</code>, <code>PUT</code>, <code>DELETE</code>)
the same, but my API doesn't work like that. So, I need to be able to
provide different data for different request methods. To do that, let's add the
request method to the template path:</p>
devdata/https_mojolicious.io_blog_2017_12_22_day-22-how-to-build-a-public-rest-api view on Meta::CPAN
<div class="post-content">
<section id="section-1">
<p>The <a href="https://www.openapis.org/">OpenAPI</a> Specification (formerly named
Swagger) is an API description format for REST APIs. An API specification
written using the the rules set by the Open API Initiative can be used to
describe:</p>
<ul>
<li>All the available endpoints. An endpoint is a unique resource that can
access or modify a given object.</li>
<li>Input parameters, such as headers, query parameters and/or body parameters.</li>
<li>The structure of the response, including headers status codes and the body -
if any.</li>
<li>Authentication methods</li>
<li>Contact information, license, terms of use and other information</li>
</ul>
<p>This post look into how to write an API specification and how to use it
together with
devdata/https_mojolicious.io_blog_2017_12_22_day-22-how-to-build-a-public-rest-api view on Meta::CPAN
</section>
<section id="section-2">
<h2>Why would you use OpenAPI</h2>
<p>This question comes up quite often after telling people about OpenAPI:
"but...why?" The people asking this often come from the same background as
myself, where you both write the producer (backend web server) and consumer
(JavaScript, ...) of the data. When you're in complete control of both sides
you don't really need to write any formal specification or document your API,
since you already <em>know</em> how it works. This can be very true - at least if you
make sure you have tests of all your endpoints.</p>
<p>Personally I'm a <a href="http://www.linkognito.com/images/05-08-08/metal.gif">huge fan</a>
of documenting as well as testing. I often say that if you can't document
(describe) the API/method/whatever, something is wrong and you should reconsider
what you're coding. Documenting an API on the other hand is awful in my opinion,
especially during rapid prototyping/developing where it's hard to keep the
code and documentation up to date.</p>
<p>So how does OpenAPI fix this? Since the input/ouput Perl code is generated
<em>from</em> the OpenAPI Specification, you know that the backend is always running
code accordingly to the specification. Also, since the documentation you
generate is not hand written, but generated from the same OpenAPI document you
can with certainty know that the code the server is running, is in sync with
the documentation.</p>
<p>By "generated code" I don't just mean the routes/endpoints, but also input and
output validation. This means that when any data has made it through to your
controller action, you know that the data is valid. On the other side, the
consumer (let's say a JavaScript that cares about the difference between an
integer and string) will know that it has received the correct data, since
invalid output will result in a
<a href="https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#5xx_Server_Error">500 - Internal Server Error</a>.</p>
<p>So... If you don't care about documentation or collaboration with others, then
I'm not sure if I would care much about OpenAPI either.</p>
( run in 0.279 second using v1.01-cache-2.11-cpan-27979f6cc8f )