Contiamo REST Client
This REST client attempts to communicate with a backend API, interacting in a declarative way.
Getting Started
First, you'll want to add the contiamo-rest-client
to your project like so:
npm install contiamo-rest-client
, alternatively
yarn add contiamo-rest-client
if you're into yarn.
Then, your code needs a couple of building blocks:
Block 1 - an API blueprint
Consider the following REST endpoint:
GET https://api.myapp.com/tenants/123/bundles
The above URL signals two things:
- There is a
collection
ofresource
s available at/tenants
. - There is a more specific
tenant
(#123) that we want to retrievebundle
s for.
Expressed as a blueprint that this client understands, this would look like:
key: 'tenants' collection: TenantCollection path: 'tenants' children: key: 'bundles' collection: BundleCollection path: 'bundles'
From the above snippet, we see that the BundlesCollection
is a child of TenantsCollection
, similar to our URL structure.
But what is TenantsCollection
?
Block 2 - Collections and Resources
Consider:
Collection { thisresource = }
From the above snippet, we see the proper intended usage of this client. The client exposes a Collection
and a Resource
onto which certain privileges can be applied: Fetchable
, Listable
, Destroyable
, Editable
, Retrievable
, etc. These privileges, under the hood, really just map to their respective HTTP verbs.
The API blueprint composes these collections together.
Putting It All Together: Instantiating the Client
Consider:
const myClient = blueprint apiBase: 'https://whatever.rest/'
The client then exposes an API as so:
/** * Keeping the URL in mind, * GET https://api.myapp.com/tenants/123/bundles */ const getBundles = async await myClient
This would fetch a list of bundles for tenant 123. To fetch a specific bundle resource, one could instead write .children('bundles').build('456').fetch()
.
The API of this client is self-documenting when using TypeScript and an autocomplete feature like IntelliSense.
Privileges
Below is a brief overview of the various privileges (.list()
, .fetch()
, etc.) available to Collections
and to Resource
s.
Collection
Privileges
Listable(Collection)
This privilege lets a collection (or list) be retrieved. (GET
)
Usage: Collection.list()
const listChildren = async await Client
Creatable(Collection)
This privilege lets a collection (or list) be created. (POST
)
Usage: Collection.create()
const createCollection = async await Client
Resource
Privileges
Fetchable(Resource)
This privilege lets a single resource be retrieved. (GET
)
Usage: Resource.fetch()
const listChildren = async await Client
Modifiable(Resource)
This privilege lets a single resource be modified. (PUT
)
Usage: Resource.modify()
const listChildren = async await Client
Destroyable(Resource)
This privilege lets a single resource be deleted. (DELETE
)
Usage: Resource.destroy()
const listChildren = async await Client
How It Works
Basically, the Client
at the top of the .children().build().children().build().doSomething()
chain is the single point of contact with a backend API. This is where the fetch
ing happens. Everything else is just syntactic sugar that consults the blueprint in order to construct a path to query. When request
is called on a Resource
or a Collection
, this method bubbles up to the top-level request
method on Client
, that does the actual server communication.
Contributing
git clone git@github.com:Contiamo/rest-client.git
yarn install
code .
(oratom .
orslime .
or whatever dude)
Look up and create issues, make PRs, spread the love. ❤️