Nick Sjostrom
5 min readFeb 26, 2020

Introducing Machinable

Machinable Logo

Built as a custom Backend-as-a-Service to bootstrap apps, Machinable is an open source web application that let’s you create projects with custom sub-domains, then define API resources for that project using JSON schema. From your project’s dashboard, automatically generate OpenAPI documentation, create web hooks to POST events to your own servers to handle business logic, and manage user sessions.

Features

Below are a list of some of the features provided by Machinable. If you’d like to dive right in, check out the user documentation here:

API Resources, described by JSON Schema

API Resources are endpoints which store JSON Objects that are described and validated by JSON Schema. This gives you the ability to create API endpoints that will validate the data being saved to it without writing any code.

Machinable Project Dashboard

Say you have a Pet Store project and you want an API Resource at /dogs , where the dogs for your pet store app have a name and an age. The corresponding JSON schema could look like this:

{
"type": "object",
"properties": {
"age": {
"description": "The age of the dogs.",
"maximum": 50,
"minimum": 0,
"type": "integer"
},
"name": {
"description": "The name of the dog.",
"maxLength": 32,
"minLength": 0,
"type": "string"
}
},
"required": [
"name",
"age"
]
}

Notice we have added some constraints to the fields; min/max length to the name and min/max value to the age. The fields also have defined types.

With Machinable, we can create a new project called Pet Store, with a sub-domain “slug” of pet-store (note that project paths are globally unique). Within the project a new API Resource can be created with the URL path of /dogs and the schema above. The dogs of our Pet Store are then instantly accessible from https://pet-store.machinable.io/api/dogs (the access configuration for this path is currently disabled, so feel free to play around with it).

We can now perform simple CRUD operations on the dogs resource, which will validate our data:

$ curl -s -X POST -d '{"name": "Murphy", "age": 3}' https://pet-store.machinable.io/api/dogs
{
"_metadata": {
"creator": "anonymous",
"creator_type": "anonymous",
"created": 1582744738
},
"age": 3,
"id": "6dcdb8bd-6076-40ce-bff2-1e3b99414832",
"name": "Murphy"
}
$ curl -s https://pet-store.machinable.io/api/dogs
{
"count": 1,
"items": [
{
"_metadata": {
"creator": "",
"creator_type": "anonymous",
"created": 1582744738
},
"age": 3,
"id": "6dcdb8bd-6076-40ce-bff2-1e3b99414832",
"name": "Murphy"
}
],
"links": {
"self": "https://pet-store.machinable.io/api/dogs?_limit=10&_offset=0"
}
}

Here’s an example with an error response describing invalid value(s):

$ curl -s -X POST -d '{"name": "Max", "age": "seven"}' https://pet-store.machinable.io/api/dogs
{
"error": "failed to save dogs",
"errors": [
"age in body must be of type integer: \"string\""
]
}

Web Hooks

Now that we have an API Resource, perhaps we need to know when an object is created, edited, or deleted so that we can perform some other custom operation.

Web Hooks can be configured to send events to custom endpoints when API Resources or Root Keys are created, edited, or deleted. Use Web Hooks to callback to your server in order to implement custom business logic for your app.

New Web Hook for Dogs (with custom header)

If we were to create a Web Hook to trigger on creation of a dog, Machinable would POST the following payload to the configured URL:

{
"entity_key": "dogs",
"entity_type": "resource",
"event": "create",
"payload": {
"_metadata": {
"creator": "anonymous",
"creator_type": "anonymous",
"created": 1582744738
},
"age": 3,
"id": "6dcdb8bd-6076-40ce-bff2-1e3b99414832",
"name": "Murphy"
},
"project_Id": "02327c9f-b523-45b6-b8a1-4cd47565aeba"
}

You can then perform whatever business logic required.

If needed, Web Hooks can be disabled for a single request by setting the X-Trigger-Hooks header to false. This may be useful if business logic needs to perform CRUD operations without triggering an endless loop of hooks…

Documentation

Since API Resources are already described with JSON Schema (and Key/Values are just objects), the OpenAPI specification is compiled and made available to you and your API users. The OpenAPI specification can then be used to write your own backend using the same HTTP Interfaces made available by Machinable or automatically generate clients and UIs.

OpenAPI Doc by Redoc

Machinable provides hosted documentation using Redoc. Redoc provides dynamic documentation of your Project’s API using the OpenAPI specification document.

Other Features include:

Key/Value

Key/Values are JSON objects, where the full object is accessed by the Root Key. Each layer of the JSON structure can then be accessed, and edited, with HTTP path parameters as keys/indices to the JSON.

Access Tools

Project Access provides tools to create and manage Project Users and API Keys. These two entities are how someone or something interacts with the Project data stored for an API Resource and Key/Val.

Security Tools

The security page provides request logs, made by project users as well as project administrators, and active project user sessions, which can be revoked if needed.

If you would like to self-host or just view the tech stack, check out the Github org here:

I created Machinable as a way to quickly bootstrap my projects’ storage, REST APIs, and user management. I quickly realized that if this was useful to me, it may be useful to others as well.

The Machinable stack is a constant work in progress, so if you have any feedback, problems, or comments regarding Machinable please open a GitHub issue or send me an email at nick@machinable.io

https://www.machinable.io/documentation/

Nick Sjostrom

Software Engineer who enjoys building things and learning.