About this video
What You'll Learn
- Handle request headers by reading x-name, uppercasing it, and echoing it back.
- Parse JSON request bodies with Zod so runtime validation matches the TypeScript shape.
- Use qs to split query strings from the path, then allow outbound hosts.
A walkthrough of Fermyon Spin's Node.js SDK in TypeScript: handling request headers, ArrayBuffer bodies, JSON parsing with Zod for runtime safety, query strings via qs, outbound fetch, and configuring allowed_outbound_hosts.
Jump to a chapter
- 0:00 Introduction to the Node.js SDK
- 1:20 Getting Started with Code and Setup
- 1:38 Understanding Spin SDK Types (Request/Response)
- 2:49 Building and Running the Basic Application
- 3:28 Handling Request Headers
- 6:44 Handling Request Body (Accessing ArrayBuffer)
- 8:05 Converting Body to String
- 9:08 Handling JSON Request Body
- 10:38 Runtime Type Safety with Zod
- 13:02 Handling Query Strings with `qs`
- 15:23 Outbound HTTP Requests (Using Fetch API)
- 16:31 Configuring Allowed Outbound Hosts in spin.toml
- 17:52 Conclusion and Summary
Full transcript
Generated from the English captions. Timestamps jump the player to that moment.
Read the full transcript
0:00 Introduction to the Node.js SDK
0:00 Hello, and welcome back to the complete guide to spin at the Rawkode Academy. Today, we're taking a look at the Node JS SDK. Much like the other SDK walkthroughs, we're gonna cover everything that you need to get started right in your first WebAssembly microservice web Vermeion spin. Let's dive right in. Alright. Let's get started with the Node. Js SDK. The most common things you'll need to do with the Spin SDK is your first endpoint. When you run Spin New, it generates a simple endpoint that just says, hello. I'll guide you through the code that is
0:42 involved and the setup to get that running locally. Next, we'll grab some HTTP request headers, then the body, then the query params, and lastly, we'll speak to another service. When you start to build out your microservices, you're inevitably gonna wanna speak to, well, one, other microservices or two, other things on the Internet. So I'll show you how to get started using Spin's SDK for outbound HTTP connections. If you need any help, please feel free to drop into the comment section. I'll keep an eye on it, and I'll do my best to help you get on your way.
1:20 Getting Started with Code and Setup
1:20 So let's start looking at code. So the first thing we want to do, from PMPM and so on, or whatever package manager you prefer to use. Now that we have our dependencies, we can pop open our index dot t s. You'll see here that the Spin SDK exposes handle request, HTTP request, and HTTP response. The handle request is just a type definition that describes the function that handles an HTTP request and spits back an HTTP response. HTTP request and HTTP response are just object that allow us to grab information about the request and our response.
1:38 Understanding Spin SDK Types (Request/Response)
2:04 Simple. Now because we're using TypeScript today, we have really great language server protocol and our IDEs understand the code inside and out. You can click on HTTP response, and you'll see the interface definition. The only thing to know is that our body is in a rebuffer. If you're not familiar with the semantics of WebAssembly, essentially, everything is an array of integers or bytes. I think that's right. So we can't just throw text back down the pipe. Hence, we use the text encoder to encode a string value into the array buffer. Other than that, you're just writing standard TypeScript
2:47 code. Let's run this and see what it looks like. We can run spin build to compile our web assembly module. We can then run spin up with follow all, Make our first request to our Node. Js service. And that's going to return a four zero four, because as you can see at the top of my screen, the endpoint that we need is slash hello. Now we have our hello from the Node JS SDK, and that's pretty sweet. Alright. Let's take a look at headers. First thing we wanna do is grab our header or at least a
3:28 Handling Request Headers
3:36 header that we're going to provide called x name. I'm just gonna pass my own name in as a request header and we're gonna transform it and propagate it back onto the response and then include it in the body. Super exciting. Now we're gonna add some debug here. Name is x n, like so. Where the warning console dot debug is not supported and spin with the Spin SDK. So you'll get function not found. Now let's modify the response headers to include x name where we do x name and we'll transform it just to uppercase. Nothing exciting,
4:25 but enough that we're doing something with it we can see visually. We could see on our response. Lastly, we'll update the body like so. There is a few things to note here. One, this is standard TypeScript code with the exception of console dot debug. Nothing else here is unique. We assign with constant assignment. We're using string functions on strings, and we have template literals where we can interpolate variables. All standard Node. Js, JavaScript, TypeScript stuff. Your dev loop, it's around spin build and spin up. And I would encourage that you add follow all so you can see the logs on
5:16 the console. This will compile your program to a web assembly module or binary where we can run curl. I'm adding dash v so that we can see the response headers, and I'm gonna add my own header on the request. And we'll set that to David. Now we can request local host 3,000 slash hello, which is the endpoint that we have configured and the spin dot toml. We'll take a look at that in just a second. As you can see here, our console printed name is David. We can see the response header of x name is David in uppercase,
6:03 as well as the original x name of David in the body response. Now the other thing to note here is that the HTP framework is part of Spin's SDK, always lowercases all of the headers. Even though I passed it in as x name like so, this would actually give us an error and a crash because that key does not exist on the object or the record. So just keep that in mind. Always lower case your header names. So that's headers. Hopefully, nice and simple, but nice to understand how to fetch them and how to use
6:42 them. Okay. Let's understand the request body. Let's do body equals request dot body. If we hover over the variable, we get our intelligent information from the IDE. So this is either on a rebuffer or undefined. So let's do good error checking. And if we don't have a body, we'll return a 400 and say this is a bad request. Now we do a console log for body, not to print it out, but just to understand where the TypeScript compiler thinks we are. We can hover over and we'll see that it's narrowed the scope of the type.
6:44 Handling Request Body (Accessing ArrayBuffer)
7:30 And now knows that beyond this point, we always have an array buffer. And in fact, let's actually run this and see what we get on the terminal. So we're gonna run, spin build, spin up, follow-up. There's a pattern here. Next, we'll run the curl and we'll just keep the same stuff that we had from the previous request. And you'll see here that we have an object array buffer. We're not actually getting a string. Again, web assembly works with integers and bytes. So let's get a string. The easiest way to do this is to say body string equals
8:05 Converting Body to String
8:14 buffer dot from passing on our body and calling to string. Now we can do a console log of body string, and for good measure, we can include it on the body response. We come back, we build, and we wait. And why does it look like nothing happened? Well, nothing did. We can see a blank line coming through. What do we need to do? Include a body. Well, let's do dash d, and we'll pass through an empty JSON object. Now we can see that the body is printed above in the logs and as well as in a response
9:06 on the bottom. Perfect. So let's take a look at one more thing before we move on to query strings. I'm going to define an interface called request body. And that's I'm going to have a string name. Down here, I'm going to say that my request body is equal to my request dot JSON. Now we haven't done any type matching here, which means we don't get auto complete on our request body. But the JSON function will parse the body of this JSON. Now we can't just say that this is our request body. What we actually need to do
9:08 Handling JSON Request Body
9:56 here is choose TypeScript's concept of as a request body. Now down here, we can see got the name request body with auto complete name. So let's run spin build and send a curl request. This time passing through the body with JSON. And we got the name David. So let's send a call request this time with that and we get undefined. So it's always wise to remember that while you're developing and writing and TypeScript, that all that type information disappears off to the at runtime. So if you do need to make sure your types are valid at runtime,
10:38 Runtime Type Safety with Zod
10:55 I recommend checking out Zod. You can do a PMPM install Zod. From there, you can define your Zod object. You can see that our request body equals Zod object, which has a shape of Zod string. Now instead of defining our interface as a duplication, we can remove this and we can say type request body, sort of fair, type of request body. So now we have two definitions of request body in the same scope. One is a value and one is a type, and that's okay in TypeScript. So we can choose to leave this as it is,
11:57 but use our request body value to do a parse on the object and see if it's valid. And you can see Copilot already there with the answer. So let's recompile and send our field request once the server is listening. And now we have a big large error telling us that our types are invalid. This may not be the best approach, especially for production systems. So you can change this to safe parts. Now this won't crash, but you will have to evaluate the response. You can then use response dot success to decide if you need to continue or
12:49 present the user with an error. So this audio is really cool. If you need runtime type safety and your Node. Js microservices, check it out. Let's move on to query strings. Now there's nothing special provided for you to handle a query string. You will have to parse it through regular Node JS code, which means we're gonna have to pull in the QS library. You can do PMPM install QS. From here, we can import star as QS from QS. Like so. Now that we have QS, we can parse the query string. Let's do a const query string equals q s dot parse.
13:02 Handling Query Strings with `qs`
13:47 Now the thing that's important to remember here, that we have a request URI, but the query string library splits on the ampersand, which means we still have the path in there. So we have to manually split the path off. So we can just do split based on question mark and then grab the right hand side. Next, we can just do console log and say hello limit limit like so. So let's set our limit to be equal to query string dot limit. Well, that copilot pick a default 10. Now we can use the syntax because if we click on parse,
14:36 we see it returns a parse queues and this is just a string indexable object. So this should just work. So let's build and run. We can do spin build up and follow. We can now do curl local host 3,000 slash load, and we see the default limit of 10. In order to change this, we have to quote our URL because of the question mark and set limit equals five. And as you can see on the top, we have the query string parsed and our limit processed. Alright. Last but not least, outbound HTTP. You'll be pleased to know that you just
15:23 Outbound HTTP Requests (Using Fetch API)
15:26 get to use the regular fetch API. What does that mean? Well, it means we get a const response equals await fetch tanker Copilot, and let's actually just grab google.com. That's it. You'll see here, we have a response with a fetch result. So let's grab the response body, which equals await response dot text. There's nothing new here. You don't need to learn anything else. This is standard fetch API. Let's do a console dot log response body. Next, guess what we're gonna run? Spin, build, up, follow. And we'll do a nice simple request, local host 3,000 hello.
16:31 Configuring Allowed Outbound Hosts in spin.toml
16:31 Now if you've seen the other walk throughs for the other SDKs, you'll see that we always had destination not allowed. Spin ships with secure default, which mean you can only make outbound request to domains and destinations that you specifically allow. We can modify that in the spin.com. Let's pop over to here. Each component that you have can define the allowed HTTP host. From here, we can set google.com. Let's run our spin, build up, and replicate our current request, like so. And as you can see on the server logs at the top, we have the output
17:28 from google.com being console.log. Now if you don't want to restrict outbound access and you want to allow anything for whatever reason, I promise, I don't judge. You can change allowed HTTP hosts to be insecure colon allowed dash all. This will allow you to request any website that you want. That's it. We've covered the Node. Js, specifically with TypeScript SDK for Spin. I hope you found this useful. If so, jump into the comments. If you run into problems, jump into the comments. And if you want to see more videos like this, click thumb up, subscribe, and go
17:52 Conclusion and Summary
18:11 check out Fermion Spin. Happy hacking. I'll see you next time.
Technologies featured
Stay ahead in cloud native
Tutorials, deep dives, and curated events. No fluff.
Comments