Ihr Browser (Internet Explorer 10/11) ist veraltet. Aktualisieren Sie Ihren Browser für mehr Sicherheit, Geschwindigkeit und den besten Komfort auf dieser Seite.
About us
wolkenkit-boards logo

Portrait of Matthias Wagler
Matthias Wagler


Boards in the Clouds – Part 4: Building the client

So far, we’ve had the idea to digitalize our white boards, we’ve shaped and modeled our domain using domain-driven design, and then we turned this domain into a real-time API. One last important thing missing here is a user interface that lets us attach post-its to our digital whiteboards, so let’s talk about how we’ve built the client that actually talks to our wolkenkit backend.

What do we want to build?

Just like in the previous step, let’s first spend some time talking about what we actually want to build. We want to have a screen where people can mount new boards because we don’t want to limit ourselves to just brainstorming about Monday meetings. Each board has a unique link and can easily be shared with other people by sending out a link.

Mounting a new board

Once you click on a board, you’re taken to the board screen showing all of the post-its attached to it. What we really like about the post-it metaphor is the fact that post-its have limited space, so you actually do need some focus when noting down thoughts on them. That’s something we wanted to preserve in the digital version. The post-its should autosize themselves to a certain height, but they should definitely not invite the user to write large amounts of texts – only brief, quick thoughts. But we also wanted to extend the digital version: you can add links to them, and you can simply drag images from your desktop and drop them on a board. We truly believe that work should be playful, so we thought about adding a very subtle physical behavior to the post-its while dragging them around.

But how do we actually turn these concepts and ideas into code? And how does wolkenkit support us in achieving this goal? Technically speaking, we’re going to build a single-page application using JavaScript that uses the wolkenkit-client SDK to connect to our backend. The SDK brings the API that we’ve modeled into the client. It dynamically generates the objects we’ve modeled in the backend (the aggregates, commands and lists) for us on the client side. So we’re able to use the exact same language on the backend and the frontend without having to translate between different abstractions or technical layers in between. There’s a lot more detail involved in the UI architecture, but to keep things simple we’ll focus on the most important steps in our application lifecycle. Once this blog post series comes to an end, you’ll be able to dig into the source code.

Connecting using the wolkenkit client SDK

The first thing we need to do is to integrate the wolkenkit client SDK into our project. We install the wolkenkit-client package with the help of npm and import it into our project. Then we can connect to the backend using the default host and port for local testing. Please note: we’re using a compile step so that we can take advantage of modern JavaScript features and transpile it down to good old JavaScript so that older browsers still are able to keep up.

import wolkenkit from 'wolkenkit-client'; const api = await wolkenkit.connect({ host: 'local.wolkenkit.io', port: 3000 });

What we get back from this function call is an application object, which we’ve called api. Through some nice magic inside of this connect function, the app contains all the objects we defined in the readModel and writeModel folders of our wolkenkit application. Now we can start using them to reach out to the backend.

Mounting a board, a.k.a. writing

So the first thing we’d like to do is to mount a new board whenever somebody hits Enter inside the dialog for mounting new boards.

In order to do so, we trigger some handler code whenever the form is submitted by the user. Our application is now able to use the api object to send the mount command to a new board.

api.collaboration.board().mount({ title }). await('mounted', event => { // Show success notification });

The client SDK contains some helpers to deal with the asynchronous nature of commands and events. For example, the await function lets us wait until a specific event occurs in response to a sent command. An additional timeout handler can be used to trigger logic if the event doesn’t occur in a given amount of time. There are a lot more details to discover, and you can read about them in the wolkenkit documentation on sending commands.

Now that we’ve changed the application’s state by sending a command, let’s look at an example of how to read this state.

Observing posts in real-time, a.k.a. reading

One example for reading application state is fetching the list of all the posts for the active board. Obviously this is something we would read more than once since we would like to stay up-to-date while people are collaborating. Luckily we don’t have to worry about this – wolkenkit lets us read and observe read models. Whenever something changes inside a list read model on the server, our app will be informed about that change. We simply have to re-render our user interface.

api.lists.posts.readAndObserve({ where: { boardId: state.activeBoardId } }). started((posts, cancel) => { // render our ui }). updated((posts, cancel) => { // re-render our ui });

The api object therefore contains a context for lists. We can use it to reach out to the list of posts and call the readAndObserve function. Again we get some async helper methods (started, updated and failed) to subscribe to the lifecycle of a list. The most important thing to note here is that inside the updated callback, we get an array of posts that we can use to re-render the board. There’s a lot more information to discover about reading lists over at docs.wolkenkit.io. But for now let’s just see how it feels inside our app…

While we’re issuing commands, e.g., we’re attaching a post to board, we’re moving it around, our list of posts gets updated for us. These are two of the most important parts of our client. We’ve come a long way and built a simplistic single-page application that talks to our backend running in the cloud. In the next part of this series, we’ll sum things up, see what we’ve learned so far, and release the source code.