<?xml version="1.0" encoding="UTF-8" standalone="yes"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-us"><id>https://blog.pgxn.org/tags/api-server/</id><title>API Server</title><updated>2011-04-29T20:44:02Z</updated><link rel="self" type="application/atom+xml" href="https://blog.pgxn.org/tags/api-server/feed.xml"/><link rel="alternate" type="text/html" href="https://blog.pgxn.org/tags/api-server/"/><author><name>The PGXN Maintainers</name></author><generator uri="https://gohugo.io/" version="0.167.0">Hugo</generator><entry><id>https://blog.pgxn.org/post/5049235040</id><title type="html">About the Infrastructure: PGXN API</title><link rel="alternate" type="text/html" href="https://blog.pgxn.org/2011/about-pgxn-api/"/><updated>2026-10-07T16:13:48Z</updated><published>2011-04-29T20:44:02Z</published><author><name>David E. Wheeler</name></author><category scheme="https://blog.pgxn.org/tags" term="infrastructure" label="Infrastructure"/><category scheme="https://blog.pgxn.org/tags" term="api" label="API"/><category scheme="https://blog.pgxn.org/tags" term="api-server" label="API Server"/><category scheme="https://blog.pgxn.org/tags" term="metadata" label="Metadata"/><category scheme="https://blog.pgxn.org/tags" term="rest" label="REST"/><category scheme="https://blog.pgxn.org/tags" term="http" label="Http"/><summary type="html"><![CDATA[<p>The second piece of the PGXN infrastructure, after <a href="https://blog.pgxn.org/post/4854707157/pgxn-manager" title="About the Infrastructure: PGXN Manager">PGXN Maanager</a>, is the
<a href="https://api.pgxn.org/">PGXN API Server</a>. I&rsquo;ve just finished the <a href="https://github.com/pgxn/pgxn-api/wiki">API documentation</a>, which covers
both the lightweight static file API provided by mirrors and the superset
provided by the API server. So now seems like a good time to talk about the
design of the API server and how it works.</p>
<p>At its core, the PGXN API server is just another mirror. It has an hourly cron
job that <code>rsync</code>s to the master mirror, updating the mirror. But then it
iterates over the <code>rsync</code> log and transforms some things. Here&rsquo;s what it does:</p>]]></summary><content type="html" xml:base="https://blog.pgxn.org/" xml:space="preserve"><![CDATA[<p>The second piece of the PGXN infrastructure, after <a href="https://blog.pgxn.org/post/4854707157/pgxn-manager" title="About the Infrastructure: PGXN Manager">PGXN Maanager</a>, is the
<a href="https://api.pgxn.org/">PGXN API Server</a>. I&rsquo;ve just finished the <a href="https://github.com/pgxn/pgxn-api/wiki">API documentation</a>, which covers
both the lightweight static file API provided by mirrors and the superset
provided by the API server. So now seems like a good time to talk about the
design of the API server and how it works.</p>
<p>At its core, the PGXN API server is just another mirror. It has an hourly cron
job that <code>rsync</code>s to the master mirror, updating the mirror. But then it
iterates over the <code>rsync</code> log and transforms some things. Here&rsquo;s what it does:</p>
<ul>
<li>Unpacks each distribution in a directory for browsing. Here, for example, is
where one can <a href="https://api.pgxn.org/src/semver/semver-0.2.1/">browse the semver 0.2.1</a> sources.</li>
<li>Searches for a <code>README</code> file and any files recognized by <a href="https://search.cpan.org/perldoc?Text::Markup">Text::Markup</a> and
converts them to sanitized HTML with a table of contents. Such files can
then be used to display the <code>README</code> on the <a href="https://pgxn.org/dist/semver/" title="semver distribution page">distribution page</a> and to
display <a href="https://pgxn.org/dist/semver/doc/semver.html" title="semver documentation">individual documentation files</a>.</li>
<li>Merges the distribution metadata file with the latest stable release
<code>META.json</code> generated by PGXN Manager. For example, as of this writing, the
API server&rsquo;s <a href="https://api.pgxn.org/dist/semver/0.2.1/META.json">semver 0.2.1 <code>META.json</code></a> and the unversioned <a href="https://api.pgxn.org/dist/semver.json">semver.json</a>
are identical. Effectively, this format has all the metadata from the
<code>META.json</code> as well as a list of all releases of the distribution from the
<code>semver.json</code>. This is useful for displaying all the data on the
<a href="https://pgxn.org/dist/semver/" title="semver distribution page">distribution page</a> by fetching the data in a single API request.</li>
<li>Updates all other versions of the <code>META.json</code> file. For example, if you look
at the <a href="https://api.pgxn.org/dist/semver/0.2.0/META.json">semver 0.0.0 <code>META.json</code></a>, you&rsquo;ll see that it includes 0.2.1 in its
list of releases, even though 0.2.1 was released after 0.2.0. This allows
<a href="https://pgxn.org/dist/semver/0.2.0/">semver 0.2.0</a> page on the main site to have a select list of version to
choose from, including versions released later, with a single API request.</li>
<li>Adds additional metadata to the extension JSON file for all extensions in
the distribution. The added data includes release dates for the list all
distributions providing the extension, as well as an abstract and doc path
for the latest stable release. To see the differences, compare the <a href="https://api.pgxn.org/mirror/extension/semver.json">mirror
<code>semver.json</code></a> to the <a href="https://api.pgxn.org/extension/semver.json">API <code>semver.json</code></a>.</li>
<li>Adds an abstract for each distribution listed in the user&rsquo;s JSON file and
all tag JSON files. Compare, for example, the <a href="https://api.pgxn.org/mirror/user/theory.json">mirror <code>theory.json</code></a> to the
<a href="https://api.pgxn.org/user/theory.json">API <code>theory.json</code></a> and the <a href="https://api.pgxn.org/mirror/tag/data%20types.json">mirror <code>data types.json</code></a> to the <a href="https://api.pgxn.org/tag/data%20types.json">API
<code>data types.json</code></a>. This allows the <a href="https://pgxn.org/user/theory">user page</a> and <a href="https://pgxn.org/tag/data%20types/">tag pages</a> to include
the abstract in the list of distributions released by the user or associated
with a tag.</li>
<li>Adds records to a <a href="https://incubator.apache.org/lucy/">Lucy</a>-powered full text search index.</li>
</ul>
<p>All of this merging stuff came out of my thinking following the discussion of
the <a href="https://blog.pgxn.org/post/3099288750/pgxn-api-rfc">PGXN API RFC</a>. The decision to use <a href="https://incubator.apache.org/lucy/">Lucy</a> instead of PostgreSQL&rsquo;s
<a href="https://www.postgresql.org/docs/current/static/textsearch.html">full-text search</a> followed rather naturally from this, as I quickly realized
that there was no other driving need for a relational database behind the API
at all. The <em>only</em> dynamic API is the <a href="https://github.com/pgxn/pgxn-api/wiki/search-api">search API</a>. Everything else is just
static files. And given the <a href="https://www.depesz.com/index.php/2010/10/17/why-im-not-fan-of-tsearch-2/">performance issues</a> of in-database search, as
well as the desire to have fewer outside dependencies, made the decision a
natural one.</p>
<p>Beyond the syncing, there is a very simple web server providing the HTTP REST
interface to the static JSON files and the full-text search. That&rsquo;s it,
really. The API server is really just another mirror on steroids. The nice
thing is that it allows an interface, such as <a href="https://search.cpan.org/perldoc?WWW::PGXN">WWW::PGXN</a> or the new <a href="https://blog.pgxn.org/post/5026314153/writing-a-client-for-pgxn">PGXN
client</a> to work with either interface, just failing gracefully when API server
APIs are unavailable.</p>
<p>If you want to learn more about the specifics of the REST API, the <a href="https://github.com/pgxn/pgxn-api/wiki">API
documentation</a> has <em>all</em> the details. Really, it&rsquo;s quite comprehensive!</p>
<p>I actually consider the API to be 1.0-complete at this point, unlike PGXN
Manager. The only thing I want to add is <a href="https://en.wikipedia.org/wiki/JSONP">JSONP</a> support for static JSON files
(right now it&rsquo;s only for search results) and might tweak a few things here and
there, but otherwise I think it&rsquo;s in pretty good shape.</p>
<p>Longer term, though, it might be worthwhile to add some other features to
enhance the value of PGXN overall. Some ideas:</p>
<ul>
<li>Distribution and/or extension ratings (reviews, Like/Dislike, stars, or
something).</li>
<li>Diffs to compare changes between versions.</li>
<li>A test reporting infrastructure with result matrices (á la <a href="https://www.cpantesters.org/">CPAN Testers</a>.</li>
</ul>
<p>But I think we need to build up some momentum on the foundation that&rsquo;s in
place. Have you submitted your extensions, yet?</p>
]]></content></entry></feed>