Blog post cover image

Getting Started

Sailhouse is currently not available for public access, but will be soon! 🎉

Sailhouse is a platform all about the developer experience. It’s optimised to move quickly, with confidence, allowing engineers to focus on the product, not the tooling.

Sailhouse is split into verticals called “apps”. These are flexible enough to be anything you would want to use.

  • Environments (production, staging or even isolated dev environments)
  • Individual applications
  • … I’ve run out of ideas

Everything happens within the context of an application, subscriptions live on topics, topics live on apps etc.

> sailhouse apps list
sailhouse-staging
sailhouse-production
sailhouse-demo

And you can create a new one really easily

sailhouse apps create lets-go

Schemaless development

Schemas are a core, and powerful, tool available to developers on Sailhouse. However, flexibility is paramount, even on an opinionated platform.

Using the CLI

Both topics and subscriptions can be created easily from the command line.

Let’s create a topic called project-added.

sailhouse topics create project-added

In our demo scenario, every day we want to fetch the latest projects added and send a slack digest, so let’s create a slack-notification subscription.

sailhouse subs create project-added slack-notification

By default, the CLI runs against the currently selected app and team, but this can be easily overriden with the --app and --team global flags.

And there you have it, a topic and subscription set-up and ready to go!

Self Healing

Sailhouse offers self-healing on topics and subscriptions, making it possible to develop an application without even touching the CLI.

When an event is sent to a topic that doesn’t exist, such as project-added, Sailhouse will automatically create the topic and store the event.

Likewise, when you attempt to pull events from a subscription that doesn’t exist, Sailhouse will create the subscription and back-fill events sent within the default_window property you define in the getEvents(...) call.

Although not advised for production, this is great for rapid development which can then be backported to a schema for more a more maintainable infrastructure.

But I want a schema?

Then you’re in the right place!

Sailhouse schemas can be “sharded”. This means, you can split definitions over several files, repos, git providers, even source control software! I’m kidding on the last bit, don’t do that.

Each Schema has a key, a short string used to say “Hey, all resources with this key belong to me”. This is how you can create, delete, update resources with relatively complex dependencies. The ownership is split, and the platform doesn’t let you delete if there are dependencies.

key="main"

[[topics]]
slug="project-added"

[[subscriptions]]
slug="slack-notification"
topic="project-added"
type="pull"

[[subscriptions]]
slug="update-billing"
topic="project-added"
type="push"
endpoint="https://project.app/hooks/add-project-billing"

You may have expected subscriptions to live under topics. But as we mentioned earlier, schemas are sharded, and therefor considered partial. To give the most flexibility, both topics and subscriptions are top-level arrays on a schema file.

Working on Netlify

Sailhouse was built with serverless in mind. It’s not a case of it only working with severless, but it’s an area that benefits a huge amount from the DX improvements offered by Sailhouse.

import { SailhouseClient } from '@sailhouse/client';

const client = new SailhouseClient();

export const handler = async (event, context) => {
    const { repo, name } = JSON.parse(event.body);

    await client.sendEvent('project-added', { repo, name });

    return {
        statusCode: 200
    }
}

Let’s say, every day we want to pull all the new projects created and send a slack message notifying us of how many.

import { SailhouseClient } from '@sailhouse/client';
import { schedule } from '@netlify/functions';
import { sendSlackMessage } from '../utils';

const client = new SailhouseClient();

interface ProjectAddedEvent {
    repo: string;
    name: string;
}

const dailySlackSummary = async () => {
    // Fetch all unacknowledged events on the
    // "slack-notification" subscription
    const events = await client.getEvents<ProjectAddedEvent>(
        'project-added',
        'slack-notification'
    );

    const count = events.length;
    const names = events.map(e => e.data.name);

    await sendSlackMessage(
        `We have ${count} new projects! ${names.join(" 🎉\n")}`
    );

    // Acknowledge all the events we've just processed
    await Promise.all(events.map(e => e.ack()));

    return {
        statusCode: 200;
    }
};

export const handler = schedule("@daily", dailySlackSummary);

Making use of Netlify’s Scheduled Functions it’s trivial.

Fin

And that’s Sailhouse 101! Truly, that simple.

If you want to get in early, reach out over email or reach me on twitter.

hello@sailhouse.devTerms of UsePrivacy PolicyFair Usage PolicyStatusChangelog