 Welcome. So great that you are here at our talk. So happy to be here. I don't expect this room to be this big. So great that you are here. Before we start, we want to ask you three questions. So please raise your hand if you have heard today maybe about Dapper before. Who has heard about Dapper? Yay! Who has heard about WebAssembly before? Okay, great. Amazing. And who has ever thought about using these both technologies together? Thank you guys in the first row. Okay, so if you don't know about Dapper or don't know about WebAssembly, you will learn about it today. You will learn why we think these technologies are better together. And we will show you some blueprints on how to connect these technologies and basically build your use cases with this stack. My name is Sven Fennig. I'm a Principal Consultant for Software Engineering at Liquid Replay. And, yeah, I'm working mainly on cloud-native application development for hybrid and multi-cloud applications in environments. And I'm also in tech lead of the working group WebAssembly in the tech runtime and founder of an open-source project and co-maintainer called K-Wathom. This is a logo if you want to learn more about it. We have a website. I have my awesome colleague Christoph with me who can introduce herself. So, please. Yeah, hello and also welcome from my side. My name is Christoph Vogt. I used to do a lot of infrastructure. I used to do a lot of software development. And now I'm also trying to develop a consultancy called Liquid Replay. I'm also active member of the working group Wathom as a subgroup of the tech runtime. And today we will talk about applications because I think most of you will have and run some kind of application. And what we want to achieve today, I would like to explain with a simplest example. So, we have an image processing service which should count the number of kittens of an image that we process. So, if we write an application, what would we need? Of course, we would need a service which is handing the request, right? You can post the image to our server. And the server then forwards this to some kind of image processing library which can do the image detection to detect that there are actually some kittens on the image. Plus, I need some business logic in order to do something with this information, right? This something can be arbitrary complex. But in our case, we definitely want to store the amount of kittens in a database. What do I need in order to access or to store something in a database? Of course, I need some kind of client which can be different from language to language, right? But the client is crucial and important in order to not only maintain the connection to the database but also like to store our information. But what if now I want to change my database? All of a sudden, I would need to adjust my application code. I would need to introduce yet another library that is able to communicate to this new database, right? What if I want to do additional authentication? There would be yet another library as part of my stack that is not yet even an image. And what if I want to write a similar app? Like a similar app which is actually a web server, has some business logic but maybe just processing different things. In this specific case, I would reinvent the entire wheel and need to rewrite a lot of code. So introducing Dapper, which helps exactly with this issue. Dapper is the distributed application runtime and it's an open source project and actually pretty widely distributed already and has a lot of stars and github, so definitely check it out. And it provides a set of building blocks that developers can use to build scalable, resilient and cloud-native applications with the goal that the dev itself doesn't need to deal with the intricacies of the complexity of cloud-native environments. And Dapper provides various building blocks. You see them all here in the row. Most importantly for now are the building blocks of state management because Dapper contains a set of libraries that know how to talk to various sets of databases. So for instance, it contains a library to talk to a PostgreSQL database as well as it knows how to talk to a MongoDB database. All that I would need to do is change some configuration on the Dapper side. But the actual application only communicates to the database through Dapper. Of course, Dapper also adds a lot of other building blocks that most importantly pops up. A lot of observability stuff, authentication, it adds things for secret management, a lot of stuff that you usually need in cloud-native applications. It's designed to work in any kind of environment, so it doesn't make any kind of assumptions that you are actually running in Kubernetes. But of course, it's nice to work with this in Kubernetes. So adding Dapper to the equation, our architecture would look something like this. So we have a Dapper, for instance, as a sidecar. And Dapper basically takes over the communication to the database. And my actual application only needs to know how to talk to Dapper, but it doesn't need to know how to talk to the specific interface of the database anymore. So what did I achieve with this change? The benefits are, of course, I can change my database, which means if I was on Postgres, I now need to change the configuration only on Dapper side and I can use, for instance, MongoDB or any other support in the database. And Dapper can also handle authentication for me. So this means, Dapper itself provides means to do OAuth, so I can add it to my actual identity provider and authenticate the request that I have. But what if I want to write a similar app? There's still a big chunk of the app that I would still need to rewrite. And yeah, that needs to be improved here, right? So this is where we propose WebAssembly. And we think that WebAssembly would be a very good thing. But what is WebAssembly actually? So WebAssembly is the first and foremost a compilation target. So if you right now have applications and you compile it, you most likely compile it for a certain processor architecture like x86 or ARM, and there would be now a new compiler target called WebAssembly. And what it does basically is that WebAssembly, or WebAssembly itself is like a binary instruction format for a virtual machine. And it is an abstraction for the processor, so to say. And WebAssembly has been developed with like 12 design goals, but I would like to highlight four which are most important, like prominent for our use case. So on the one hand side, it's extremely portable. So it does not make any architectural assumptions that are not broadly supported across like modern hardware. So it claims to run on any, or you can compile it in any kind of hardware. It can be compiled on all kind of architectures, like be it desktop, be it mobile or any kind of meta systems. And it can be integrated in browsers, as you might know already, as well as for like standalone VMs or other integrated environments. One great use P is like it's safety promises. The code executes in a memory safe sandbox environment, preventing data corruption or security breaches. It embraces a security model that's called a capability based security model that you're most likely familiar from your mobile devices. So if you want to give an application or a lot of application, if you want to give it access to your photo roll or camera roll, you explicitly have to allow this. And this is basically exactly this capability based model. WebAssembly is fast. It claims to be like near native from a code performance perspective, which basically means that if you compile your code to JavaScript, it will be as almost as fast as JavaScript, but not faster. And it's a polyglot in the way that it does not privilege any particular language or programming model. And it's basically up to the program language tool chain to implement the spec to WebAssembly. So how do you interface, how do you work with WebAssembly conceptually? So let's assume I want to create a function, which is adding always plus one to a parameter. In any language, I would compile this to WebAssembly. The result is WebAssembly module. And I can take this WebAssembly module, this output, and load it into another application that has a WebAssembly runtime. In the process of loading this into the runtime, we create the security sandbox that I was mentioning, which basically means that I would explicitly need to allow any kind of IO that I want to do between the guests, like the WebAssembly thing or the host. And the beauty of this is actually that I can compile this wasn't module once and give it to, I don't know, the other department or to my colleague, and all of a sudden he has this compilation result and can use it in this exact own application without recompiling it. He doesn't even need to know in which kind of language it is written. He only needs to know what it does. And that's pretty cool, right? Because, yeah, this would basically actually allow to share libraries, for instance. But now let's compare like the goals of Wasserman Depper, because the goals are actually very similar, and both of them try to avoid the boilerplate code and try to foster code reuse. So this means like less code that I have to reinvent in a way, creates more reliable architectures, and this also means like less bugs to introduce, right? Adding Depper to your architecture is relatively lightweight, so is WebAssembly in terms of additional costs at runtime, and both aim to give a developer the freedom of choice. So both of them try to make a minimum set of assumptions of what kind of language, what kind of tool chain, what kind of architectures you actually run on, and they try to be very flexible in a sense. And, yeah, both add on security, but they do all of this on different levels, as you might already notice. So our claim is basically that we want to use WebAssembly together with Depper, because we want to use WebAssembly for its runtime specifics, its security, its speed. And with Depper on the other hand side, we get interfaces to all this kind of neat services, and we additionally get things like observability, authentication, and all this kind of things, that I would otherwise need to develop on my own in this new application. Plus, to everyone who is familiar with WebAssembly, the ecosystem is still developing, so Depper definitely also helps to overcome a lot of shortcomings that WebAssembly has right now. So if you want to use it right now, this is a very good bet to work with. So how would our application look like if we would integrate both technologies? So this would mean that I would add either libraries or a kind of handlers, and write and compile them to WebAssembly, which means that now, all of a sudden, I can reuse the actual host, the majority of my actual application, and only would need to reinvent the actual business logic on this side. And this is basically the promise of the very nice thing that we think is definitely worth investigating, and Sven will now show you how to actually connect both technologies together. Thank you, Christoph. So, yeah, we will now have a look on how exactly connect WebAssembly with Depper. We thought about a lot of use cases, and not every use case is looking like the other. So you have different architectures in terms of WebAssembly. You have different run times. You can use a lot of languages, and a very important thing about your application is the invocation characteristics. So how is your application being called, and how often is it calling another application? When you deploy your application to a platform, for example, Kubernetes, you can do a lot of choices. Like, in terms of Depper, do you want to deploy it as a sidecar in shared mode? Do you connect via HTTP, GRPC? Do you have a WebAssembly standalone run time, or do you embed it into a bigger application? How do you do scaling? And we want to give you a starting point where you can still do these choices based on what's best for your use case. What we came up with is a blueprint. So in contrast to a pattern where you have a specific problem in mind and you can just apply the pattern, the blueprint is a starting point that you can easily adapt to your specific needs. So we have four points here, considerations. So what do you need to consider when you are applying this prerequisites? What do you need to apply this blueprint? Most important, variations. So what choices can you still make and how you can adapt it? And limitations. So when should you not do that? The first thing is something... Yeah, I would say something to easily get started. Depper already ships with an WebAssembly run time on board. You don't need to do anything. You don't need to deploy something besides Depper. You can just use Depper. It's initially created that you can easily customize your Depper without recompiling it and redeploying it. Things you need to consider. So Bozio is already there. You can host pure functions, for example, for transformation or validation. So you already have a validation logic. You can compile it to WebAssembly. You can host it on Depper and it says okay or not okay. As prerequisites, you need almost nothing than your Depper deployment, a function you can compile to WebAssembly and a way to bring your WebAssembly to your Depper deployment. In the variations, so it doesn't matter how you get your WebAssembly into the container. You can build it in an image. So you just put it together, deploy it. You can mount a volume. You can put your WebAssembly during startup. And you can still with this HTTP middleware do what it's supposed to. So do routing to filtering block access. So it's something where you can very easy get started and you have almost no entry barrier. Limitation is only for pure functions. So you need everything you need to do. You get a request. You can do something. You can write a response. And that's basically it. So let's go to something I would say more widely used, a microservice. So you can also write a microservice in your WebAssembly runtime. A microservice is a very common architectural pattern and almost all WebAssembly runtimes have the ability to start an HTTP server and do HTTP requests. For our case, that's almost... So that's the minimum requirement to connect to DAPR because the APIs are exposed via HTTP and we can just get started. So we don't need to have a database driver or something like that. We just can HTTP to DAPR and get the capabilities we need. With input bindings, we can also get caught with other than HTTP, for example, with a PubSub or the Kafka input binding and make our application available to those platforms. And we can scale with this pattern pretty well so horizontally like we love it in our cloud-native ecosystem. As prerequisite, we just need a WebAssembly standalone runtime that supports HTTP for client and server, which are at the moment almost all of them in one way or the other. So as variations, we have... Yeah, just being called by... The Wasm server is called directly and can use DAPR as a backend, but we can use every other capability as well so we can be called by PubSub, invoked our module, changing our state and giving back the response. So limitation is only when we need non-HGTP characteristics, then we would change our pattern slightly. Talking about that, if HTTP has quite some overhead, so if I have lots of trigger invocations, then HTTP may slow down a little bit the connection, but therefore, fortunately, DAPR has the ability to use GRPC. Unfortunately, most of WebAssembly one times don't have the capability to do GRPC. It's just a matter of implementation and that will change over time, but for now, we need to have something in between to get these features to work. Fortunately, WebAssembly is a great plugin system. So that is one of the use cases if you have an application. All major runtimes have SDKs for a lot of languages where you can just embed the WebAssembly runtime in your application and that's really one of the strengths. And what we can do with this is when we have a runtime with an SDK, a supported language, and we are willing to invest some development effort, we can create a very thin layer that just does the GRPC communication and expose the API to our WebAssembly runtime via host calls. As an example here, I have just a Rust application that is doing the GRPC calls and just forwarding it to our WebAssembly application and then accepting host function calls that are then mapped again. But what we also can do is that we have more logic in our application like we can have a local state, we can do caching to even reduce the calls more than we would do now. The limitation in this case is that we would need to have some more implementation effort. So what do we say? Is the combination of DAPR and WebAssembly something that I would say really lives up to its promises? You can already start with very, very few boilerplate code and just have the standard case of a microservice and communicate with DAPR like you would do with any other technology that is not a WebAssembly. But you can, with a little more development effort, really gain all the advantages you have right now and are not available in the WebAssembly ecosystem right now. Especially observability is a really, really huge thing because enabling observability in pure wasm has some overhead and repetitive code, what we don't want to. And here DAPR really brings a huge value. And you're still very flexible, so you can build architectures. You are familiar right now and switch over to WebAssembly and gradually shift to a more functional-based approach and make use of all the future innovations that WebAssembly brings, like the component model, but this is not the WebAssembly date. So what it's good for? It's good for cloud-native architectures. So that really works well. What's not so good for? If you have very highly specialized UDP protocol or do want to do system programming, you may choose another tool. Where do we go from here? So unfortunately, 25 Minutes is not really enough to give like an entire demo, but our friends from Second State created a course on running WebAssembly together with DAPR. They published it together with many publications. Furthermore, you see this Git repository, so they also have a couple of examples of how you can actually do this, so you can definitely work through them. And by the way, we are also working on a DAPR and WebAssembly course, so stay tuned for this and follow our socials. And if you want to learn more about WebAssembly or the WebAssembly and Kubernetes combination, so there are more ways to run WebAssembly on Kubernetes. So if you want to learn more about the core technology, there's a very great course of our friends from Siebel Cloud. You'll see the link here. And also if you want to learn more about our work, what we are working on, we just last week released a tool called SpinCubed, or basically we contributed to this tool. And if you want to learn more about this tool, there's a presentation during KubeCon by Matt Butcher, the inventor of Helm, who is the CEO of the company, who also created this tool.