This tutorial covers:
- Getting set up the first time.
- Implementing a simple little system with three services.
- Hooking the services up to the event system.
- Testing the system locally.
- Deploying and securing everything in mist-cloud.
This tutorial is intended to quickly get you set up and ready to play around with mist-cloud, locally and in the cloud.
Before we dive in, let’s briefly look at the basic model of how the mist-cloud platform works with your software. You write some code, then push it via Git to mist-cloud, where it is packaged and deployed onto our servers (yellow path). When end users, IoT devices, or other external clients sends a request to mist-cloud the code is executed (blue path). Optionally your code can send replies back (green path), like in a server-client setup.

Currently, all administrative tasks in mist-cloud are performed through a command-line interface (CLI). We use NodeJS’s Package Manager (npm) to install the mist-CLI, and all code is managed with Git. If you do not already have npm and Git installed follow this guide.
Open PowerShell and run the command:
npm install -g @mist-cloud-eu/mist-cli
This command uses NodeJS’s Package Manager (npm) to install the mist-CLI, globally (g), i.e. accessible from any folder on the computer.
Verify the installation by running the command:
mist version
1.4.1
From here, if at any point you get lost or stuck try running the command:
mist help
It usually has good suggestions for the next steps at the bottom of its output.
We use the mist-CLI to set up a new user account. During this process, we are guided through creating an RSA key pair and adding the public key to our mist user account.
mist login [your email]
Press enter to generate RSA key-pair, or enter a public key manually: Verification email sent to [your email]
After we click the “verify” link in the email, our account is created.
To verify that everything is setup correctly try running this command which should give an empty output:
mist list-organizations
[]
Showing that we haven’t got access to any organizations yet. Let’s create one!
Everything in mist-cloud has the same basic structure: Users and services belong to teams, which belong to organizations. Therefore we need to create an organization:
mist org [organization name]
mist commands do not change your working directory, so to work with an organization you also need to change the directory:
cd [organization name]
If you have a danish CVR number you can from this point forward sign up for early access at any time with the command:
mist sign-up-for-early-access [danish cvr number]
As mentioned before, services can only be owned by teams. Every organization has a default team. All we need to do is go into its directory:
cd default
We are now ready to start writing some code.
We can now create our service.
mist service [service name]
cd [service name]
For this example we implement a system with 4 parts:
hello or hola event containing a name in JSON format as its payload.hello events and posts an intermediate event.hola events and also posts an intermediate event.intermediate events and posts a reply event.💡 We have made up the
hello,hola, andintermediateevents for this example, but thereplyevent has special meaning in mist-cloud.replyis the only reserved event type.
For simplicity services A, B, and C are in the same service repository. You can download the source code in your favorite programming language here:
git pull https://github.com/mist-cloud-eu/ts-template
git pull https://github.com/mist-cloud-eu/js-template
git pull https://github.com/mist-cloud-eu/go-template
Because we have mixed two git histories we also have to run:
git pull --rebase
The service templates share similar structure:
rapids define a nice interface for posting to the rapids.english, spanish, interm.app file maps actions to code and parses the envelope’s payload then calls the appropriate business logic.Finally, build the service with the command:
mist build
The mist.json file maps river/event combinations to actions, which are defined in code. We have three services in this repo so our mist.json should have a hook for each, mapping to the appropriate action.
{
"hooks": {
"english-river/hello": "english-action",
"spanish-river/hola": "spanish-action",
"common-river/intermediate": "intermediate-action"
}
}
Since all the events are different (hello, hola, intermediate) the rivers have no effect here. Rivers only come into play if multiple services want to handle the same event.
By default, everything in mist-cloud is protected, and inaccessible to the outside. So in order to allow part 1 from above:
- A client posts either a
helloorholaevent containing a name in JSON format as its payload.
We first have to expose the hello and hola events.
We do this by registering them in the event catalogue. That is, in the api.json file in the event-catalogue folder of an organization.
{
"hello": { "waitFor": 5000, "replyCount": 1 },
"hola": { "waitFor": 5000, "replyCount": 1 }
}
In the event catalogue we also configure how the API should behave, in particular, its maximum wait time (waitFor 5000 milliseconds = 5 seconds) and how many reply events we expect (replyCount).
We can now start a local version of our entire system by simply running the command:
mist run
This command finds the mist.json files from all the services we have checked out and simulates the Rapids-Rivers setup. It only uses local information, so this works offline as well.
While the simulator is running, we can trigger our service by opening a second terminal and running the command:
curl --silent -X POST \
-d "[Your name]" \
http://localhost:3000/rapids/hello
Whatever we put after /rapids/ is the event type, and what we put after the -d argument is the event’s payload.
There is a lot of stuff happening when we trigger the system. So let’s go through it in detail. To make it simpler we have segmented it when each event enters the Rapids. Unless otherwise stated the simulator and cloud function identically.
POST request to mist-cloud with an API key (ie. xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx), an event (ie. hello), and a payload (ie. "John Smith").
curl --silent -X POST \
-d "John Smith" \
https://rapids.mist-cloud.io/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/hello
5000ms) and reply count (ie. 1) configuration from event-catalogue/api.json, then puts the event on the Rapids.
{
"hello": { "waitFor": 5000, "replyCount": 1 },
...
}
english-river.mist.json.
{
"hooks": {
"english-river/hello": "english-action",
...
}
}
mist.json (ie. english-action).It runs the appropriate code, which posts a new event to the Rapids (ie. intermediate). Then the service shuts down.
Notice that no security check is performed here. Services post events directly to the Rapids.
common-river.mist.json.
{
"hooks": {
...
"common-river/intermediate": "intermediate-action"
}
}
mist.json (ie. intermediate-action).reply). Then the service shuts down.It took a bit of work to set up this system because it involved first-time setup which only happens once and security configuration which rarely changes after it is set up.
First-time setup (only once):
mist login [email]mist org [name]Security configuration (rare):
event-catalogue/api.json.mist role Developer --user [email]mist deploymist key [duration]mist event [event] --key [key]Implementing code (common):
mist service [name]mist.json.mist buildmist runmist deployThat’s it. You’re all set to start playing around on your own. Some interesting questions to explore in no particular order:
english-river/hello but replies directly. What if we use a different river? What if we increase the reply count for hello?And just a reminder, if you have not done so already you should sign up for early access with the command:
mist sign-up-for-early-access [danish cvr number]
More to explore: