 Hello, everyone. Welcome to Cloud Native Live, where we dive into the code behind Cloud Native. I'm Annie Telasto, and I'm a CNPS ambassador, and I will be your host tonight. So every week, we bring up news that are for centers to showcase how to work with Cloud Native technologies. They will build things, they will break things, and they will answer all of your questions. So you can join us every Wednesday to watch live. So this week, we have Mikkel here with us to talk about building serverless applications using spin and web assembly. Very excited for the session. And as always, this is an official live stream of the CNC app, and as such, it is subject to the CNC code of conduct. So please do not add anything to chat or questions that would be in violation of that code of conduct. So basically, please be respectful of all of your fellow participants as well as the centers. With that done, I'll hand it over to Mikkel to kick off today's presentation. Thank you, Annie. And thank you for having us here. My name is Mikkel Markinoy, and I work as head of product and developer relationship at a company called Fermion. And at Fermion, we build what we believe is the next wave of cloud computing. And part of what I'm going to talk about today is how we use web assembly to power that movement. And in particular, our open source framework called spin that I will be introducing you to and demonstrating some applications. So let's dive into this. I'm going to start out talking a little bit about web assembly and why we believe that web assembly is a good fit for sort of the next wave of cloud computing. So I usually come up with this thing about when people ask about what web assembly is and trying to figure out what are sort of the three most important things that you should know about web assembly, which was a challenge I gave myself. And I ended up with a list of five and eight and 10 things. It's really, really hard to get it down to three, but here's what I got to. First of all, what you need to know about web assembly is that it is a specification and it is a specification of a binary instruction format, which is designed as a portable compilation target. Now I'm going to unfold that in a little bit. So we all sort of get a level set on what all that means. And I believe the third most important thing to know as you are going to listen in for the next hour or so is that if I at any point in time say wasm, it's the same as web assembly. It's just does not a name. Basically, it's the file extension we use for web assembly. And so wasm web assembly will be used interchangeably by me. So don't be don't be thrown off by that. So there might be a lot of other important things to know about web assembly, but at least this is a place to start. And by the way, if you want to read about web assembly, there's a link here to web assembly.org that'll help you get some more understanding about the specification and how the work around the specification is going on. So when we talk about this portable compilation target or the bytecode format, what, what does that really mean for web assembly? Well, when we walk, we don't want to walk you through sort of the symbol, the three simple step that that is part of getting from the code you write into running that code in this bytecode format that is the web assembly. So first of all, you start out with some code that you write and you can write this code in a lot of different programming languages. And I'll get back to that a little bit in terms of what type of support we have across various types of programming languages. But as the compilation happened for the code, the code combined compiles into this bytecode format or into the web assembly. Now it's language specific how this happens today and there are at least two ways of doing this and there's probably many more ways depending on languages. And this is sort of, you know, state of the ecosystem here in the maturity of web assembly is also that this is continuously improving, you know, and new languages are coming in with more support. But that is sort of the first step that needs to be done. Now that we have our bytecode format, the web assembly, the compile code, we need to run that. And the way that that works is that we have a virtual machine that runs our web assembly. Now this is this is very similar to how things like the JVM is working that used to work still works today, and many other scenarios. And this is where we need a web assembly runtime is basically what will provide that VM for web assembly. The way that you run these web assemblies and the various web assembly runtimes that are out there. There are sort of two two branches to this. And one of them is dependent on JavaScript. And that's when you want to run web assembly inside of the browser. The other one is not dependent on JavaScript, which is also sometimes referred to a server side web assembly. And there are a lot of different ways of doing this. And all of that depends on the various web assembly runtimes that you choose to use. That will sort of take you down different different paths. So to get a better overview of this whole what's the state of support with languages when running inside the browser web assembly or running web assembly in other places or using something called wassy, which I will expand on a little bit later. We at Fermion, we have created this language guide that can help you give a good overview of the state of the individual languages. So if you head over to fermion.com website, you'll be able to find a link to the language, the wasm language matrix. And that will sort of give you a good idea and you can dive into the state of these, these individual languages. Okay, but diving in a little bit into this whole runtimes and virtual machines of web assembly. Now I mentioned something about being dependent on JavaScript and not being dependent on JavaScript for running inside the browser or outside of the browser. So there are these two, there are these two different types of web assembly you can sort of call them on the JavaScript runtime site. These are designed to complement and are along run alongside JavaScript to share functionality between JavaScript and web assembly. This is this is where web assembly comes from. This is what web assembly was originally designed to help solve basically enhance the experience you can build inside of a browser by enabling other programming languages to be used to write applications for in browser experiences. And this has been around for, for many years, I believe web assembly as a specification was originally from 2017 or something. So it's been some years where web assembly has been used inside of the browser. So if you are in that world of writing web assembly for the browser, the web assembly runtimes that you use would be either v8 or spider monkey that are used inside various browsers. You can see Google, Firefox and the, the edge, the Microsoft Edge being called out here. And also if you have frameworks like node and denote to run on the server side, which uses v8, you're able to do similar things with web assembly. But the thing is that you, the way that web assembly would interact with the API's inside those engines through JavaScript API's. So there's always JavaScript in there, sort of as a kind of glue code intermediate between your web assembly and the API of the browser. Now, on the other hand side, we have this thing called wassy runtimes. And this is, this is, this is, wassy has come in a little bit later and was is still a preview specification. But wassy as a sort of specification on top using web assembly is designed to be independent of browsers. Right. So we don't depend on web API's or JavaScript. And we are limited to need by the needs to be compatible with JavaScript. So there are sort of wassy compatible runtimes out there. And there are many mores that the ones I've listed here wasn't time which is built by bytecode alliance is one of those. There is was more and there's wasm edge, which is a CNCF project as well. So these are all runtimes where you can run web assembly without having that tie into JavaScript. And wassy is what we have based our framework spin on top of. So just to give you a quick idea of how this, how you can, you know, take Rust and JavaScript and combine in the browser. What I'm showing you here is some Rust code. And what I really want to call out is that you can see how within the Rust code I'm able to call into a set of API's that should be quite familiar. If you know about web development, you know, how you can get to a document and a document body and you can create HTML elements directly from your Rust code and basically set some inner HTML saying hello from Rust. And all of this you can do, you can do in Rust as well as you can expose some functions like here's a calculate function that takes two numbers and adds them together and returns the results. Now, if I wrote that in Rust compiler to WebAssembly, then I could write some JavaScript code that basically imports the calculate function that you have over here and also my main function to the init. And then I'm able to, you know, run that init function to have my Rust code type stuff into my browser window and I'm able to call my Rust function from within my JavaScript. So you can sort of see how these things work together. And part of compiling this in the tool set that you would use will produce sort of these intermediate, intermediate JavaScript glue code that's needed to, you know, get the JavaScript and the Rust to work together. So that's just sort of you get this idea of like WebAssembly in the browser has, you know, has this path and the way that you can then from within your JavaScript call into these functions being exposed by WebAssembly's written in other programming languages. So, focusing in on Wasi and the server side part of WebAssembly. So Wasi is what it's called a system interface. So it's a WebAssembly system interface for WebAssembly platform. And basically, what Wasi sets out to do is to enable code that's not running inside the browser to be able to talk to a conceptual operating system. Like you need access to files, sockets, clocks, random numbers, many more things. So these types of resources that you would expect an operating system to provide with of which are different things that what you would expect a browser's environment to provide to you. And the reason why talk about this as a conceptual operating system is because because because of the portability right is not talking directly to the operating system. Otherwise, we have to have, you know, we will sort of break the portability by doing that. And, and I think there's a point here in terms of why we believe that WebAssembly on the server side or WebAssembly is such a good, good specification or system to use for server side is that if you think about if you have to build an application to run inside the browser. There are at least four things or four things I think I typically think of that that we always have to think about. One of them is obviously portability, right? We need that code to run in various set of browsers, you know, different JavaScript engines running on different operating systems, different processor architecture, all of that, right? You want to write your code once and run it anywhere. That's why you write applications for the browser typically. Supportability is some of the things that that browser path takes us on. Another one is security, where, you know, because whenever you run code inside of the browser, it's always, you know, it's untrusted in the way that you can hit any random endpoint and it will basically just that server will give you some code. Your browser would happily execute it. Security settings set aside for a moment, but, you know, it's not it's not code that you can necessarily validate before you actually end up running, right? So you need the code to be executed in a highly isolated environment where it can't escape that browser and get onto your computer and do stuff and get access to that system, right? So you have that security model that's built in for browser frameworks for things running in the browser. The third one is the size of the binaries, because we always have to have the actual executable or the binary that we need to execute transferred across the Internet. Like we want to optimize the size of them to be small so that we can quickly get them there and execute them, you know, at the time we actually need them. It's not like we, I guess we use that once, like you come into a website, right? And you waited for something to download and install and then you could see your website. And that's, you know, we don't want that experience in the browser, which means that we want to have small binaries. And the last one is that, you know, fast startup time. They need to start immediately because, again, we don't want to have a website experience, a web application experience being dragged down by having, you know, things taking a long time to get up and running. So those four things are actually highly attractive for, you know, a lot of the stuff that we do in the cloud native world, like you have things that are portable. So build, run, run anywhere. You have things that are secure by default. They run in isolated sandboxes. You have things that are small binary sizes so they can quickly be moved around. And you have things that start up really, really fast. And so, so wasi is, is, is here to provide that conceptual operating system for those types of workloads that can sort of, you know, that have those capabilities. And that opens a whole, you know, range of scenarios that we can do much, much better in the world of cloud native development today than what we've been used to before. So that is really what wasi is about. And I think I've highlighted two here with portability and security. And we can, we can dive a little bit into the data if people are interested in that. And so feel free to ask questions as we go along if there are certain things you want to know, you want to know more about. Okay, that leads me to spin. I'm just going to take a sip of water here. And spin spin is an open source framework that we affirm you and have been built spin was two weeks ago, I think very recently released as a 1.0. And it is a developer tool for building web assembly microservices and web applications. So what, what do we mean by that? I think one of the things with with with web assembly is that it provides for a whole new set of experiences. And, you know, as I'm going to dive in now with the demo and show you spin. And as I noticed, Annie was saying in the beginning that I will break things. I'll see if I can live up to that promise as we go along with the live demoing. I hope that one of the things that you'll notice is that, you know, the vision of spin has really been to not necessarily get you into the weeds of web assembly because web assembly is a fairly can be a fairly low level thing. But we need to provide you a great developer experience, which because it's built on top of web assembly, it makes it, it's make it makes it, you know, a delightful experience to build applications. So, you know, rather than me trying to just praise things that you haven't seen or rather show that in action to you. So let me just start by doing some very simple Hello World introductions so that we can sort of see what this what this is. And then a little bit later we can dive into a bit more of a complex application that we want to build. Okay, so I'm in a terminal here and what I've done is I have downloaded spin. So actually let me go and show this to you. We have a, we have a site called developer fermion.com. And I am trying to get stuff over here so those links can be shared, which is basically the documentation home for spin. So here you can read about spin you can read how to install. There's a great quick start here. Michelle, one of my colleagues have given to sort of give you an introduction to that. And if you notice on the installation side that we run spin runs on Linux spin runs on max and runs on Windows, you can choose all of those those those operating system to use spin. But really what spin is about is just to make it really, really easy for you to write application. So let's do this. So what do you want to do if you want to do spin is you create a spin application you run a command called spin you. Now, what we're going to show you when you run a spin you command is that there's a set of templates that you can use to build applications with to build your spin applications with. Now, a few things that you might have noticed here that there's a lot of HTTP there's a little bit of redis there's some other stuff in here and then there's a wealth of different programming language like CC shop go JavaScript, and Rust, and so on and so forth. And this is, you know, because WebAssembly and the support across all these different programming languages you can within a spin application you can combine the various programming languages you want to use. You know, as your discretion it doesn't really I mean you can have a component and rust you can have part of it and go you can part of it in JavaScript. You can combine all of these together that is that is part of you know where WebAssembly is really powerful. The other thing to notice is the HTTP part or the redis part which are the two things that I just want to call out here. So the way that the spin application model work is it's an event driven model. You probably like you know functions as a service type of model that you know from services like lambda, which means that spin is built in a way where the ask and the developer who builds the application is to make a choice of what type of events. Your application supports so in this case it could be an HTTP request it could be a redis queue event happening. And then you write the logic to handle that HTTP request and you return something back. So we are setting this up in a way where you know there's very little boilerplate code for you to deal with and you can just you know get straight into writing that actual code you want to handle a request. So let me go ahead and try and start out with a JavaScript HTTP handler here and we can call this CNCF live demo app. And we can give it a description if you want to we can choose where in the URL structure we want to listen I'll get into that a little bit later. But now that we created this. Let me see where did we put this this and then in the CNCF live demo app. I want to show whoops does not want to do want to do trees that I want to show you what got created here. So we have, well, we have a read me file in there. But what we have is we have a few JavaScript specific things. First of all, we have an index days and we have a package JSON. So we're using npm as a way to handle dependencies within JavaScript. Have I chosen a have I chosen had I chosen a a template of a different programming language you would have seen sort of the tool chain for that programming language in there. So, so spin doesn't really, you know, we use the tool available for within that programming language to build to build your application. But what you also see in here is you see the spin file and maybe let's start out with that and then I can show you how a spin application is sort of is designed or structured. So here my editor, you can see the spin.toml file. The spin.toml file is that definition of a spin application. And the first six line here is basically just some metadata about the application. You can see there's a manifest version in there. There is the author name. I didn't provide a description. I could have done that. There's a name. You can see that this there is this the HTTP is defined as the trigger type in here. So when we talked about this as a function as a service or event driven, that is the trigger type defined in here. And then I can version my application as part of this manifest as well. And then you'll see I have a not having a ray down here. I have a table of components that that make up my application. So what happened as I did they spin new application is we created the first component. We gave it an ID, which is the same as the name of the application. And we can see there's a source. This is where the web assembly starts showing its its its face in here or come to the surface in that there's actually a wasm module or wasm file that will be running. Now, how do we get from a JavaScript to a wasm file? Well, we do that by running an MPN build command. So part of the spin application definition you can sort of you can, you know, you define how to hook into that, you know, developer or the language specific tool chain in terms of producing the web assembly module. So in this case, npm run build will be part of producing that web assembly. So let's actually start by looking at what's happening in that npm with that npm build command. So now I'm in my package json file and you can see this is the build command that will be running. And you can see we're doing some web pack stuff to create a module out of the JavaScript. This is this is specific to spin and specific to how we build an SDK for JavaScript in spin, how this works. Our JavaScript SDK is in an experimental phase at this point. Part of that is because the JavaScript compilation to web assembly works today, but it hasn't necessarily found what we think is the most optimal form. So there is, you know, there's some evolution going on here on the JavaScript side of things. But this is how we do this today and this is specific to the to the spin SDK. And then what we do is we run a component in spin called JavaScript to wasm, which basically helps take the output of the web pack produced JavaScript module and create it into a web assembly. And it's going to output that web assembly file specifically in the target folder, which is then the one that you can see if we go back to the spin.tumble file that we will run when we run our spin application. So now for me talking, let's actually see this in action. This is this is the code that will execute. And you can see from the code up here. Well, I actually wasn't done talking sorry about that, but as you can see from the code up here, the template provides you a function that you know, it's called handle request. And this is requirement for JavaScript. And we what we do is that the spin framework hands over the request, the HTTP request coming in to you, and then you do whatever you want to do it in you. You do whatever you want to do with it within this function. In this case, we're simply just returning. We have an HTTP status 200 saying, okay, we said a few headers, and we said some body text in there as well. Okay, now we're actually going to go and try and run this. So if you go over to Tim and I think we call this CNCF. I gave this app a terrible name. This is probably where we're going to break things as we go along. I need to run npm install because we're in a JavaScript npm world. So now we have all our modules downloaded. And then I can do a spin build command and basically spin build calls into that spin tamer file and executes the command defined for all my components. So spin bills call npm run build and you can see that right here. And that produces the Web SMD file, which means that if I now run the spin up command, which is how you start a spin application, then we'll go and load that Web SMD file. And because of the definition in this, let me go back to the Tamil file. You can see that this component of this JavaScript is being served on the base route or the root route, sorry, which is then translated in here where we can see on port 3000. We now have a CNCF live demo app. So if we go ahead and we just curl that one. We see that we get a response back and we get that header. We get the 200 okay and we got the hello from JS SDK. That is really all it takes to build a spin application. And from here on I can go and I can extend functionality in my JavaScript component. I can add more components to the same application and then start building out of these small micro services. You could call them almost, you know, that could be built in any programming language. So I'm just going to do a quick pause here. And Andy, do we know if there was any questions that we need to get to? There hasn't been any questions so far, but a good reminder to our audience. If you have any questions, just put them to the chat and we will get them. But there was a comment. There was Sam who said they are a spin fan already. So that's very promising, really nice. Thank you, Zain. Thank you very much for that compliment. Yeah, I mean, yeah, I'm not the best to say this, but I'm going to say this anyway. When I started working with spin, which is almost a year ago now. I mean, that immediate feeling of getting into this developer experience where, and I think it's hard to demo that, but I mean, beyond having my JavaScript tool chain set up, I just need spin, right? I only need that one executable that I can just copy into my machine and that's it. And I hope, you know, part of what you can see from the demo is that, I mean, the build didn't take a long time. It's a small application anyways, but spin up is, you know, this is how quickly these start. And what's actually more important, I'm going to show that in a slide in a second, is that the response speed for these, I think we can even try to, you know, just try to just call this guy a thousand times by different clients. I think the response time of these spin modules. So actually what I did is I just ran a small mini load test, where I did a thousand requests across five clients. You know, it's fast responding. I know this is local and I know there is hardly any computation happening inside of the component. But what's really, really interesting, and I want to show you this, a little illustration is, is how spin sort of handle these WebAssembly components internally. So remember that I talked about how these are small in sizes and that they have an incredible startup time. That's actually part of what you're seeing here. So if you try to walk through this process of what's happening from when I run spin up to I'm able to, you know, and until these events are being handled or until the requests are being picked up by spin is that spin up goes and run another process, a sub process to spin and calling a spin trigger command. And what that spin trigger command does is it loads all the individual components. Well, it loads the individual component information that you had in that spin or tunnel file. I remember I said what I showed you before we just had a single component. I'm going to show you application a little bit that has four different components in it. And so what that means is that as the spin size, these individual components are being loaded, you know, the virtual machine is being created by Watson time, which is the WebAssembly runtime we use. So each component now runs in its own little isolated environment there. So component A here could be the JavaScript component. I just showed you and I could have other components in there as well. Now all that information is now loaded and ready, but the component itself is not running. The WebAssembly module is still unloaded at this point in time. It's not until that, you know, in this case, I do a curl to basically send an ACP request that hits the spin trigger process that the WebAssembly runtime goes and load that module from disk and, you know, handles the request and unloads the module again. So each individual request is a separate and fresh module load. And that obviously has, you know, it has some opportunities. It has those opportunities that, you know, if you think about this in context of how you would scale an application like this, is that they're really like, you know, the concept of scaling down to zero as such is at a fairly different level in the sense that, well, I mean, if you run high scale enough, you need multiple machines, probably if there's a huge request load. So you might want to scale the number of underlying machines you have as infrastructure, but the individual component you don't scale as such because they only load and they only do work when requests are coming. So, you know, and that's stuff we can do because they start so quickly and because they're so small in size. I had another point that just totally slipped my mind, but I'll probably get back to that one. But, you know, so I think that's a good thing to be reminded of when you see this. Oh, now remember, yeah. I say that this open up some opportunities. There are obviously scenarios where, you know, this isn't like running a web server, you know, where you can do, you know, where you have some things that you warm up and, you know, and, you know, each sub-C pin request that being loaded and you can hold some kind of session state in memory or what those things you do, you can do that here because every single request is a fresh reload. You need to somehow, you know, offload your state to something else and we have a solution for that, which is great. But, you know, but so you have to think about it in that way. And I think what I've come to sort of acknowledge over this little bit of a year I've been working with these spin thing is that it's actually nice that, you know, you can have components taken care of a really, really small sort of, you know, concern within your application. And you don't have to think about a whole lot of life cycle things happening. And hopefully that will show you when I sort of get into this next application that I want to walk you through that I've built that is probably a little bit more complex that, it is a little bit more complex than the Hello World that I just showed. So before going into that, let's just, you know, expand on what spin does and expand on just, you know, how we execute, how the whole execution model is and what I showed about these templates. Well, it's just that one binary tool, as I said, you download it and you use that sort of developer tool. It's also how you can, you know, run it on a server or anywhere else, spin up basically is the way to run your application. Now, there are projects out there that enable you to run spin in Kubernetes. There is a project called Run Wasi, which enables you to use spin as a runtime class inside your Kubernetes cluster. The same way you can do that with Run Wasi, which is part of Container D. There's also another project called KWasim that will sort of help get things installed inside a Kubernetes cluster. I'm not sure we're going to have time to show that today, but I know we have a follow-up on demand session where we can dive a little bit more into those scenarios also. And again, but some of these are early, you know, those are early experiments and trying to figure out how that operational model of these type of spin applications can look like. But it's something you can go and do today. And Microsoft's Azure Kubernetes service actually has a built-in support for Wasi workloads, among those Wasi workloads being spin. And if you have tried the latest Docker desktop, Docker desktop did a technical preview too of Wasi support recently. You can also run Wasi workloads like spin directly on Docker desktop. So many ways of, you know, sort of getting these type of applications into either infrastructure you already know and that you're comfortable using or that you already have, you know, at the place where you run stuff. Okay, so that was a little bit about, you know, how and where you can run these things. Obviously, the last thing that I almost forgot to mention is that Fermion, the company that has been building spin, a company where I work, we also have a cloud offering to run spin applications. So Fully Managed Cloud for running spin applications as well. And I'm going to show you that a little bit, how you can run these applications deploy into the cloud. So we talked about that seeing the binary tool. We talked about all these different languages that we have support from. We had this, this template. Yeah, there's an audience question. Yeah, so Darshan asks, is there a logging architecture? No, spin doesn't provide anything for logging outside of capturing standard output and standard error. So if you, so it's not, it's really not a concern that spin goes into, which means that, you know, you would probably use a, let me back up a little bit, inside. So in a spin application, as I'm handling a request, and I didn't show that here, you are able to do outbound calls as you, you know, as you handle requests. So, so one way of doing that is that have your component log out as it executes. So basically you write the code. So you implement logging in your component yourself. Other than that, you would have to, you know, you have to fall down to the infrastructure level and pick up the log files that spin are producing. So standard out and standard error are being locked into log files. So, you know, if you use things like, I guess it's Fluent D. Those are the types of things. I might be a little bit off of my comfort zone here, but you know, some of those log collection tooling things that can pick up log files, that that will be a way where in these infrastructure there's an area is you can, you can collect the data. Great. There was another question from the audience that we can grab now as well. So Bustfader asks, how about any known limitations? Yeah, that's a really good one. You probably have noticed. So I mean, I've always mentioned a few things. I mentioned, you know, maturity of WASI mentioned, various support for various levels of maturity and support for programming languages and also specifically how our JavaScript SDK is experimental. A lot of this boils down to support for the individual programming language being able to compile to WebAssembly. And then the state of the WASI specification, which are sort of, you know, the things that we interact with in terms of what we can do. From programming language point of view, if you want to be, you know, where you, let's go for those, those where, you know, the system language is like, like in this particular Rust and also language like C and C++ has the far best support for WebAssembly today. Go has very recently gotten, I'm actually not sure if everything got merged in, but Go should also be there or be very close to. We have been using TinyGo up until now, because TinyGo had better WASM support so far, but Go should be very close if not already there. If you look at the interpreted types of languages like JavaScript, TypeScript, Python and those, there's a lot of effort going on to improve that right now. Basically what is being done today is the interpreter is the one that is being compiled onto WebAssembly, not the actual code. So that definitely has some important performance impacts there. So that's the thing that needs to be solved. And if you look at things like, you know, Java and .NET also have some preview and experimental support at this point. So that's sort of the programming language side of things. The other thing I think is worth mentioning is WASI. So WASI has a preview one release right now. And some of the main things that we're looking forward to in WASI Preview 2 is to be able to use sockets directly from within our component. So today, the way that we've solved this has been, is basically through SDK we enabled you to do outbound connectivity to a certain set of protocols, so HTTP, Redis, MySQL and Postgres. But once we get to the next preview of WASI we'll be able to have sockets which means that you can use any library that relies on the network connectivity. So there's some movement on the WASI side and the WASI roadmap to get to that. So I think those are the main limitations to be aware of at this point. Whoops. Yeah. Great. And we actually continued with asking for the GitHub 3.4 details. Did you have them? Yeah. There are a lot of places we can go. Let's do this. Let's do the spin one. I'll just get that down here in the chat. And that's a good place to start. And it will help you understand and read about the spin projects. There are some links here. Talk about whether some component model was in time and stuff that we built on. This is definitely a good place to start. Perfect. We'll get that link to the audience, but sounds like a good place to start. Cool. Okay. So let's move on and let's look at something beyond that Hello World example. And let's probably go over here. Okay. So I built an application that... Let me just show you the application straight away. Maybe that's easier and then we can sort of take a look at the code and how this all works in a spin scenario. I have built an application that enables you to create shop links. So it enables you to create easily ways to redirect. There are a little flaws in here, but we'll get back to that. So basically what I can do with this application and everything you see here, by the way, the front end and everything is served by a single spin application. I can go in and I can stay here. I want a short link to a CNCF live webinar. And that will be a... I don't have a link handy. Let's just do this. Is it CNCF.org or is it IO? Do you guys remember? It's IO. It's IO. Okay. I know we don't need to short link CNCF.IO as long as we know it's IO and not org, but anyways, you sort of get the idea here, right? I can go and save these in here and you can see I now have a redirect and if I click that, it takes me to CNCF. What's also nice with this small application I built is we go back, have a way to generate QR codes, right? So if you pick up your mobile phone and you start scanning this QR code, it will now take you to CNCF.IO. So I guess you sort of get the idea of what this application can do for you, right? I know this is hosted on a weird domain for now and that's probably not the idea with the short linking, but we all get the idea of what this application can do. So there's stuff in here about a UI that we present in the browser. There's stuff in here where we generate QR codes. There's stuff in here where we save state. So all of these are things we can build with Spin. Let's take a look at how this application... I'm just going to go over into my text areas as well. And what I want to start showing you is the terminal file, which is called an application manifest. It's called an application definition. Again, you can see I have some metadata to begin with and that's not... The only relevant thing is there that it's an HTTP trigger. Yeah, let's give spin a spin tailor. That's true. You wouldn't know how many times that thing comes up, but yeah. So one thing to just be aware of, if I build an application with multiple components, they all have to be of the same trigger type today. We have some experiments of supporting multiple trigger types, but in this case, they all are. So you can see that I have three things in my application in here, three components. First of all, I have an API. And what you can see is that the route that is serving API is slash API. And so that's basically the API, the CROT API from my application. That's where I can create a new short link. That's where I can list all my short links. I can delete them. I can get a specific one. So that's all good. The next component that I have is my client. So that's my frontend. You noticed up here that you may have noticed that this is a Wasm file, API that wasn't filed serving this component. And you can see it has sort of a local disk reference, which means that this is something that I built locally. Now, with the client component down here, it's a little bit different. Now, this is not a component that I built. This is actually a component that I am running off of GitHub, off a remote server, remote endpoint. So what I'm able to do here is I'm actually able to take components that someone else built and put it in and make it part of my application. And that sort of enables me to very easily have these sort of generic reusable components so I can construct applications in a fairly quickly way. Now, for my client here, what I'm using is something called a spin file server. And all that is, is a file server. So basically this will serve a set of files. And that's what I use for my UI. So this component has this configuration down here where it's able to serve a set of files. Now, this is part of, you know, I mentioned the security model of WebAssembly a little bit earlier. And it's what's called a capability-based security model, which means that WebAssembly, any of these WebAssemblies that I have here, this is the only WebAssembly that I actually able to access my file system when it runs. And the only reason why I can access is because I configure it with access to a certain set of files. In this case, I'm configuring to access the directory called client. So the capability-based security model is, you know, it means that the model, the WebAssembly component only gets, you know, access to what you specifically, you know, enable it to have access to. It's not about, you know, commissions of the user running the process. It is actually you cannot get out of that virtual machine or the sandbox inside the WebAssembly runtime unless you explicitly are given the permission to do so. It's the same thing that if I had a component that needed to reach out to an HTTP endpoint, I would have to in here specify specifically which HTTP endpoint can this specific component call. So it's a very fine-grained security model in here. And what I really like about this model from a user point of view is that, I mean, the default is that these can do anything but just live with inside themselves in their own little memory space unless I explicitly tell them to do so or being able to do so. And that's really, really nice. Okay, so two nice things about that file server. I didn't write it. Someone else wrote it and it worked really nice. And I can, you know, serve some files for my web UI for that one. My last component then is something that I built myself. And this is the one that is actually doing the redirect. And what you may have noticed about this component and also the API component is that they both have this thing called a key value store defined. And the key value store is something that's built into spin where we enable you. Remember that I mentioned earlier that anything is a freshly reloaded for component. So I don't have shared memory. I don't have memory persisted between handling requests which means that if I need to store anything between my requests I need a place to store them. So well, with spin we provided a key value store for you. So there's a simple API that you can use from code to store keys and values and retrieve them back and they can actually be shared across components inside an application. So in this case, the API component has access to the default key value store and the redirect components access to the same key value store. Okay, so that was a little bit of some of the capabilities that these spin things, spin applications can have and what they provide. All of these, by the way, are the two that I have here written in Rust. So you can see we're using cargo commands here as a way to build the components. Let's have a quick look at the, let's take a look at the API implementation just for a second. So I'm trying to walk through this even though you may not know Rust code but let me just show you how such a component, how the code of such a component can work. There's a bunch of use statements up here in the beginning because I have some external libraries, crates that I use. I have a structure defined in here. It's basically my name. I have a bit of helper functions, greater random string. It's always nice. And then this is the handle redirect command that is annotated with this HTTP component macro. And if you remember what this looked like in the JavaScript file, I know this is not about learning multiple programming which is sort of give you an idea that it's the same model we have. I had a handle request function in JavaScript where basically a request was handed over to me. I returned some stuff. It's the same model in Rust. I get a request and I do stuff and I return a result, right? So HTTP and HTTP out. But what I can do in here is because I have that key value store in my API I can open my store. So you can see there's an easy API to just open the default store that is available there. And then I'm going to figure out whether a post came in, whether a get came in, whether the lead came in through the HTTP request. If it's post, I'm going to, you know, get the body of the post request. I'm going to serialize that into a link. And then I'm going to use the store.set API which basically means now I'm going to store this into my key value store. If everything is okay, we're going to return a HTTP created code back to the caller. You know what, as we go along, we just see this in action. And it will do spin up. And we already have spin running somewhere. So didn't break things. We just didn't make things work on the first go, but it was folks. Let's call the API. So basically I'm just calling all 3002. Now you can see this is running a 3002 and you can see my API down here is running a 3002. And basically because this is going to be my get command, we can see that what we're doing when we're getting is that we are just checking if there's any query parameter that I added. If I didn't add any, we're basically just going to go and get all the keys in our store and we're just going to iterate through this and get all our records out. Probably want to do this. Don't want to do this if this is a large collection, but it's not here, so I can do that. And basically what we end up returning down here is to all our links serialized back to JSON. So if I went in and I asked my API for one of the specifics, you can see I will now get that up. Just need to close around that. You can see I get that one specific redirect from my API. And again, I want to just call out because this is always so funny as we run these things. How quick do things work? Basically as I run this command, this WebAssembly module gets loaded. It's going to evaluate the get command, the query parameter. It's going to open that key value store, which locally is backed by my SQL instance on disk. So it's actually going to go down to that my SQL file, grab the record and send it back to me. And then it just happened really, really, really quickly. So yeah, that's always a joy. Okay, so basically this is just a CROT API and that is what that is. What's interesting about this local version of my application and I'm just going to go into the admin interface is that you might notice that I didn't have that QR code generation function in here. So I can still go and edit these if I want to. Let's just call this edited for now. So now we can see it's edited, but I don't have that QR functionality. So let's say I started developing this application and I got to this point where I need to add this extra functionality. How could I go ahead and do that? So let me go into this terminal window over here. Now remember that I have... At one point in time, I may or may not have mentioned that spin has this concept of templates. Locally, I have a set of templates that I can use when I need to write new components. And you can see these are all the templates that I have installed. For instance, the static file server that I mentioned that I'm using to serve my HTML and JavaScript files is one that I'm just downloaded off of GitHub. So because I have that template installed, I can use that for spin new or spin add command. Now it so happens that someone very friendly who is... Well, it's actually me. Anyways, they had one of these components. I actually created a spin component, which is a QR code generator, which is just an HTTP component that if you curl that component, if you send an HTTP request to that component and anything you put into the URL as an argument will come back as a QR code. So the QR code that I'm showing you here in this GitHub site where this component lives is taking you to GitHub.com for me as that spin. And this is actually something that I want to use my application because I want to have a way of generating QR codes for those redirects that I have. So in order for me to do that, I need to first go ahead and install this as a template. So I do spin templates install. I point to that GitHub repository. And you can see I now have this QR generator as part of my template list. So we can go down here and we should be able to see I have QR generator that generate QR codes. That's nice. Okay, so the next thing I'm going to do is I'm now in the directory where my spin.toml file is, which means that this is the spin application I'm working with. I can do spin add. I can say I want to add the QR generator template. I'm going to call it QR except the defaults for the template guide. Now what happened is that, let's go up here. Let's find the spin.toml. Let's close that file. What happened up here is that I now had a fourth component added to my application. And again, this is one of these components were then referenced by a WebAssembly that lives in GitHub. And this is being served on this route called QR. So all I have to do now is go back, run spin up, and I now have an endpoint in my application called QR. So if I go back and we curl, and we should be able to do QR, and I think we can do something like www.cncf.io. What we will get back now is we should be able to get, this is an SVG off a QR code to get you to cncf.io. So I now have that functionality as part of my application by basically just taking that remote component and adding it to my application. So I did do a little bit of trick here to prepare because obviously the next thing that I would go ahead and do now, I don't know if it's obvious, but the next thing that I would go ahead and do is somehow implement this in my client. This is the HTML that I'm using for my client. And I did go ahead and cheat a little bit. And I think I should have something in here that I just needed to, that's actually not here. Sorry, that's in the JavaScript file. Hey, there you go. Let's uncomment this. And so the idea is right that I am now, I've added some functionality to my client that enables QR button. And when I click the QR button, I think I have that down here. That's the short link. Oh, this is one right. When I click that button, we'll go and encode the URL, which is the key that's in there. And then we'll call that QR endpoint, right? And we will show a modal that will give us the QR code. So let's go ahead and I just, so I changed the static file, which means I just have to say that file. I don't have to rebuild my application because spin will just serve, serve those static files to my file server. So I can go back into the admin interface. And I now have this QR button in here. And if I click that, you can see I can generate my QR codes. So I know, you know, you had to do more than just write spin add to get this functionality in there. But basically I wrote spin add to get that prebuilt component in here. I added a button and I added a little bit of logic to that button to open the modal and show the QR code. And I'm actually just going to test this because let's see, if this one will take us to developerfirmware.com slash spin. And hopefully I can show, I need to get rid of this. Okay, this is obviously, yeah, sorry, this is going to run for my local machine. So you won't get the full QR there. But it is a valid QR code. I can tell you. Okay, so I hope this gave a good idea of, you know, what you can do with spin, what spin is, what WebAssembly is, you know, some easy hello world to issue into developing the spin applications a little bit more of a complex type of application, how you can use this idea of components and spin applications to share functionality. And, you know, we hope, we hope that more people want to join that ecosystem of having these small components that just make it easy to compose applications where, you know, you can bring component in any programming language and make it part of your spin application. Yeah, so do we have more questions, Annie, as we, I think we're nearing the one hour mark now. Yeah, we have two minutes left. So if anyone is typing a question and thinking about a question, now is your time. This is final call for questions. And while we see if anyone is writing it, Matt says this was great. Thanks, which is always great. Matt is my boss, by the way. Yeah, if anyone's typing away, please send it now. And while we wait to see if anyone is going to send a question in, I have a question. What will the future for a wind assembly or spin look like? Yeah, so I touched a little bit upon, you know, languages and supporting languages and definitely, you know, having better support for the languages that are somewhat somewhat supported today. We know where we get fully on par with performance and those things. We are heavily invested in both the JavaScript and Python at this point because we believe that a lot of developers would like to have those languages being available in a framework like this. So that is definitely the, there's some work that we want to do there. On the WebAssembly system interface, there is a really good roadmap. In general, I'm just going to do a there was a conference two weeks ago called Wasm.io and there's there's a lot of very, very great talks on YouTube now. So Wasm.io I don't have a link handy, but it should be fairly easy to find that one. And there are some talks that talk about the roadmap of Wasi. So particularly the socket supports are being able to use, you know, normal database libraries and drivers that you use today in your applications being able to support all of that, which is somewhat hard today. It's definitely going to be good. And then the big one further out is something called the WebAssembly component model. I mean, we have a minute left, so it's really, really hard to go into that. But I think the main thing to sort of understand with the component model is that whereas I've shown you a scenario now where you can construct applications of components written in different programming languages, but they're sort of, you know, isolated, but they're their own endpoint in this application construct or whatever you want to call it, right? Then what the component model enables you to do is to actually use the individual WebAssembly components as libraries, cross-programming languages. So, you know, the QR code generator that I here used as, you know, an expose to an ACV endpoint, I could actually, even though that would have been written in a different programming language than what I wrote my client in, I could just reference it directly from within my client as a library. Sort of in that sense, right? That's the whole idea of the component model to get to that point where libraries written in different programming languages can be used by one another. So, that will definitely, you know, that's the big change and we're probably going to see more of that in the next six months or so and how that would impact the spin-developer model and application model. Like, it'll be interesting to see but that will be a bright future once we get to that point. Great. I like it. Ambitious goals are good and looking forward to seeing that bright future as we go along as well. And I saw that Karen also linked the sessions to the chat. So, if anyone wants to check them out please use that. But that's all that we have time for today. So, let's start wrapping up. So, thank you everyone for joining the latest episode of Cloud Native Live. It was really great to have a session about building serverless applications using spin and web assembly. We really love the introduction as well as the questions from everyone today. I especially love the comment great to see you giving a spin, extra points for that. But in the coming weeks we have more great sessions coming up. So, thank you for joining us today and we'll see you next week. Thanks, Annie.