<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: dk</title>
    <description>The latest articles on DEV Community by dk (@thesephi).</description>
    <link>https://dev.to/thesephi</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F225019%2F3274228e-25a5-41e6-ba4a-65c915b37caf.png</url>
      <title>DEV Community: dk</title>
      <link>https://dev.to/thesephi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/thesephi"/>
    <language>en</language>
    <item>
      <title>Bootstrapping Cloudflare Workers app with oak framework &amp; routing controller</title>
      <dc:creator>dk</dc:creator>
      <pubDate>Sun, 30 Jun 2024 01:57:39 +0000</pubDate>
      <link>https://dev.to/thesephi/bootstrapping-cloudflare-workers-app-with-oak-framework-routing-controller-3blp</link>
      <guid>https://dev.to/thesephi/bootstrapping-cloudflare-workers-app-with-oak-framework-routing-controller-3blp</guid>
      <description>&lt;p&gt;Hello all,&lt;/p&gt;

&lt;p&gt;Following up on my previous &lt;a href="https://dev.to/thesephi/scaffolding-api-projects-easily-with-oak-routing-ctrl-1pj"&gt;introductory post about the library oak-routing-ctrl&lt;/a&gt;, I'd love to share an &lt;strong&gt;npm script&lt;/strong&gt; that generates a boilerplate code-base with the following tools built-in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://oakserver.org/" rel="noopener noreferrer"&gt;oak framework&lt;/a&gt; (middleware framework)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://jsr.io/@dklab/oak-routing-ctrl" rel="noopener noreferrer"&gt;oak-routing-ctrl&lt;/a&gt; (TypeScript decorator for API scaffolding)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://workers.cloudflare.com/" rel="noopener noreferrer"&gt;Cloudflare Workers&lt;/a&gt; application development kit (wrangler)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Part 1: Bootstrapping
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm create oak-cloudflare-worker@latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This script will ask us a few setup preferences, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;project &lt;strong&gt;directory&lt;/strong&gt; (we can leave empty to use the &lt;em&gt;current directory&lt;/em&gt;)&lt;/li&gt;
&lt;li&gt;project meta i.e. &lt;strong&gt;name&lt;/strong&gt;, &lt;strong&gt;version&lt;/strong&gt;, &lt;strong&gt;author&lt;/strong&gt;, etc. - basically the things we'd normally declare in the &lt;code&gt;package.json&lt;/code&gt; file&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once the last step is confirmed, we'd have a project directory ready to work on. Here's the folder structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;|____.npmrc
|____.gitignore
|____package.json
|____tsconfig.json
|____wrangler.toml
|____src
  |____index.ts
  |____CfwController.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Part 2: Developing
&lt;/h2&gt;

&lt;p&gt;We can now install the dependencies (as declared in &lt;code&gt;package.json&lt;/code&gt;) with e.g.:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Executing &lt;code&gt;npm run dev&lt;/code&gt; will start the "Worker" on local:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;⎔ Starting local server...
[wrangler:inf] Ready on http://localhost:8787
╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ [b] open a browser, [d] open Devtools, [l] turn off local mode, [c] clear console, [x] to exit                                      │
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Assuming we use the template example provided in the boilerplate (&lt;a href="https://github.com/Thesephi/oak-routing-ctrl-cloudflare-worker/blob/main/src/CfwController.ts" rel="noopener noreferrer"&gt;CfwController.ts&lt;/a&gt;), then we can communicate with the Worker like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl http://localhost:8787/echo/devto

{"query":{},"body":{},"param":{"name":"devto"},"headers":{"accept":"*/*","accept-encoding":"br, gzip","host":"localhost:8787","user-agent":"curl/8.6.0"}}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Part 3: Deploying
&lt;/h2&gt;

&lt;p&gt;To deploy to Cloudflare, one way is simply running&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run deploy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;which will guide us through the Cloudflare authentication flow until the application is fully "uploaded" to Cloudflare.&lt;/p&gt;

