Overview
========
Before we dig in, here is a high-level overview of Cosmic.
Motivation
----------
We believe that using web APIs should be as easy as using native libraries.
Cosmic builds a native communication bridge across all supported languages,
while providing a well-documented, clean HTTP structure as a fallback.
We are tired of discussing HTTP, of arguments around how to structure URLs,
how to serialize query parameters, which headers to include and which codes to
return. We believe that these questions are simply not worth your time. Cosmic
attempts to gather the best conventions of HTTP APIs and abstracts them away.
When you write your API server using Cosmic, developers can use it in their
favorite language as if it was a locally installed library. In addition to
this, we are working on the Cosmic Registry, a centralized hub of richly
integrated Cosmic APIs with beautiful auto-generated documentation.
The Universal Client
--------------------
You cannot escape writing API clients. On the provider side, the API library
or framework serves as glue between business code and HTTP. On the consumer
side, the burden of gluing HTTP to business logic lies on the shoulders of the
developer.
Writing a client for every API/language combination is a tremendous amount of
work (``O(n^2)``), only the most popular APIs and the most popular languages
have clients written for them. Cosmic brings the amount of work down to
``O(n)`` by specifying a way of building universal clients. Such a client is
built from the description of an API in the form of a JSON spec.
If you port Cosmic to a new language, you do the equivalent of writing a
client for every existing Cosmic API. If you use Cosmic to build an API, you
get a number of clients for free. New client ports should motivate developers
to pick Cosmic as a server-side API framework. New Cosmic APIs should motivate
developers to write new clients.
As for the API spec, our approach differs from something like `Swagger
`_ as we are not trying to
describe an API in low-level detail. Instead, the JSON spec of a Cosmic API
tries to be high-level and semantic. For instance, in Swagger, every REST-ful
endpoint of a collection needs to be described separately, including the
method, URL format and response code. In Cosmic, these details are decided by
the framework, so the API spec only describes the data structure of the model.
REST and RPC
------------
The definition of `REST
`_ is a
controversial subject. For our purposes, these are the key elements:
* Objects are assigned unique URLs.
* These URLs are used to link objects together.
* Objects are manipulated by a set of standard methods (`CRUD
`_).
It is fairly straightforward to create a REST API from a database table, but
other kinds of information can be expressed with REST as well. In general it
is a good idea to try, and fall back on `RPC
`_ only if REST is clearly
a bad fit.
RPC stands for "remote procedure call". It is a simple interface where a
client sends a request to call a remote function with certain parameters and
gets the return value of the function in the response. You might find many
discussions online that are framed as "REST vs RPC", but in reality they are
tools that complement each other.
Architecture
------------
Cosmic is a layer that sits between business code and HTTP. This is true for
both the client and server components. In fact, if you were to draw the client
and the server component, you'll see that they are perfectly symmetrical.
Because of the above, and because API clients are to be built from a JSON spec
generated by the server, we decided to implement the API class as a
serializable type. When you serialize a server-side Cosmic API, you get the
JSON spec, when you deserialize it on a different machine, you get an API
client. The serialization is done by `Teleport
`_.
Cosmic abstracts HTTP into endpoints. An endpoint is a rule for serving a
function via HTTP. It contains both the server and the client component. For
the server, it defines :meth:`parse_request` and :meth:`build_response`
methods. For the client, it defined :meth:`build_request` and
:meth:`parse_response`. The reason the server and the client components are
grouped in one object is that the client's :meth:`build_request` method is
intimately related to the server's :meth:`parse_request` method. Similarly,
:meth:`build_response` and :meth:`parse_response` are perfectly symmetrical.
Cosmic treats HTTP as an elaborate serialization scheme and takes full
responsibility for it, leaving you with natively-behaving functions.
.. TODO [endpoint diagram]
.. _teleport:
Built on Teleport
-----------------
.. seealso::
The `Teleport documentation `_ is worth a
look if you are getting started with Cosmic.
Teleport is our very own library that is used for JSON serialization,
validation, and generating documentation. At first this might seem like an odd
set of features for a library, but they come quite naturally from the fact
that Teleport is essentially a very simple static type system. All information
that gets carried between Cosmic clients and servers is statically typed with
the help of Teleport.
Teleport is implemented as a collection of composable type objects. The
composition of these objects mirrors the data it is meant to serialize and
validate. One important feature of Teleport is that this composition, the
schema, is also serializable. This makes it possible to use Teleport to
serialize model properties and function definition, which are necessary to
serialize the API.
Teleport makes it easy to define custom types, a feature used by Cosmic.
The Teleport docs will teach you to import from the :mod:`teleport` module::
from teleport import *
In Cosmic, you should import from :mod:`cosmic.types`::
from cosmic.types import *
Apart from providing the standard Teleport types, this will give you custom
types defined by the Cosmic library as well as access to Cosmic models by
using the ``.`` syntax. For instance::
>>> from cosmic.types import Schema
>>> from myapi import MyModel
>>> Schema.to_json(MyModel)
{u'type': u'myapi.MyModel'}
Built on Flask
--------------
For the server component, Cosmic relies on `Flask `_,
a great Python web microframework. A Cosmic API server creates a complete
Flask application from scratch. Running this application means running your
API. When working on a Cosmic API, some knowledge of Flask may be necessary.
In particular, Flask provides some objects that could be useful to import:
`request `_ and `g
`_.
.. _hal:
Hypermedia with JSON HAL
------------------------
`JSON HAL `_ is a compact
specification for linking REST-ful resources as well as returning multiple
embedded resources in one call (this is used by the :ref:`get_list` endpoint).
Note that HAL recommends ``application/hal+json`` for the *Content-Type*
header, but currently Cosmic responds only to ``application/json``.