Episode #4: Rapid Side Projects with Cloudflare Workers and Workers Sites
Continuing API development with the Workers Router Template, Mocha and Test Driven Development
Welcome, welcome to episode four. Welcome to my millions and millions of adoring fans following along closely each week as we hack our way through Cloudflare workers.
This show is not about me documentation or showing you enterprise use cases for workers, but as a guy who hacks around at home sometimes how you can sort of quickly get going and side projects and put them out into the world to hack and use and have them not fall over because they're on this super high -performance super reliable distributed system that we call Cloudflare Workers and workers sites and workers KB.
Let's do a little of where we are and maybe where we're going.
You can have studio at Cloudflare TV and I should see them.
Again for the sort of correct way to do things check out the documentation for enterprise customers, contact your account team.
So far we've done a couple of things. We've got a site live. First episode we got a like a worker's site up.
So just a little site on the web that was doing white conversions and then we thought okay let's see and build something API back into it and we sort of finished up the last episode with a local development environment with unit tests integration tests and we actually got a an API deployed that you know sits under a domain name receives these requests and forwards them on to a free forex site and shows response.
So we're gonna sort of put something in front of this API so we can like actually connect it to a website and see it working and so a water end-to-end project could look like and then depending on the time see if we can make it look nice and maybe things like cache results to take the load off this guy when you know when the new millions of fans start hitting it as you watch it.
Okay dive in again we finished off with this. I can't remember whether we used wrangle a tail or not we might have but it's a time logging and basically any sort of console that logs that get written from our API awesome experience.
So you can see something's happening there like ideally I'd actually pipe jq extract this message we might do that later but I can see things happening and so if I get errors or something or if I had logs I'm gonna see that.
Good stuff I can I know that when when requests are coming we're seeing them.
Okay so what do I want to do I want to have start locally so we're gonna go back to we're gonna add something to our website.
It's not going to be pretty to start in fact it probably won't be pretty at the end either but I feel like this design is starting to age a little.
Let's put something there right we're going to need let's just make ourselves some room to start and this is where we'll start doing now and then um you know I can still make it look pretty ugly we'll try a bootstrap or there's also a like a Vue.js sort of specific bootstrap project as well that's meant to make it easier to interact with you.
Yes okay so this is where we're going to be.
Okay convert and we're going to want some sort of select now this is probably be easier I don't have one sitting there ready to go so let's grab one.
Do we go to the source or do we go to Q&A?
Who's gonna who's gonna give me the better result?
There's the form I wanted to select didn't I?
Now this looks pretty good. Okay so we're gonna choose our rate from here and we know we can popular rates and where's this being bound to it's kind of something pull it right and I'm gonna add it down here is our model so it's currently one big one we get point where we break this out into components maybe we'll do that in a future episode but this isn't really to teach Vue.js I'm just using it like I find it to be a pretty sort of productive platform.
Okay so let's just check we're actually getting the thing selected.
Okay so we're confident that if we choose a rate we have the right the right field on our model.
So then when we click the button we're gonna want to go and get the rate and or the agile question do I pass in the value here or do I get in the method in the method but I'd love to hear your millions of adoring fans.
Okay so let's say we're going to get the current rate for time check a minute okay for this dot rate and let's just let's see if we've got let's see if we've got this far that we are so clicking on a button and getting no we want to actually call API.
So a few options here I think I talked about in a previous episode that you know my first reaction is to like a reach for Axios to reach for Axios as a library to make requests but that wasn't there was some incompatibilities because Axios relied on some sort of browser elements that weren't available in workers and so we used fetch that sort of you know how to mock that out so this time we are in the browser we can use it so let's install that and then we're going to do something like see I'll start get and URL something like this but we're passing in this dot rate so this is doing that so we call out to our workers API that we did in the last episode we're having to get a response and that response is gonna some data in it and that day is gonna look something like this so we're hoping for a structured back that we can sort of old so let's say great data it's gonna look something like this with a rate and a time stamp so and then we're gonna want to set the result so I think we'll actually call this pair and we'll call right so we're actually binding this and then the result which we will get from right okay so we're gonna set right to the result which we think is gonna look like that so say this dot rate equals rate data dot rate okay we also need to actually include axios so I barely move to that so it's just a standard import where are we and we're down in the script area again you don't have to use this like it's a pretty simple operation we're doing we could use fetch but I've just the sort of that's into like the shape of the axios API okay so what's being a you the and what's happening if anything lots of red that's okay so chestnut okay so I think like we so it's looking at you know creating a local development development environment and we've got the API to a point where we're happy to sort of iterate locally test and push to it's sort of this there are some more steps required able to run a like local website on localhost and and call your API either the remote one there's a tool wrangler dev that helps you run things at localhost and there's some code we can write in the worker itself to actually sort of return the origins that that are able to call like API I've times it takes time it would actually would be a good future episode so something I'll keep in mind but I'm sure I won't get the whole sort of thing done in the half hour and I'd love to get us having a PI that's actually sort of calling all the way through see so let's just check okay getting right for null so that's not great let's fix that we're actually sending a request that looks right yeah okay so that at least looks like what we're aiming for deploy that and to see if if at least we're able to sort of make you know to a which is already sorry published yeah and this is where like um you know you start to get into things like um you know in the real world or even when you start to get sort of further along with the site project like you're gonna want to get into sort of continuous integration and you know publish your environment I mentioned a couple of times Wrangler is really good for that because you know like when you base it on Wrangler and config files you can substitute those environment variables and really build up a full sort of CI CD pipeline but this is of trying to get end -to-end today we're gonna just straight out to play a published a script to that is that actually see if that went to yeah so Wrangler is telling us here it deployed to here but you might recall so workers scripts are at the account level and we could access it through this this domain but also in my dashboard the converter 10 domain with my workup so that's why I'm able to access it this way so let's see are we shift window shift Mac I know always get that all right get right so my logging is wrong there you go actually worked so first try so we just very quickly right locally strung together a combo box bound to some model variable pair call get right we pass that to our API it actually then passes it on to the downstream API which we configured back in our rate handler dot handle here called it's going to this free Forex API it's getting back and then just binding it to a rate variable which we're displaying here so we're actually already there with 12 minutes left of a worker site with workers API no data storage at this time and no cash it's just it's sort of I guess you'd call it like it's a does something in this case forwarding it somewhere else a little bit of sort of manipulation of the structure but that's a pretty common use case for workers all right so let's all right well let's fix this actually I don't want to like having logging statement be wrong getting great for this dot pair and you know no error handling all right so what else we try and do okay we are we already saw that we've got some I think it would be okay we are we're logging the full origin URL which is going to include the pairs that's enough for now okay so we're gonna look at make it look nice or catch the results to save the load I think it might be more actually the results sure the free Forex API folks would appreciate that and I'm gonna save adoring fans watching me play around with the UI because they won't be happy time great so take a step back for a minute um the Cloudflare cache cache is what backs Cloudflare's CDN you know that's one of the products that really Cloudflare is known for that as you know grown to be a like market leader over the years our of that cache is actually exposed to workers so you can use it to cache things you know in the colo you know where this worker is executing for those who are wondering the difference between workers KV like workers KV is a V store but it's not colo specific so if you put something in workers KV it will eventually be accessible in all of in all the colos where local to the colo with a asterisk there I'm not sure how to cache so those of you that talk to your to your account team if you're interested in that so looks like a pretty simple API we can just use caches dot default we can put things in the cache and hopefully we can see I guess okay matches how to get something out and we can delete okay um let's give this a go I'm not actually sure used this in a previous side project so this could be fun so let's let's say something like okay we're doing we're doing this for converter you could imagine something like for the free version here for all of the Cloudflare TV users our delayed rates or something like that and so that would be a really good use case for cache and maybe for a paid subscription you would get something along those lines it would make sense to use caching for that all right so let's let's so we need to get access to the cache and let's clean up clean up the code a little bit ah this also is a interesting one for local local development you've got a few like an implementation of cache similar in the way I did for fetch and you know pre-populated with data as you expect sort of the Cloudflare you know to great you can use Wrangler dev I haven't done a specific episode on that but that's because Wrangler dev actually runs on the edge so you need an example but you know the full runtime is there and available so really up to you the approach you take I'm not gonna I'm not gonna buy in today's episode to try and get it all mocked out let's see if we can actually use to return cached responses okay so we've got that we've got put things in enough so what are we gonna put it expects and so I guess we really want to put like whatever we're gonna return to the eyeball data now do we want to do we want to cache just the data or do we want to cache like the whole response so I think the like contract of this method is it just returns the rates so it doesn't really say anything about whether it's cached or not and I had the implementation of like what our logic is for caching inside here so I think I'll will basically say if in cache not stale turn otherwise we'll go through the usual thing and um you know putting cash down here before we return this like it feels like something that would benefit from like a pipeline or some sort of decorator pattern but let's see how we go all right this is the request no if it's in cache and I'll stay return it yeah five minutes to go thank you producer Cody five minutes can we do this in five minutes in previous episodes let's see like it is actually expecting a whole response which would imply I need to sort of change the structure get right or or do it up here so when we get the right and then we create let's just let's believe the docks and assume that we've got a that we have to do that so we're gonna we're gonna care about the response folks in previous episodes you've watched me code and this is the the TV you tuned in for now what do we the return come on returns a promise wrapping the response okay where cached response equal way catch match this request so you know if we're getting if we're getting the same requests that we did just you know before the USD you know we're hoping that will match and if it does let's return okay well that's my which is keyboard going crazy not yourself by a new keyboard and then we actually want to put things in the cache and I'm interested in here of the TTL because I really want to say something like say 15 minutes was what way yeah what we're going to put as the SLA for this this free Forex converter website chain so the cache API respects all the following HTTP headers expiry is handy but we use that but also respects all of these headers max age be the easiest and that's in seconds let's run with that and say we're gonna responses that way okay so we were just returning a response before I should first so cash the request this is interesting so it expects the response and I want to set cash headers on the response do the same cache headers to the client I guess that's fine the browser can just cache the result if it's otherwise I'd have to do something like you know clone this and have different headers that I put in the cache I don't think I need a different cache sort of expiration policy here for what's cached on the edge versus what's on the browser true I want to catch something oh we're done you