&lt;p&gt;Alternatively, if we don't like going through the authentication flow all the time, we can get a &lt;a href="https://developers.cloudflare.com/fundamentals/api/get-started/create-token/" rel="noopener noreferrer"&gt;Cloudflare API token&lt;/a&gt;. Note that, at the minimum, we'll need the permissions to manage "Workers" resources. I chose these for my example:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkjti73q0078gdroxaye0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkjti73q0078gdroxaye0.png" alt="Example of Cloudflare API token permissions to manage Worker resources" width="800" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With the token, one can add it to the env var and run the deployment script e.g. like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;CLOUDFLARE_API_TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;your-cloudflare-api-token npm run deploy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Closing words
&lt;/h2&gt;

&lt;p&gt;I hope the script&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm create oak-cloudflare-worker@latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;may help you bootstrap your Cloudflare Workers project with ease. It is obviously opinionated on the &lt;code&gt;oak&lt;/code&gt; and &lt;code&gt;oak-routing-ctrl&lt;/code&gt; libraries, but also there's nothing preventing one from switching to another supporting framework (or writing everything from scratch).&lt;/p&gt;

&lt;p&gt;If 'starting from scratch' is your flavour, you can also execute &lt;code&gt;npm create cloudflare@latest&lt;/code&gt; (as &lt;a href="https://developers.cloudflare.com/workers/get-started/guide/" rel="noopener noreferrer"&gt;documented&lt;/a&gt;) to start off with an almost-empty Cloudflare Workers project.&lt;/p&gt;

&lt;p&gt;In parallel, a &lt;a href="https://github.com/Thesephi/oak-routing-ctrl-cloudflare-worker" rel="noopener noreferrer"&gt;GitHub code template&lt;/a&gt; also exists as an alternative to running &lt;code&gt;npm create oak-cloudflare-worker&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For transparency: the source code for the &lt;code&gt;npm create&lt;/code&gt; script itself is &lt;a href="https://github.com/Thesephi/create-oak-cloudflare-worker" rel="noopener noreferrer"&gt;hosted here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you've created or plan to create something cool with this script, your story would be so much appreciated in the comment section below 🙏. If you got an idea to improve the script, I'm all ears here, or you may simply &lt;a href="https://github.com/Thesephi/create-oak-cloudflare-worker/pulls" rel="noopener noreferrer"&gt;suggest a PR&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;I wish you enjoyments in your next projects 🍺🍺🍺&lt;/p&gt;

</description>
      <category>worker</category>
      <category>typescript</category>
      <category>oak</category>
      <category>webhook</category>
    </item>
    <item>
      <title>Scaffolding API projects easily with oak-routing-ctrl</title>
      <dc:creator>dk</dc:creator>
      <pubDate>Thu, 20 Jun 2024 22:06:19 +0000</pubDate>
      <link>https://dev.to/thesephi/scaffolding-api-projects-easily-with-oak-routing-ctrl-1pj</link>
      <guid>https://dev.to/thesephi/scaffolding-api-projects-easily-with-oak-routing-ctrl-1pj</guid>
      <description>&lt;p&gt;Greetings to Deno / TypeScript / JavaScript community!&lt;/p&gt;

&lt;p&gt;Today I'd love to introduce a DevTool: &lt;a href="https://jsr.io/@dklab/oak-routing-ctrl" rel="noopener noreferrer"&gt;oak-routing-ctrl&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now if you read the link above &amp;amp; still are unsure what this tool does, then I hope this article may help 😀&lt;/p&gt;

&lt;p&gt;Let's say you:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;wanna build a microservice that provides a set of API to your consumers&lt;/li&gt;
&lt;li&gt;chose the &lt;a href="//oakserver.org"&gt;oak framework&lt;/a&gt; as your HTTP middleware library&lt;/li&gt;
&lt;li&gt;do not want to write repeated routing code for all your API endpoints&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Then &lt;code&gt;oak-routing-ctrl&lt;/code&gt; might be worth a try.&lt;/p&gt;

&lt;p&gt;Here is what's in the box:&lt;/p&gt;

&lt;h2&gt;
  
  
  1. TypeScript Decorators
&lt;/h2&gt;

&lt;p&gt;First we have a set of TypeScript Decorators (conforming to &lt;a href="https://github.com/tc39/proposal-decorators" rel="noopener noreferrer"&gt;TC39 proposal&lt;/a&gt;) that makes it straightforward to declare API endpoints &amp;amp; assign it to a handler function in a few lines of code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// MyController.ts&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Controller&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Get&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@dklab/oak-routing-ctrl@0.9.0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Controller&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyController&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="nf"&gt;doSomething&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hello, dev.to&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. An initiation helper function
&lt;/h2&gt;

&lt;p&gt;Now to actually spin up an HTTP server, we'll need to initiate the server instance e.g. with the middleware &lt;a href="https://jsr.io/@oak/oak" rel="noopener noreferrer"&gt;oak&lt;/a&gt;, and glue it up with the API route handler function we wrote above. Of course it can be in the same file, or a different file, up to your flavour. Here we use a different file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// main.ts&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Application&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@oak/oak@16.1.0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useOakServer&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@dklab/oak-routing-ctrl@0.9.0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;MyController&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./MyController.ts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Application&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nf"&gt;useOakServer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;MyController&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1993&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The example code so far assumes we're on &lt;code&gt;Deno&lt;/code&gt; runtime. But heads up: both &lt;code&gt;oak&lt;/code&gt; and &lt;code&gt;oak-routing-ctrl&lt;/code&gt; &lt;a href="https://github.com/Thesephi/oak-routing-ctrl?tab=readme-ov-file#other-runtimes" rel="noopener noreferrer"&gt;fully support other runtimes&lt;/a&gt; (Bun, Cloudflare Workers, and Node.js).&lt;/p&gt;

&lt;p&gt;With Deno assumed, let's start our server up:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;deno run &lt;span class="nt"&gt;--allow-env&lt;/span&gt; &lt;span class="nt"&gt;--allow-net&lt;/span&gt; main.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And send a test cURL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl localhost:1993
&lt;span class="c"&gt;# prints: hello, dev.to&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That was the most simple form of it. More complex examples are available in the &lt;a href="https://github.com/Thesephi/oak-routing-ctrl?tab=readme-ov-file#example-retrieving-path-parameters" rel="noopener noreferrer"&gt;README&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Looking forward...
&lt;/h2&gt;

&lt;p&gt;Up to this point, you may wonder what's so special about this library. I, as the author, am of course biased, but if you must know: nope, it's indeed "&lt;em&gt;just another DevTool&lt;/em&gt;". I'm not taking pride in its superb performance or any underlying rocket science, I do appreciate the level of care and seriousness I myself put in while developing it. Before it reached the "relatively stable" version of 0.7.4 (at which time I wrote this blog post), it had gone through a valley of alpha releases:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft3n8i3cvynb9y17en4yr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft3n8i3cvynb9y17en4yr.png" alt="screenshot of the oak-routing-ctrl library on its JavaScript Registry page" width="800" height="731"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I don't intend to put much more logic in it from this point on. After using it on production for a while, I'll bump it to 1.0.0. It's released under MIT &amp;amp; anyone can &lt;a href="https://github.com/Thesephi/oak-routing-ctrl/blob/main/CONTRIBUTING.md" rel="noopener noreferrer"&gt;contribute&lt;/a&gt; or even fork their own development directions.&lt;/p&gt;

&lt;p&gt;What I commit to is the &lt;strong&gt;continuous maintenance&lt;/strong&gt; of this library. It is used on production for my own and my employer's web-scale products, thereby giving me "unfair incentives" to keep it sane &amp;amp; performant.&lt;/p&gt;

&lt;p&gt;If you use it for your work, I would really love to hear your thoughts and suggestions, i.e. what you like, what you don't like. A GitHub &lt;a href="https://github.com/Thesephi/oak-routing-ctrl" rel="noopener noreferrer"&gt;Star&lt;/a&gt;, or a constructive feedback issue, to me is equally valuable.&lt;/p&gt;

&lt;p&gt;If I still have you on this line, it means my English skill is not any more rusty than my coding skill ;) and it means the world to me (😀). If you feel I missed something, or said something contrary to your knowledge, please feel free to place your questions in the comment section down below. Discussing tech topics is the best way for everyone to learn!&lt;/p&gt;

&lt;p&gt;Thank you for your time on this blog post. Have a blast in what you're doing, wherever you are 🍻&lt;/p&gt;

</description>
      <category>deno</category>
      <category>typescript</category>
      <category>api</category>
      <category>tooling</category>
    </item>
  </channel>
</rss>
