<?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: Chukwuemeka Igbokwe</title>
    <description>The latest articles on DEV Community by Chukwuemeka Igbokwe (@chukwuemekaigbokwe).</description>
    <link>https://dev.to/chukwuemekaigbokwe</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F368617%2Ff96c2f56-e714-4c92-ad19-3ac749e4a749.jpeg</url>
      <title>DEV Community: Chukwuemeka Igbokwe</title>
      <link>https://dev.to/chukwuemekaigbokwe</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/chukwuemekaigbokwe"/>
    <language>en</language>
    <item>
      <title>Chuks v0.2.0-rc.1 Is Out, We Need You to Try to Break It</title>
      <dc:creator>Chukwuemeka Igbokwe</dc:creator>
      <pubDate>Sat, 19 Sep 2026 07:06:49 +0000</pubDate>
      <link>https://dev.to/chukwuemekaigbokwe/chuks-v020-rc1-is-out-we-need-you-to-try-to-break-it-31ah</link>
      <guid>https://dev.to/chukwuemekaigbokwe/chuks-v020-rc1-is-out-we-need-you-to-try-to-break-it-31ah</guid>
      <description>&lt;p&gt;Chuks v0.2.0-rc.1 is live, and unlike our last few release posts, this one isn't "here's what shipped." It's an ask.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What we need&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Chuks compiles two ways: a bytecode VM you develop against, and a native binary you ship. Every release lives or dies on those two modes computing the same thing. We have a serious internal gate for that, golden tests on both backends, a differential fuzzer, 24 differential suites, cross-compilation to five targets. What that gate can't do is run a program it's never seen.&lt;/p&gt;

&lt;p&gt;So here's the ask: build something with rc.1, or point an existing program at it, and run it both ways.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;chuks run main.chuks    #&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;the bytecode VM
&lt;span class="gp"&gt;chuks build main.chuks  #&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;the native binary
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If they don't agree, byte for byte, on everything the program prints, that's a bug we want. &lt;a href="https://github.com/chuks-programming-language/releases/issues/new?template=bug_report.yml" rel="noopener noreferrer"&gt;File it here&lt;/a&gt; with chuks --version and the smallest file that shows it.&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="c"&gt;# already have Chuks&lt;/span&gt;
chuks upgrade &lt;span class="nt"&gt;--prerelease&lt;/span&gt;

&lt;span class="c"&gt;# first install&lt;/span&gt;
curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://chuks.org/install.sh | bash &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; chuks upgrade &lt;span class="nt"&gt;--prerelease&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A plain &lt;code&gt;chuks upgrade&lt;/code&gt; stays on v0.1.2 until v0.2.0 actually ships, this is opt-in.&lt;/p&gt;

&lt;p&gt;Why this matters more than usual this time&lt;/p&gt;

&lt;p&gt;Most of what's fixed in rc.1 wasn't found by a test. It was found by building real programs. Two examples, because they show why "someone else's program" is the thing our gate structurally can't replace.&lt;/p&gt;

&lt;p&gt;A precedence bug that produced two different wrong answers. &lt;code&gt;await&lt;/code&gt; and &lt;code&gt;spawn&lt;/code&gt; used to bind to the wrong side of an expression:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;f&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;]&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This used to parse as &lt;code&gt;await (f() + "]")&lt;/code&gt; awaiting the string concatenation instead of the call. The VM printed &lt;code&gt;"Task(pending)"&lt;/code&gt;. The native binary printed &lt;code&gt;"0"&lt;/code&gt;. Same source, two backends, two different wrong answers, because the bug was in the grammar itself, not in either backend's implementation of a correctly-parsed program. Our differential fuzzer generates programs; it doesn't yet think like someone writing an async pipeline by hand, which is exactly how this surfaced.&lt;/p&gt;

&lt;p&gt;A closure bug that both backends agreed on, and were both wrong about. This is the more interesting failure mode:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;fns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;fns&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;// every fn used to return 3, on BOTH the VM and the native binary&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every closure made in a loop was reading one shared binding instead of its own per-iteration value, on both backends, identically. Our differential testing checks that the VM and native binary agree. It does not check that what they agree on is correct. They agreed here, and they were both wrong, in exactly the way &lt;code&gt;var&lt;/code&gt; in a pre-&lt;code&gt;let&lt;/code&gt; JavaScript loop was wrong. Fixed now: each pass gets its own binding.&lt;/p&gt;

&lt;p&gt;That second one is why we're asking for outside testing specifically. Agreement between two backends is necessary but not sufficient, it can't catch a bug baked into both from the start. Only someone hitting the actual behavior, expecting something else, catches that.&lt;/p&gt;

&lt;h2&gt;
  
  
  Also in this RC
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;String indexing now counts bytes consistently on both backends, with accessors like &lt;code&gt;at/slice&lt;/code&gt; snapping to whole Unicode characters, this used to differ between the VM (characters) and native (bytes) for some methods.&lt;/li&gt;
&lt;li&gt;A dropped &lt;code&gt;spawn&lt;/code&gt;'d task's failure used to disappear silently. It's reported now, at exit for a CLI program, immediately for an embedding host.&lt;/li&gt;
&lt;li&gt;Reserved words are usable as field/key names now (&lt;code&gt;dataType Rec { from: string, class: string }&lt;/code&gt;), a payload's fields aren't the language's to rename.&lt;/li&gt;
&lt;li&gt;Generic base classes now work correctly across module boundaries, with this reflection (&lt;code&gt;json.stringify(this)&lt;/code&gt;) seeing the whole object, subclass fields included, identically on both backends.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Full changelog, including all the breaking changes and exact migration notes: &lt;a href="//chuks.org/blog/chuks-v020-rc1-the-release-candidate"&gt;chuks.org/blog/chuks-v020-rc1-the-release-candidate&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you try it and it breaks, that's the best possible outcome for this post. File it.&lt;/p&gt;

</description>
      <category>chukslang</category>
      <category>go</category>
      <category>compilers</category>
      <category>programming</category>
    </item>
    <item>
      <title>Chuks v0.1.1, The Correctness Release</title>
      <dc:creator>Chukwuemeka Igbokwe</dc:creator>
      <pubDate>Sat, 05 Sep 2026 04:52:16 +0000</pubDate>
      <link>https://dev.to/chukwuemekaigbokwe/chuks-v011-the-correctness-release-262o</link>
      <guid>https://dev.to/chukwuemekaigbokwe/chuks-v011-the-correctness-release-262o</guid>
      <description>&lt;p&gt;Chuks has two execution modes: a bytecode VM you develop against, and a native binary you ship. v0.1.1 is about making them agree everywhere, down to the last digit of an IEEE-754 float.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://chuks.org" rel="noopener noreferrer"&gt;Chuks&lt;/a&gt; runs your code two ways.&lt;/p&gt;

&lt;p&gt;A bytecode VM you develop against, it starts instantly, so the edit-run loop feels like a scripting language. And a native binary you ship, the compiler lowers your program to native code ahead of time, so production is fast. Code like a script, ship like a binary.&lt;/p&gt;

&lt;p&gt;That design only earns its keep if both modes compute the same thing. If a program behaves one way while you develop and another way once you ship, the two-mode model is a liability, not a feature. v0.1.1 is the release that makes them agree, everywhere they are asked to, down to the last digit.&lt;/p&gt;

&lt;p&gt;Where v0.1.0 was about speed, this one is about correctness. The headline numbers: 220 commits since v0.1.0, 446 files changed (+33,070 / -2,098), all 407 golden tests green on both the VM and as a native binary, 1,404 differential cells across 17 suites, and a ten-stage release preflight clean.&lt;/p&gt;

&lt;p&gt;Here is what that meant in practice.&lt;/p&gt;

&lt;h2&gt;
  
  
  Agreement to the last ULP
&lt;/h2&gt;

&lt;p&gt;The most instructive fix in this release is a floating-point one, because it shows exactly the standard Chuks holds itself to.&lt;/p&gt;

&lt;p&gt;The n-body benchmark computed two different results depending on how it was run. As a native binary it printed 0.013051029850722899; on the VM it printed 0.009171719055316834. We checked against three other IEEE-754 runtimes, all three agreed with the VM, to the last digit. The native binary was the outlier.&lt;/p&gt;

&lt;p&gt;The cause was a fused multiply-add. The native backend was contracting &lt;code&gt;a * b + c&lt;/code&gt; into a single instruction, which keeps the intermediate product at full internal precision through the addition and rounds once instead of twice. That sounds more accurate, and in isolation it is, but IEEE-754 prescribes a specific sequence with a specific rounding at each step, and every conforming runtime follows it. A fused multiply-add lands one unit in the last place, one ULP from the value the standard specifies.&lt;/p&gt;

&lt;p&gt;One ULP is the last digit of a sixteen-digit number. Invisible in a short program. But the first divergence appeared in exactly the shape a compiler wants to fuse:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dx * dx + dy * dy + dz * dz
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run 500,000 times, each result feeding the next, that one-ULP gap compounded into a difference you could read off the screen.&lt;/p&gt;

&lt;p&gt;Every float multiply is now rounded explicitly before anything can fuse it. Chuks and every other IEEE-754 runtime now print the same number.&lt;/p&gt;

&lt;p&gt;The fix costs about 11% on the most multiply-heavy loop in the benchmark set; roughly half of that came back from computing a repeated array-element read once instead of six times. The rest is gone, and we kept the fix anyway. The lost speed was the speed of a wrong answer, and there is no version of this that keeps both.&lt;/p&gt;

&lt;p&gt;The lasting part is the guard. We added a differential suite of 17 shapes covering every adjacency of a multiply to an addition, crossed with every path an operand takes to reach it. The inputs are adversarial, a case only counts if fusing genuinely changes the answer, and each carries the exact value computed in rational arithmetic, not just the VM's output. That last detail is what makes it airtight: if both backends were wrong the same way, comparing them to each other would prove nothing. Checking against a hand-computed exact value means two backends that agree with each other but not with IEEE-754 still fail. All 17 shapes fail without the fix.&lt;/p&gt;

&lt;h2&gt;
  
  
  How these bugs surface
&lt;/h2&gt;

&lt;p&gt;Chuks has been carrying real software for several releases, a package registry and its frontend, HTTP services, a growing package ecosystem, an editor backend. Those programs turned up most of what v0.0.7 through v0.1.0 fixed, and they keep doing that job.&lt;/p&gt;

&lt;p&gt;What this cycle added was a different kind of pressure. A mobile framework is a large program whose generics cross package boundaries constantly: a class in one package specialized on a type from another, a specialization that has to be emitted somewhere neither package owns, closures capturing module state, the same private name declared in three files. And it runs on two targets that must agree, which turns any disagreement into a visible bug rather than a latent one. That combination is what shook these fixes loose, not because earlier releases were only tested, but because this workload leans hardest on the seam this release is about.&lt;/p&gt;

&lt;p&gt;One example, because it is representative. A generic function's specialization carries a map of type arguments, and by that stage the map holds compiled types, not Chuks ones. Naming the specialized class converted them back to Chuks names first, and that inverse only handled primitives. A class argument fell through to the opaque case, so the compiler emitted a reference to a &lt;code&gt;Cell_ptr_any&lt;/code&gt; that nothing ever generated. The program ran perfectly on the VM and failed to build as a binary.&lt;/p&gt;

&lt;p&gt;The fix removed the round trip. The lasting part, again, is the guard: a class type argument axis was added to the generics differentials, because only a class argument makes a type-map value a pointer. That axis immediately found two more bugs, one of them a cross-package import cycle.&lt;/p&gt;

&lt;p&gt;The rule that came out of it:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A real consumer build is the compiler's best fuzzer, and every bug it finds is converted into a generated test axis rather than a single regression case.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is why the battery grew by three axes this cycle instead of by forty-eight one-off tests. An axis is a permanent net; a regression test is a single caught fish.&lt;/p&gt;

&lt;h2&gt;
  
  
  Live imports
&lt;/h2&gt;

&lt;p&gt;The one behavioral change worth reading carefully. Previously the VM copied an imported module-level variable at import time, while the native compiler read the exporter's current value, so the same program could print different numbers in development and in a release build.&lt;/p&gt;

&lt;p&gt;In Chuks, an import is a live binding: a window onto the exporting module, not a snapshot of it. The VM is what changed to match.&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;// counter.chuks&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;total&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;total&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;total&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// main.chuks&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;total&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;add&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;./counter.chuks&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;total&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;   &lt;span class="c1"&gt;// 0&lt;/span&gt;
&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;total&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;   &lt;span class="c1"&gt;// 5, in both execution modes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three consequences:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A binding is live. Reading an imported name always sees the exporting module's current value.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assigning to an imported name is a compile error. It is a read-only view, export a setter instead. Aliasing doesn't create a writable copy: &lt;code&gt;import { f as g }&lt;/code&gt; gives you &lt;code&gt;g&lt;/code&gt;, not &lt;code&gt;f&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A module is one instance per run. It used to be re-initialized for every importer, so its side effects ran once per importer and any accumulated state was discarded.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you were relying on the old copy behavior, the compiler tells you at the assignment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reading a map yields an optional
&lt;/h2&gt;

&lt;p&gt;The other breaking change, and worth reading. A key that is not present has no value, so reading a typed map gives you an optional:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;stock&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"apples"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"pears"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;stock&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"kiwis"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;      &lt;span class="c"&gt;// true&lt;/span&gt;
&lt;span class="n"&gt;stock&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"pears"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;      &lt;span class="c"&gt;// false - a stored zero is a value, not an absence&lt;/span&gt;
&lt;span class="n"&gt;stock&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"kiwis"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="err"&gt;??&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;         &lt;span class="c"&gt;// 0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Previously this was &lt;code&gt;null&lt;/code&gt; on the VM and the zero value in a native build, and the difference was not cosmetic: &lt;code&gt;m[k] + 5&lt;/code&gt; printed a number as a binary and aborted the VM with a type mismatch. The same source working when shipped and dying in development is the worst shape a bug can take.&lt;/p&gt;

&lt;p&gt;The migration is &lt;code&gt;?? default&lt;/code&gt;, and it is free, that form compiles to a single lookup that never builds an optional, measured at the same speed as the old unchecked index over two million reads. A null check narrows the type, so &lt;code&gt;if (m[k] != null) { total = total + m[k] }&lt;/code&gt; works too. &lt;code&gt;.get(k)&lt;/code&gt;, &lt;code&gt;.getOr(k, d)&lt;/code&gt;, and &lt;code&gt;.has(k)&lt;/code&gt; are unchanged.&lt;/p&gt;

&lt;h2&gt;
  
  
  Generics across packages
&lt;/h2&gt;

&lt;p&gt;Generics that stay inside one module were already solid. This release fixes what happens when a specialization has to be placed somewhere. The specialization of a generic from package A on a type from package B is emitted in B, next to the type, because A cannot import its own consumer. Nested arguments pin to the innermost class, so &lt;code&gt;Box&amp;lt;Box&amp;lt;Node&amp;gt;&amp;gt;&lt;/code&gt; lands where &lt;code&gt;Node&lt;/code&gt; lives rather than where &lt;code&gt;Box&lt;/code&gt; does. A function specialization emitted into a foreign package qualifies its reads and its writes of the defining module's variables, and declared types of module-level variables are now published across packages so a reader no longer treats a typed value as opaque.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mobile: a real development loop
&lt;/h2&gt;

&lt;p&gt;The mobile toolchain gained a proper edit-reload loop. &lt;code&gt;chuks pack&lt;/code&gt; collects an app and its dependencies into a single source bundle, &lt;code&gt;chuks serve&lt;/code&gt; serves it with hot reload, and the Chuks Mobile Runtime (CMR) is an on-device VM that runs it. The device needs no compiler toolchain and no framework source, and a save reaches the running app as a delta. &lt;code&gt;chuks pack&lt;/code&gt; type-checks and fails closed, a bundle that doesn't compile is never served, and when something fails at runtime the host shows a red error card with the file and line, built from a structured payload with clean paths, a code frame, and a filtered stack.&lt;/p&gt;

&lt;p&gt;Underneath it, &lt;code&gt;--c-archive&lt;/code&gt; lets the AOT compiler emit a C-ABI bridge, which is what allows a native host a UIKit or Android app, to embed a compiled Chuks program in the first place.&lt;/p&gt;

&lt;h2&gt;
  
  
  Streaming HTTP, both ways
&lt;/h2&gt;

&lt;p&gt;Server-Sent Events on the server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sse&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;tick&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;end&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and a pull-based streaming client, so a response is consumed as it arrives rather than buffered whole:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;stream&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;GET&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also in this cycle: generic type inference (a generic call's type arguments are inferred from its arguments into the result type, so &lt;code&gt;useState("")&lt;/code&gt; is a &lt;code&gt;Cell&amp;lt;string&amp;gt;&lt;/code&gt; with no annotation), and as now accepts an interface, a generic instantiation, and a union, previously only a bare class name or a primitive.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where Chuks stands
&lt;/h2&gt;

&lt;p&gt;Nine benchmarks, five languages, best of seven runs on an M4 Max. Outputs are compared before any timing is reported, a benchmark where two languages compute different things is not a benchmark, and two of these were doing exactly that until this release.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1uk6rcwnwpzqi1wyoxwr.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1uk6rcwnwpzqi1wyoxwr.png" alt="Chukslang is faster than Bun, Java, Python" width="800" height="464"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Milliseconds, lower is better.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Read honestly: startup floors the small numbers. Chuks starts in 2.3ms, Bun 5.1ms, Python 12.2ms, Java 20.8ms, so the whole Java column below about 25ms is JVM startup rather than work.&lt;/p&gt;

&lt;p&gt;Chuks takes seven of nine against Bun and eight of nine against Java, and leads Python by between four and two-hundred-and-fifty times. The two it loses are allocation-heavy and hash-heavy, and one has a known cause: &lt;code&gt;values()&lt;/code&gt; and &lt;code&gt;keys()&lt;/code&gt; sort their keys for a deterministic order, which is 14.75ms of a 17.6ms call on a map of 100,000 entries. That is the next piece of performance work, not a mystery.&lt;/p&gt;

&lt;p&gt;The n-body row carries the footnote from earlier. The correctness fix cost 0.9ms there. Every runtime in that table computes &lt;code&gt;0.009171719055316834&lt;/code&gt;, and so does Chuks. Buying that 0.9ms back would mean printing a different number than everybody else.&lt;/p&gt;

&lt;h2&gt;
  
  
  Upgrading
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;chuks upgrade
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two changes can break existing code, and both report themselves at the line responsible:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Assignment to an imported binding is a compile error. Export a setter instead.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Reading a typed map yields &lt;code&gt;V?&lt;/code&gt;. Add &lt;code&gt;?? default&lt;/code&gt; where a value is required, also the fastest form, or bind it and check for &lt;code&gt;null&lt;/code&gt; where absence means something.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Everything else in this release makes programs that already worked on the VM behave the same way as a native binary.&lt;/p&gt;

&lt;p&gt;That is what the Correctness Release is: not a headline feature, but a promise that the thing you develop against and the thing you ship compute the same answer, verified across 1,404 differential cells, and held even when the correct answer is the slower one.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://chuks.org" rel="noopener noreferrer"&gt;Try Chuks at chuks.org&lt;br&gt;
&lt;/a&gt;&lt;/p&gt;

</description>
      <category>compilers</category>
      <category>programming</category>
      <category>chukslang</category>
      <category>performance</category>
    </item>
    <item>
      <title>Chuks v0.1.0: unboxing the hot path (and a 58x speedup hiding in `any`)</title>
      <dc:creator>Chukwuemeka Igbokwe</dc:creator>
      <pubDate>Mon, 29 Jun 2026 13:44:15 +0000</pubDate>
      <link>https://dev.to/chukwuemekaigbokwe/chuks-v010-unboxing-the-hot-path-and-a-58x-speedup-hiding-in-any-16fc</link>
      <guid>https://dev.to/chukwuemekaigbokwe/chuks-v010-unboxing-the-hot-path-and-a-58x-speedup-hiding-in-any-16fc</guid>
      <description>&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fprmphclkdb1olpt4x3pn.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fprmphclkdb1olpt4x3pn.png" alt=" " width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A loop counter should not allocate memory. An accumulator that only ever holds an &lt;code&gt;int&lt;/code&gt; should not be boxed, unboxed, and re-boxed on every iteration. Obvious, and yet for nine releases that is exactly what our runtime was doing.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://chuks.org" rel="noopener noreferrer"&gt;Chuks&lt;/a&gt; spent its whole &lt;code&gt;0.0.x&lt;/code&gt; line on correctness and feature breadth. &lt;strong&gt;v0.1.0, landing July 2026, is about speed.&lt;/strong&gt; Both execution backends, the bytecode VM and the ahead-of-time (AOT) native compiler, got a deep performance pass, and the numbers moved a lot. Here is the interesting part of how.&lt;/p&gt;

&lt;h2&gt;
  
  
  The boxing tax
&lt;/h2&gt;

&lt;p&gt;In a dynamically-shaped runtime, every value on the stack is usually a boxed object: a pointer to a heap cell that carries its type. That is fine for genuinely dynamic data. It is a disaster in a tight numeric loop, where a single &lt;code&gt;i + 1&lt;/code&gt; becomes unbox, add, re-box, allocate. Multiply by a few hundred million iterations and you are not measuring arithmetic, you are measuring the garbage collector.&lt;/p&gt;

&lt;p&gt;The fix is to prove the type statically and keep the value unboxed. We did that on both backends.&lt;/p&gt;

&lt;h2&gt;
  
  
  The VM: typed slots
&lt;/h2&gt;

&lt;p&gt;The bytecode VM now keeps &lt;strong&gt;parallel unboxed stacks and local-variable arrays&lt;/strong&gt; for &lt;code&gt;int&lt;/code&gt;, &lt;code&gt;float&lt;/code&gt;, and &lt;code&gt;bool&lt;/code&gt;, alongside the existing boxed object stack. When the compiler can statically prove a value's type, it emits typed load/store and typed arithmetic opcodes (&lt;code&gt;OP_ILOAD&lt;/code&gt;, &lt;code&gt;OP_FSTORE&lt;/code&gt;, the typed arithmetic family) that operate directly on those stacks. It only crosses into the boxed world when it has to, through explicit &lt;code&gt;OP_BOX&lt;/code&gt; / &lt;code&gt;OP_UNBOX&lt;/code&gt; bridge ops, and a typed peephole pass then cancels redundant box/unbox pairs and fuses common sequences into super-instructions.&lt;/p&gt;

&lt;p&gt;The result: the arithmetic-heavy paths the VM cares about most now run without touching the heap. You write the same code. The compiler picks the typed path.&lt;/p&gt;

&lt;h2&gt;
  
  
  The AOT compiler: inlining array reads
&lt;/h2&gt;

&lt;p&gt;The native compiler had a subtler problem. It splits its output into a &lt;code&gt;main&lt;/code&gt; package and a &lt;code&gt;crt&lt;/code&gt; runtime package, and typed-slice reads were going through a generic &lt;code&gt;__idx_slice[T]()&lt;/code&gt; helper. Generic functions cannot inline across a package boundary, so every &lt;code&gt;arr[i]&lt;/code&gt; in a hot loop became a real cross-package &lt;code&gt;CALL&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;v0.1.0 emits &lt;strong&gt;non-generic, per-type read helpers&lt;/strong&gt; instead (&lt;code&gt;__idx_slice_i64&lt;/code&gt;, &lt;code&gt;__idx_slice_f64&lt;/code&gt;, &lt;code&gt;__idx_slice_str&lt;/code&gt;, &lt;code&gt;__idx_slice_bool&lt;/code&gt;). Those are monomorphic, so they inline across the boundary. The out-of-range slow path is routed through a package-level function variable to keep it out of the fast helper, and the friendly catchable error is preserved:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;index 10 out of range [0:3]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You still write &lt;code&gt;arr[i]&lt;/code&gt;. The compiler takes the fast path whenever the array holds a primitive.&lt;/p&gt;

&lt;h3&gt;
  
  
  Warm benchmarks (min ms, arm64, lower is better)
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Workload&lt;/th&gt;
&lt;th&gt;v0.0.9 AOT&lt;/th&gt;
&lt;th&gt;v0.1.0 AOT&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;nbody&lt;/td&gt;
&lt;td&gt;110&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;15&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;matrix&lt;/td&gt;
&lt;td&gt;20&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;6&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;sort&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;6&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;nbody got about 7x faster and now runs at native speed.&lt;/strong&gt; The residual on matrix and sort is bounds-checked native writes, which is the irreducible cost of safe array access.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 58x hiding in &lt;code&gt;any&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Here is my favorite one, because it is a trap every developer falls into.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;any&lt;/code&gt; exists for genuinely dynamic data: a request body, a parsed JSON value, a heterogeneous list. But it is easy to reach for when the value is really just one type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var sum: any = 0
for (var i = 0; i &amp;lt; 300_000_000; i = i + 1) {
    sum = sum + i
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That used to cost you everything. Each &lt;code&gt;sum + i&lt;/code&gt; boxed the value and dispatched through a dynamic-type helper at runtime. The compiler now &lt;strong&gt;proves when an &lt;code&gt;any&lt;/code&gt; local only ever holds a single concrete type&lt;/strong&gt; and stores it unboxed as that type, so the operations run directly: no boxing, no dispatch.&lt;/p&gt;

&lt;p&gt;That 300M-iteration loop dropped from &lt;strong&gt;3.5s to 0.07s. About 58x faster, with no code change.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The honest framing matters: genuinely-dynamic &lt;code&gt;any&lt;/code&gt; still boxes, because it must, the type is unknown until runtime. So this is pure upside. The "accidental &lt;code&gt;any&lt;/code&gt;" tax is gone, and &lt;code&gt;any&lt;/code&gt; still means exactly what it should. It is the native counterpart of the VM's typed slots, and the same idea shows up again in control flow (typed compares now feed unboxed branches with no boolean allocated per iteration) and in linked structures (a nullable class type lowers to a direct, unboxed pointer link).&lt;/p&gt;

&lt;h2&gt;
  
  
  Speed was not the only headline
&lt;/h2&gt;

&lt;p&gt;A performance release is a good excuse to ship the things that needed the performance work to be safe. A few that I think matter most:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A data race that is now a compile error.&lt;/strong&gt; The most common concurrency bug for people arriving from Node, Python, Java, or C# is a stateful object (a query builder, a service) shared across requests and mutated inside an async handler. It passes every test, works in dev, then corrupts data under load. Chuks now catches it statically: if a class whose methods mutate &lt;code&gt;this&lt;/code&gt; is shared and a mutator is called without a &lt;code&gt;lock&lt;/code&gt;, the program does not compile. The error names the three fixes (make it task-local, move its state into the task context, or wrap it in &lt;code&gt;lock(...)&lt;/code&gt;). Read-only sharing stays legal, single-threaded code is untouched, and a self-synchronizing class can opt out with &lt;code&gt;@threadSafe&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real infrastructure, written in the language.&lt;/strong&gt; A complete gRPC stack (HTTP/2 framing and HPACK, Protocol Buffers, all four RPC kinds, metadata, deadlines, TLS/mTLS, reflection) was built entirely in Chuks this cycle. So were two production data clients: &lt;code&gt;@chuks/mongo&lt;/code&gt; (a hand-rolled BSON codec, the OP_MSG wire protocol, and SCRAM-SHA-256 auth, with typed &lt;code&gt;Model&amp;lt;T&amp;gt;&lt;/code&gt; over a &lt;code&gt;dataType&lt;/code&gt;, 62/62 against MongoDB 7.0) and &lt;code&gt;@chuks/kafka&lt;/code&gt; (the Kafka binary protocol end to end, 65/65). Building on real wire protocols is the best stress test there is: &lt;code&gt;@chuks/mongo&lt;/code&gt; alone surfaced and fixed eight latent compiler defects.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A full debugger.&lt;/strong&gt; A complete debug adapter: conditional, function, and exception breakpoints, hit counts, logpoints, real-name variables, and a Watch console that evaluates real Chuks expressions against the paused frame (including function and method calls, on a separate evaluator so inspecting state never disturbs it), plus &lt;code&gt;setVariable&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Unicode-correct strings.&lt;/strong&gt; &lt;code&gt;for ... of&lt;/code&gt; now walks code points, not bytes, so multi-byte characters and emoji come through whole, with a new &lt;code&gt;runeCount()&lt;/code&gt; and locale-aware case conversion.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A browser playground.&lt;/strong&gt; The VM now compiles to WebAssembly, so you can run Chuks in the browser with no install.&lt;/p&gt;

&lt;h2&gt;
  
  
  The throughline: one language, two backends, kept honest
&lt;/h2&gt;

&lt;p&gt;Every feature above behaves &lt;strong&gt;identically on the VM and as a native binary&lt;/strong&gt;. That is not a hope, it is a test: a differential fuzzer generates programs in four shapes (single-file, multi-module, deep-recursion, and large-data), runs each through both backends, and diffs the output. A separate coverage-guided typechecker fuzzer hammers the shared frontend. The golden suite now runs &lt;strong&gt;339 tests green on both backends&lt;/strong&gt;, with the fuzzer reporting 100% agreement across hundreds of generated programs. Several of the speedups in this post exist because a fuzzer found the divergence first.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;p&gt;v0.1.0 is in preview now, with the stable release landing in July.&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="c"&gt;# First-time install&lt;/span&gt;
curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://chuks.org/install.sh | &lt;span class="nv"&gt;CHUKS_PRERELEASE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1 bash

&lt;span class="c"&gt;# Already have Chuks&lt;/span&gt;
chuks upgrade &lt;span class="nt"&gt;--prerelease&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then re-run your benchmarks. The VM no longer boxes the hot path, and native array reads finally inline cleanly.&lt;/p&gt;

&lt;p&gt;Docs and the full changelog are at &lt;a href="https://chuks.org" rel="noopener noreferrer"&gt;chuks.org&lt;/a&gt;. If you build something with it, I would love to see it.&lt;/p&gt;

</description>
      <category>chuks</category>
      <category>chukslang</category>
      <category>programming</category>
      <category>ai</category>
    </item>
    <item>
      <title>Chuks Language Data Types</title>
      <dc:creator>Chukwuemeka Igbokwe</dc:creator>
      <pubDate>Fri, 01 May 2026 18:08:20 +0000</pubDate>
      <link>https://dev.to/chukwuemekaigbokwe/chuks-language-data-types-281l</link>
      <guid>https://dev.to/chukwuemekaigbokwe/chuks-language-data-types-281l</guid>
      <description>&lt;h2&gt;
  
  
  Stop fighting your data. Let dataType win.
&lt;/h2&gt;

&lt;p&gt;Most languages make you choose between the safety of structs and the convenience of maps. Chuks gives you both, with built-in validation, generics, embedding, and nullable safety baked right into the type system.&lt;/p&gt;

&lt;p&gt;chuks dataType is a lightweight, fields-only container. No constructor boilerplate. No class overhead. Initialize with a map literal and the compiler checks every field.&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%2Fhs1urypos6gncc7g91aj.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%2Fhs1urypos6gncc7g91aj.png" alt="chuks dataType" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a class="mentioned-user" href="https://dev.to/validate"&gt;@validate&lt;/a&gt;: one annotation, full validation.
&lt;/h2&gt;

&lt;p&gt;Attach validation rules directly to fields. Call validate(x) and get back every error. No third-party library. No schema duplication. It lives with your data.&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%2Fhzzfqttfbxwwa5sdigk5.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%2Fhzzfqttfbxwwa5sdigk5.png" alt="Chuks dataType with validation" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Custom validators: your rules, first class
&lt;/h2&gt;

&lt;p&gt;Need a strongPassword rule? Write a function, annotate it with @validator, and use it in any dataType across your whole codebase, including imported modules.&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%2F7yo9r1qy30iisqi7vhp1.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%2F7yo9r1qy30iisqi7vhp1.png" alt="chuks dataType custom validation" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nullable types + type narrowing&lt;/strong&gt;&lt;br&gt;
Append ? to any type and it can hold null. Chuks does control-flow analysis, after a null guard, the compiler narrows the type automatically. No casts. No optional chaining syntax. The compiler just knows.&lt;/p&gt;

&lt;h2&gt;
  
  
  Embedding: compose shapes, not hierarchies
&lt;/h2&gt;

&lt;p&gt;Embed one dataType inside another, and its fields are promoted directly. The Go embedding model without the Go verbosity. Perfect for Auditable, Identifiable, and any shared schema pattern.&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%2F2kkbi03tdcggh6iv07rl.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%2F2kkbi03tdcggh6iv07rl.png" alt="chuks dataType embadding" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a class="mentioned-user" href="https://dev.to/json"&gt;@json&lt;/a&gt; — rename fields for the wire
&lt;/h2&gt;

&lt;p&gt;Your internal field names stay clean. Your API contract stays happy. One annotation handles both serialization and parsing, no mapping layer needed.&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%2F46m5djsgefxeq8in01cp.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%2F46m5djsgefxeq8in01cp.png" alt="chuks dataType Json" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Read more &lt;a href="https://chuks.org" rel="noopener noreferrer"&gt;chuks&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Follow chukslang on X: &lt;a href="https://x.com/Chukslang" rel="noopener noreferrer"&gt;https://x.com/Chukslang&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Join chukslang community: &lt;a href="https://cleset.com/community/ChuksProgrammingLanguage?t=567d480d-7a28-4782-b8d0-db097adc2010" rel="noopener noreferrer"&gt;https://cleset.com/community/ChuksProgrammingLanguage?t=567d480d-7a28-4782-b8d0-db097adc2010&lt;/a&gt; &lt;/p&gt;

</description>
      <category>chukslang</category>
      <category>backenddevelopment</category>
      <category>programming</category>
      <category>backend</category>
    </item>
    <item>
      <title>Chuks, A New Programming Language That Outperforms Go on HTTP Throughput</title>
      <dc:creator>Chukwuemeka Igbokwe</dc:creator>
      <pubDate>Wed, 18 Mar 2026 19:50:01 +0000</pubDate>
      <link>https://dev.to/chukwuemekaigbokwe/chuks-a-new-programming-language-that-outperforms-go-on-http-throughput-4n31</link>
      <guid>https://dev.to/chukwuemekaigbokwe/chuks-a-new-programming-language-that-outperforms-go-on-http-throughput-4n31</guid>
      <description>&lt;p&gt;Hi i've been building a programming language called Chuks, and it just hit v0.0.6. Here's why I think it's worth your attention.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is Chuks?&lt;/strong&gt;&lt;br&gt;
Chuks bridges scripting-language simplicity with compiled-language performance. Think TypeScript's developer experience, Go's deployment model, and a runtime that's faster than both.&lt;/p&gt;

&lt;p&gt;It ships as a single binary with a VM, AOT compiler, built-in HTTP server, 4 SQL database drivers, structured concurrency, and 30+ standard library modules — all included, no packages required.&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createServer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Response&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;std/http&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createServer&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="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;{"status": "ok"}&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="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="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's a production-grade, multi-threaded HTTP server in 8 lines.&lt;/p&gt;

&lt;p&gt;The Numbers&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%2Fjef7zeuillq9eob7kuaw.jpeg" 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%2Fjef7zeuillq9eob7kuaw.jpeg" alt="Chuks Performance Benchmark" width="800" height="510"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Chuks beats Go on Fibonacci, matches it on N-Body, and is 2–5x faster than Java and Node.js across the board. It's 60–255x faster than Python.&lt;/p&gt;

&lt;p&gt;How?&lt;br&gt;
Chuks compiles to Go source via AOT, then to native machine code. The AOT compiler produces devirtualized method dispatch, typed arithmetic, and zero-cost nil checks — code that's nearly identical to hand-written Go.&lt;/p&gt;

&lt;p&gt;It handles requests across all CPU cores by default.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What Makes Chuks Different&lt;/strong&gt;&lt;br&gt;
Dual execution modes. Run with &lt;code&gt;chuks run&lt;/code&gt; (VM for rapid development) or build with &lt;code&gt;chuks build&lt;/code&gt; (AOT for production). No other language offers both.&lt;/p&gt;

&lt;p&gt;True structured concurrency. &lt;code&gt;spawn&lt;/code&gt; runs any function in parallel. &lt;code&gt;async/await&lt;/code&gt; handles I/O. Parent task cancellation automatically cascades to children — no leaked Promises, no dangling goroutines.&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="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handleRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="nx"&gt;Task&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="na"&gt;userTask&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Task&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;spawn&lt;/span&gt; &lt;span class="nf"&gt;fetchUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="na"&gt;ordersTask&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Task&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;spawn&lt;/span&gt; &lt;span class="nf"&gt;fetchOrders&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;userTask&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="na"&gt;orders&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;ordersTask&lt;/span&gt;

    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;orders&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;orders&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;p&gt;Batteries included. The standard library covers HTTP, JSON, JWT, crypto, validation, rate limiting, UUID, regex, logging, channels, TCP/TLS, file I/O, and 4 built-in SQL drivers (SQLite, PostgreSQL, MySQL, MSSQL).&lt;/p&gt;

&lt;p&gt;Growing package ecosystem. Redis, Kafka, RabbitMQ, MongoDB, Elasticsearch, gRPC, NATS, WebSocket, S3, SMTP, GraphQL, OpenAPI, OAuth, OpenTelemetry, cron, CSV, XML, YAML — all available as packages.&lt;/p&gt;

&lt;p&gt;Tooling from day one. VS Code extension with syntax highlighting, LSP, and snippets. Built-in debugger (DAP). REPL. Self-updating CLI with chuks upgrade.&lt;/p&gt;

&lt;p&gt;Get Started&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="c"&gt;# Install (macOS/Linux/Windows)&lt;/span&gt;
curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://raw.githubusercontent.com/chuks-programming-language/releases/main/install.sh | bash

&lt;span class="c"&gt;# Create a project&lt;/span&gt;
chuks new my_app
&lt;span class="nb"&gt;cd &lt;/span&gt;my_app
chuks run src/main.chuks

&lt;span class="c"&gt;# Build for production&lt;/span&gt;
chuks build src/main.chuks
./build/main.chuks.bin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;X&lt;/strong&gt;: &lt;a href="https://x.com/Chukslang" rel="noopener noreferrer"&gt;@Chukslang&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Website&lt;/strong&gt;: &lt;a href="https://chuks.org" rel="noopener noreferrer"&gt;chuks.org&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/chuks-programming-language/releases" rel="noopener noreferrer"&gt;github.com/chuks-programming-language&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Chuks is still early (v0.0.6), but the foundation is solid — 157 tests passing, cross-platform releases (macOS, Linux, Windows), and real-world projects already running on it.&lt;/p&gt;

&lt;p&gt;I'd love feedback. What would you want from a language like this?&lt;/p&gt;

</description>
      <category>programming</category>
      <category>performance</category>
      <category>webdev</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>ExpressWebJs 4 is now released!</title>
      <dc:creator>Chukwuemeka Igbokwe</dc:creator>
      <pubDate>Wed, 21 Sep 2022 17:17:22 +0000</pubDate>
      <link>https://dev.to/chukwuemekaigbokwe/expresswebjs-4-is-now-released-37bp</link>
      <guid>https://dev.to/chukwuemekaigbokwe/expresswebjs-4-is-now-released-37bp</guid>
      <description>&lt;p&gt;&lt;a href="https://expresswebjs.com/" rel="noopener noreferrer"&gt;ExpressWebJs&lt;/a&gt; version 4 is now released and it includes many new features, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mongoose and ObjectionJs ORM support.&lt;/li&gt;
&lt;li&gt;SQL database relationship addons.&lt;/li&gt;
&lt;li&gt;Multi-tenancy support for mongo DB.&lt;/li&gt;
&lt;li&gt;Route match.&lt;/li&gt;
&lt;li&gt;Route redirect.&lt;/li&gt;
&lt;li&gt;Improved middleware handler methods.&lt;/li&gt;
&lt;li&gt;Improved service registry handlers.&lt;/li&gt;
&lt;li&gt;Custom validation rules.&lt;/li&gt;
&lt;li&gt;Improved event class generation.&lt;/li&gt;
&lt;li&gt;Added Redis to the supported queue connections.&lt;/li&gt;
&lt;li&gt;Service communication for distributed services.&lt;/li&gt;
&lt;li&gt;Domain-driven design (DDD).&lt;/li&gt;
&lt;li&gt;Support for Restana platform service for faster request 
processing.&lt;/li&gt;
&lt;li&gt;New utility features like &lt;code&gt;Optional( )&lt;/code&gt;,&lt;code&gt;ObjectMapper( )&lt;/code&gt;, 
&lt;code&gt;FirstCharacterToLowerCase( )&lt;/code&gt;, &lt;code&gt;Group( )&lt;/code&gt;, &lt;code&gt;ObjectHasProperty( )&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;New Collection feature which helps you work on advanced data 
structures and algorithms.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://expresswebjs.com/" rel="noopener noreferrer"&gt;ExpressWebJs&lt;/a&gt; uses a variety of community driven packages for a number of features in the framework.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://expresswebjs.com/" rel="noopener noreferrer"&gt;ExpressWebJs&lt;/a&gt; version 4 will receive bug fixes until November 2023 and security fixes until February 2024. Here are some of the features that we’ve covered in detail.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;We’ve added some relationship add-ons for the SQL database model.&lt;/strong&gt;&lt;br&gt;
The relationship mapping method now has a nice way of handling relationships with the new &lt;code&gt;hasMany&lt;/code&gt;, &lt;code&gt;belongsTo&lt;/code&gt;, &lt;code&gt;hasOne&lt;/code&gt;, &lt;code&gt;hasOneThrough&lt;/code&gt;, &lt;code&gt;hasManyThrough&lt;/code&gt; methods that also accept additional options.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;hasManyThrough()&lt;/strong&gt;&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="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserModel&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Model&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="nx"&gt;tableName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;users&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="nf"&gt;relationMappings&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="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;carOwner&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hasManyThrough&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;App/Model/Cars_model&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;App/Model/CarOwners_model&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="na"&gt;join_final_foreign_key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;user_id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;join_parent_foreign_key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;car_id&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;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;p&gt;&lt;strong&gt;hasOneThrough()&lt;/strong&gt;&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="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserModel&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Model&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="nx"&gt;tableName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;users&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="nf"&gt;relationMappings&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="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;carOwner&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hasOneThrough&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;App/Model/Cars_model&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;App/Model/CarOwners_model&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="na"&gt;join_final_foreign_key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;user_id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;join_parent_foreign_key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;car_id&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;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;p&gt;&lt;strong&gt;hasOne()&lt;/strong&gt;&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="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserModel&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Model&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="nx"&gt;tableName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;users&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;first_name&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;last_name&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="nf"&gt;relationMappings&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="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hasOne&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;App/Model/Profile_model&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;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;hasMany()&lt;/strong&gt;&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="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserModel&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Model&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="nx"&gt;tableName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;users&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;first_name&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;last_name&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="nf"&gt;relationMappings&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="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hasMany&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;App/Model/Cars_model&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;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;belongsTo()&lt;/strong&gt;&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="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Posts&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Model&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="nx"&gt;tableName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;posts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;user_id&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="nf"&gt;relationMappings&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="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;users&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;belongsTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;App/Model/Users_model&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;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Relation filters&lt;/strong&gt;&lt;br&gt;
You can also add some filters to your relationship mapping:&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="k"&gt;static&lt;/span&gt; &lt;span class="nf"&gt;relationMappings&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="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hasMany&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;App/Model/Cars_model&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,{&lt;/span&gt;
        &lt;span class="na"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Mercedes&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;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;p&gt;Some route features are also added&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Route Match&lt;/strong&gt;&lt;br&gt;
Sometimes you may need to register a route that responds to multiple HTTP verbs. You may do so using the match method. Or, you may even register a route that responds to all HTTP verbs using the all method:&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="nx"&gt;Route&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;get&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;post&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/books&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;UserController@process&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Route Redirect&lt;/strong&gt;&lt;br&gt;
If you are defining a route that redirects to another URI, you may use the Route redirect method. This method provides a convenient shortcut so that you do not have to define a full route or controller for performing this task.&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="nx"&gt;Route&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;redirect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;source_url&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;destination_url&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can see the complete list of new features and updates on &lt;a href="https://expresswebjs.com/" rel="noopener noreferrer"&gt;ExpressWebJs&lt;/a&gt; website.&lt;/p&gt;

&lt;p&gt;Kindly follow &lt;a href="https://twitter.com/expresswebjs" rel="noopener noreferrer"&gt;ExpressWebJs&lt;/a&gt; on &lt;a href="https://twitter.com/expresswebjs" rel="noopener noreferrer"&gt;twitter&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;And don't forget to star on &lt;a href="https://github.com/Alexigbokwe/ExpressWebJs" rel="noopener noreferrer"&gt;github&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You can also join the &lt;a href="https://discord.com/invite/vrPGZCgJuj" rel="noopener noreferrer"&gt;discord&lt;/a&gt; channel&lt;/p&gt;

</description>
      <category>expresswebjs</category>
      <category>node</category>
      <category>typescript</category>
      <category>api</category>
    </item>
    <item>
      <title>Dependency Injection in ExpressWebJs V3</title>
      <dc:creator>Chukwuemeka Igbokwe</dc:creator>
      <pubDate>Sun, 17 Oct 2021 11:42:51 +0000</pubDate>
      <link>https://dev.to/chukwuemekaigbokwe/dependency-injection-in-expresswebjs-v3-444k</link>
      <guid>https://dev.to/chukwuemekaigbokwe/dependency-injection-in-expresswebjs-v3-444k</guid>
      <description>&lt;p&gt;In software engineering, dependency injection is a technique in which an object receives other objects that it depends on, called dependencies.&lt;/p&gt;

&lt;p&gt;Typically, the receiving object is called a client and the passed-in ('injected') object is called a service. &lt;/p&gt;

&lt;p&gt;The code that passes the service to the client is called the injector. Instead of the client specifying which service it will use, the injector tells the client what service to use. The 'injection' refers to the passing of a dependency (a service) into the client that uses it.&lt;/p&gt;

&lt;p&gt;We can inject the classes into another class’s constructor and then get the object of that class, and through that object, we can access its methods and properties.&lt;/p&gt;

&lt;h2&gt;
  
  
  ExpressWebJs Dependency Injection
&lt;/h2&gt;

&lt;p&gt;The Service Container in ExpressWebJs is a Dependency Injection Container and a registry for the application. &lt;/p&gt;

&lt;p&gt;ExpressWebJs Container is a powerful tool for managing dependencies and stores objects for various purposes.&lt;/p&gt;

&lt;p&gt;First let's create our Service and register it in App/Providers/AppServiceProvider.ts register method:&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%2Fa7mc2wef8ai58c6cu4c4.jpeg" 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%2Fa7mc2wef8ai58c6cu4c4.jpeg" alt="ExpressWebJs Services" width="304" height="720"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  UserServiceInterface:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;UserServiceInterface&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;createUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;UserObject&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nf"&gt;findUserById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;UserObject&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;UserServiceInterface&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  UserService:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Users&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;App/Model/Users_model&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="nx"&gt;UserServiceInterface&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;./UserServicerInterface&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserService&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;UserServiceInterface&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;findUserById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;Users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;findById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&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;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;createUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;Users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
          &lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nf"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&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;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;UserService&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Now we register UserService in App/Providers/AppServiceProvider.ts register method:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;ServiceProvider&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;Elucidate/Support/ServiceProvider&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="nx"&gt;UserService&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;App/Service/UserService&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AppServiceProvicer&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;ServiceProvider&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="cm"&gt;/**
   * Register any application services.
   * @return void
   */&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;register&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="k"&gt;this&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="nf"&gt;singleton&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;UserService&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;UserService&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;class&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;h3&gt;
  
  
  We can now inject our UserService into UserController Constructor:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;use strict&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="nx"&gt;UserServiceInterface&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;App/Service/UserService/UserServicerInterface&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;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;NextFunction&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;Elucidate/HttpContext&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="nx"&gt;HttpResponse&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;Elucidate/HttpContext/ResponseType&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserController&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nx"&gt;userService&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UserServiceInterface&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;UserService&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UserServiceInterface&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;userService&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;UserService&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="cm"&gt;/**
   * Display the specified resource.
   * @method GET
   * @endpoint api/user/get_user/:id
   * @param Request
   * @return Response
   */&lt;/span&gt;
  &lt;span class="nx"&gt;show&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;NextFunction&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;userService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findUserById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;HttpResponse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;OK&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&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="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&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;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;UserController&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, the UserController needs to retrieve a user by id from a data source. So, we injected our service (UserService) that is able to retrieve users.&lt;/p&gt;

&lt;p&gt;I hope this is helpful.&lt;/p&gt;

&lt;p&gt;Kindly visit &lt;a href="https://docs.expresswebjs.com/3.0/guide/introduction.html" rel="noopener noreferrer"&gt;Expresswebjs Docs&lt;/a&gt; for documentation and usage.&lt;/p&gt;

&lt;p&gt;Join ExpressWebJs community on &lt;a href="https://discord.com/invite/vrPGZCgJuj" rel="noopener noreferrer"&gt;Discord&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can follow ExpressWebJs on twitter &lt;a href="https://twitter.com/expresswebjs" rel="noopener noreferrer"&gt;@expresswebjs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And don't forget to star ExpressWebJs Project on Github&lt;br&gt;
&lt;a href="https://github.com/Alexigbokwe/ExpressWebJs" rel="noopener noreferrer"&gt;ExpressWebJs Javascript Version&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Alexigbokwe/expresswebTS-Version" rel="noopener noreferrer"&gt;ExpressWebJs Typescript Version&lt;/a&gt;&lt;/p&gt;

</description>
      <category>expresswebjs</category>
      <category>typescript</category>
      <category>express</category>
      <category>node</category>
    </item>
    <item>
      <title>ExpressWebJs 3.2 Released</title>
      <dc:creator>Chukwuemeka Igbokwe</dc:creator>
      <pubDate>Sun, 19 Sep 2021 22:57:35 +0000</pubDate>
      <link>https://dev.to/chukwuemekaigbokwe/expresswebjs-3-2-released-18ci</link>
      <guid>https://dev.to/chukwuemekaigbokwe/expresswebjs-3-2-released-18ci</guid>
      <description>&lt;p&gt;The ExpressWebJs team have released 3.2 with auto endpoint documentation, and improvement in service injection.&lt;/p&gt;

&lt;h2&gt;
  
  
  Auto Endpoint Documentation:
&lt;/h2&gt;

&lt;p&gt;Reference documentation for API endpoints consists of five general sections: resource descriptions, endpoints and methods, parameters, sample requests, and sample responses and schemas. All these are auto documented for you while you code, to allow you focus on building your amazing application.&lt;/p&gt;

&lt;p&gt;To get started, install ExpressWebJs by running the command below&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt; &lt;span class="nx"&gt;npx&lt;/span&gt; &lt;span class="nx"&gt;expresswebcli&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;MyApplication&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;ts&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and run 'npm install' to install the node packages 📦. Then create few endpoints and visit your base url in a browser followed by /documentationView for HTML view or /documentationJson for JSON. &lt;/p&gt;

&lt;p&gt;Example: &lt;a href="http://127.0.0.1:5000/documentationView" rel="noopener noreferrer"&gt;http://127.0.0.1:5000/documentationView&lt;/a&gt; or &lt;a href="http://127.0.0.1:5000/documentationJson" rel="noopener noreferrer"&gt;http://127.0.0.1:5000/documentationJson&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Service Injection
&lt;/h2&gt;

&lt;p&gt;You can now inject services irrespective of the order in the application context.&lt;/p&gt;

&lt;p&gt;In our Application Service Provider register method, we've registered some services.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
  &lt;span class="kr"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;register&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&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="nf"&gt;singleton&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;UserService&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;UserService&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;class&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;this&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="nf"&gt;singleton&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;CompanyService&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;CompanyService&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;class&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;this&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="nf"&gt;singleton&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;FolderService&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;FolderService&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;class&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can inject UserService into FolderService like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;FolderRepository&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;App/Repository/FolderRepository&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="nx"&gt;BaseService&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;../BaseService&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="nx"&gt;IFolderService&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;./IFolderService&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="nx"&gt;IUserService&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;./IUserService&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FolderService&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;BaseService&lt;/span&gt; &lt;span class="kr"&gt;implements&lt;/span&gt;
  &lt;span class="kr"&gt;protected&lt;/span&gt; &lt;span class="nx"&gt;userService&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;IUserService&lt;/span&gt;

  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;UserService&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;IUserService&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;userService&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;UserService&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

 &lt;span class="nx"&gt;IFolderService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;getSubFolders&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;userService&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;findById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user_id&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;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;any&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;span class="p"&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;p&gt;You can join ExpressWebJs community on &lt;a href="https://discord.com/invite/vrPGZCgJuj" rel="noopener noreferrer"&gt;Discord&lt;/a&gt; and don't forget to give us a star on github&lt;br&gt;
&lt;a href="https://github.com/Alexigbokwe/ExpressWebJs" rel="noopener noreferrer"&gt;ExpressWebJs Javascript&lt;/a&gt; and &lt;a href="https://github.com/Alexigbokwe/expresswebTS-Version" rel="noopener noreferrer"&gt;ExpressWebJs Typescript&lt;/a&gt;&lt;/p&gt;

</description>
      <category>expresswebjs</category>
      <category>node</category>
      <category>express</category>
      <category>typescript</category>
    </item>
    <item>
      <title>ExpressWebJs Maintenance Mode</title>
      <dc:creator>Chukwuemeka Igbokwe</dc:creator>
      <pubDate>Mon, 16 Aug 2021 03:15:22 +0000</pubDate>
      <link>https://dev.to/chukwuemekaigbokwe/expresswebjs-maintenance-mode-2k4o</link>
      <guid>https://dev.to/chukwuemekaigbokwe/expresswebjs-maintenance-mode-2k4o</guid>
      <description>&lt;p&gt;In this tutorial, I will show you how to switch your ExpressWebJs application to maintenance mode, and also how to change the default ExpressWebJs maintenance mode message to your custom message.&lt;/p&gt;

&lt;p&gt;More often than not you would need to perform some maintenance for your ExpressWebJs application, luckily ExpressWebJs makes it super easy to put your application in maintenance mode.&lt;/p&gt;

&lt;p&gt;You can switch your application to maintenance mode in &lt;code&gt;Config/app.ts&lt;/code&gt; 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="cm"&gt;/*
  |-----------------------------------------------------------
  | Application maintenance mode
  |-----------------------------------------------------------
  | Mode ==&amp;gt; Determine if application is in maintenance mode 
  |    or not. Default value is false
  | Message ==&amp;gt; The message to render while in maintenance 
  |    mode.
  | Retry ==&amp;gt; The number of seconds after which the request 
  |    may be retried
  | Endpoints ==&amp;gt; The endPoints that should be reachable while 
  |    maintenance mode is enabled.
  |    endpoints example: ['api/users','api/accounts']
  |
*/&lt;/span&gt;
  &lt;span class="nx"&gt;maintenanceMode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;//enable and disable maintenance mode&lt;/span&gt;
    &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Application is in maintenance mode.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;retry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;endPoints&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;p&gt;When your application is in maintenance mode, a default message "Application is in maintenance mode" will be sent as a response to all requests accessing your application. This makes it easy to "disable" your application on downtime.&lt;/p&gt;

&lt;p&gt;This downtime could be for a lot of reasons, including but not limited to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Bugs.&lt;/li&gt;
&lt;li&gt;Database error.&lt;/li&gt;
&lt;li&gt;Migration to another server.&lt;/li&gt;
&lt;li&gt;Server upgrade.&lt;/li&gt;
&lt;li&gt;Decoupling to a new architecture.&lt;/li&gt;
&lt;li&gt;SSL Error.&lt;/li&gt;
&lt;li&gt;Updating Application etc.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A maintenance mode check is included in the default middleware stack for your application. If the application is in maintenance mode, a MaintenanceModeException will be thrown with a status code of 503.&lt;/p&gt;

&lt;p&gt;To read more about ExpressWebJs, visit the Documentation site at &lt;a href="https://expresswebjs.com" rel="noopener noreferrer"&gt;ExpressWebJs&lt;/a&gt; .&lt;br&gt;
You can also join the &lt;a href="https://discord.gg/vrPGZCgJuj" rel="noopener noreferrer"&gt;Discord&lt;/a&gt; community &lt;/p&gt;

&lt;p&gt;You can follow me on twitter &lt;a href="https://twitter.com/EmekaIgbokwe" rel="noopener noreferrer"&gt;@EmekaIgbokwe&lt;/a&gt;&lt;br&gt;
You can follow ExpressWebJs on twitter &lt;a href="https://twitter.com/expresswebjs" rel="noopener noreferrer"&gt;@expresswebjs&lt;/a&gt;&lt;br&gt;
and don't forget to star on github &lt;a href="https://github.com/Alexigbokwe/ExpressWebJs" rel="noopener noreferrer"&gt;ExpressWebJs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Please, let me know if you have any questions in the comment section. 😊&lt;/p&gt;

</description>
      <category>expresswebjs</category>
      <category>node</category>
      <category>javascript</category>
      <category>typescript</category>
    </item>
    <item>
      <title>ExpressWebJs 3 Is Now Released!</title>
      <dc:creator>Chukwuemeka Igbokwe</dc:creator>
      <pubDate>Fri, 13 Aug 2021 22:59:03 +0000</pubDate>
      <link>https://dev.to/chukwuemekaigbokwe/expresswebjs-3-is-now-released-3l1o</link>
      <guid>https://dev.to/chukwuemekaigbokwe/expresswebjs-3-is-now-released-3l1o</guid>
      <description>&lt;p&gt;ExpressWebJs team is proud to announce the release of ExpressWebJs 3 and it’s now available to everyone. This release marks the start of the ExpressWebJs framework using Typescript. &lt;/p&gt;

&lt;p&gt;Also, this release includes improved authentication and authorization responses, job, middleware, route collections, sub-query improvements, among many other improvements.&lt;/p&gt;

&lt;p&gt;Here are some of the new features included in ExpressWebJs 3:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Model Types for SQL and NOSQL&lt;/li&gt;
&lt;li&gt;Maker Command&lt;/li&gt;
&lt;li&gt;Persistent Repository&lt;/li&gt;
&lt;li&gt;Multi Tenancy&lt;/li&gt;
&lt;li&gt;Social Authentication&lt;/li&gt;
&lt;li&gt;Encryption&lt;/li&gt;
&lt;li&gt;Hashing&lt;/li&gt;
&lt;li&gt;Route Groups and middleware&lt;/li&gt;
&lt;li&gt;Request Validation (Inline and external)&lt;/li&gt;
&lt;li&gt;Dependency Injection&lt;/li&gt;
&lt;li&gt;Service Providers&lt;/li&gt;
&lt;li&gt;Events And Listeners&lt;/li&gt;
&lt;li&gt;Queues&lt;/li&gt;
&lt;li&gt;Task Schedulers&lt;/li&gt;
&lt;li&gt;Web Socket&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Please visit &lt;a href="https://docs.expresswebjs.com/3.0/guide/introduction.html" rel="noopener noreferrer"&gt;Expresswebjs Docs&lt;/a&gt; for documentation and usage.&lt;/p&gt;

&lt;p&gt;Thanks to everyone  who have contributed with issue reports and pull requests. Our next set of releases are due March 19, 2022.&lt;/p&gt;

&lt;p&gt;How can you help?&lt;br&gt;
If you’re interested in helping out, or if you have general questions, please ask on stackoverflow.com using the ExpressWebJs tag or chat with the community on &lt;a href="https://discord.com/invite/vrPGZCgJuj" rel="noopener noreferrer"&gt;Discord&lt;/a&gt;&lt;/p&gt;

</description>
      <category>expresswebjs</category>
      <category>node</category>
      <category>javascript</category>
      <category>typescript</category>
    </item>
    <item>
      <title>JWT authentication in Expresswebjs</title>
      <dc:creator>Chukwuemeka Igbokwe</dc:creator>
      <pubDate>Sun, 07 Mar 2021 10:50:46 +0000</pubDate>
      <link>https://dev.to/chukwuemekaigbokwe/jwt-authentication-in-expresswebjs-djj</link>
      <guid>https://dev.to/chukwuemekaigbokwe/jwt-authentication-in-expresswebjs-djj</guid>
      <description>&lt;p&gt;With the rising popularity of single page applications, mobile applications, and RESTful API services, the way web developers write back-end code has changed significantly. We now use &lt;a href="https://expresswebjs.com/" rel="noopener noreferrer"&gt;expresswebjs&lt;/a&gt; to build APIs that our front-end applications consume. ExpressWebJs strives to give you the tools you need to implement authentication quickly, securely, and easily. Since ExpressWebJs does not support session state, incoming requests that you wish to authenticate will be authenticated via a stateless mechanism such as API tokens.&lt;/p&gt;

&lt;p&gt;In this article, we will look at using JWT to secure our ExpressWebJs APIs.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a JSON Web Token?
&lt;/h2&gt;

&lt;p&gt;JSON Web Token (JWT) is an open standard that allows two parties to securely send data and information as JSON objects. This information can be verified and trusted because it is digitally signed.&lt;/p&gt;

&lt;p&gt;JWT authentication has aided the wider adoption of stateless API services. It makes it convenient to authorise and verify clients accessing API resources. It is a critical part of the authentication system in javascript powered applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;The first thing we are going to do is create a new &lt;a href="https://expresswebjs.com/" rel="noopener noreferrer"&gt;expresswebjs&lt;/a&gt; application.To start your new project, you can open your terminal or CLI and type npx expresswebcli new command, followed by your project name. Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  npx expresswebcli new jwtApp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once that is done, cd into your project like so &lt;code&gt;cd jwtApp&lt;/code&gt; and run &lt;code&gt;npm install&lt;/code&gt; to install your packages.&lt;/p&gt;

&lt;p&gt;When that is done, you can now create your .env file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   cp example.env .env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In our .env we can now configure our database. ExpressWebJs supports SQL and NOSQL database. In this tutorial, we will be using Mysql which is an SQL database.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;APP_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;base64&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;Mk9TtGvMu3Kfp9wdahuownbdgsI3VTx2MXTQjN&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="nx"&gt;CFBadI&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;
&lt;span class="nx"&gt;APP_NAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;ExpressWebJs&lt;/span&gt;
&lt;span class="nx"&gt;APP_ENV&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;local&lt;/span&gt;
&lt;span class="nx"&gt;APP_HOST&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;127.0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mf"&gt;0.1&lt;/span&gt;
&lt;span class="nx"&gt;APP_PORT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5000&lt;/span&gt;
&lt;span class="nx"&gt;APP_TRANSFER_PROTOCOL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;http&lt;/span&gt;

&lt;span class="nx"&gt;DB_SHOULD_CONNECT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="nx"&gt;DB_CONNECTION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;mysql&lt;/span&gt;
&lt;span class="nx"&gt;DB_HOST&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;localhost&lt;/span&gt;
&lt;span class="nx"&gt;DB_PORT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3306&lt;/span&gt;
&lt;span class="nx"&gt;DB_USER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;
&lt;span class="nx"&gt;DB_PASSWORD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;
&lt;span class="nx"&gt;DB_DATABASE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;network&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;provider&lt;/span&gt;
&lt;span class="nx"&gt;DB_USENEWURLPARSER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="nx"&gt;DB_USEUNIFIEDTOPOLOGY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="nx"&gt;DB_USECREATEINDEX&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Note: Don't forget to set your APP_KEY.
&lt;/h3&gt;

&lt;p&gt;run &lt;code&gt;npm run dev&lt;/code&gt; to start your app&lt;/p&gt;

&lt;p&gt;To generate our authentication files, we will now run auth Maker command to setup our auth routes&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  node maker make-auth
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our auth routes will be generated in &lt;code&gt;Routes/authRoute/index.js&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;use strict&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;Route&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@routerManager&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="cm"&gt;/*
|-------------------------------------------------------------
| Authentication Route File   
|-------------------------------------------------------------
|
| This route handles both login and registration.
| 
*/&lt;/span&gt;

&lt;span class="nx"&gt;Route&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/register&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Auth/RegisterController@register&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;Route&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/login&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Auth/LoginController@login&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Route&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exec&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, uncomment the auth middleware inside the App/Http/kernel.js file routeMiddleware section:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="cm"&gt;/*
  |-----------------------------------------------------------
  | Route Middleware
  |-----------------------------------------------------------
  |
  | Route middleware is a key/value object to conditionally 
  | add middleware on
  | specific routes or assigned to group of routes.
  |
  */&lt;/span&gt;
  &lt;span class="nx"&gt;routeMiddleware&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;App/Http/Middleware/Auth&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this point we need to setup and run our migration schema for our user model. Head over to Database/Migrations/20201209124747_user.js file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="cm"&gt;/**
 * Migration layout file.
 * Assign your table name to the tableName variable.
 * Remember, it's always in plural
 */&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;tableName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;users&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;up&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;knex&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="nx"&gt;knex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;schema&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createTable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tableName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;table&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;table&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;increments&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;table&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;username&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;notNullable&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;table&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;email&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;unique&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;notNullable&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;table&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;password&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;notNullable&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;table&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;timestamps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&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;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;down&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;knex&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="nx"&gt;knex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;schema&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dropTable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tableName&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;p&gt;we can now run our migration with the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   node maker run-sql-migration
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To view our authentication config, head over to App/Config/auth.js file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="cm"&gt;/*
  |-----------------------------------------------------------
  | Authenticator
  |-----------------------------------------------------------
  |
  | ExpressWebJs does not support session state, incoming 
  | requests that 
  | you wish to authenticate must be authenticated via a 
  | stateless mechanism such as API tokens.
  |
  */&lt;/span&gt;
  &lt;span class="na"&gt;authenticator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;jwt&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

  &lt;span class="cm"&gt;/*
  |-----------------------------------------------------------
  | Jwt
  |-----------------------------------------------------------
  |
  | The jwt authenticator works by passing a jwt token on each 
  | HTTP request
  | via HTTP `Authorization` header.
  |
  */&lt;/span&gt;
  &lt;span class="na"&gt;jwt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;User_model&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;jwt&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;uid&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;email&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;password&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;APP_KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;expiresIn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;86400&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;//default is 86400 (24 hrs)&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;p&gt;To read more about authentication config, visit &lt;a href="https://expresswebjs.com/2.0/guide/security.html#password-hashing" rel="noopener noreferrer"&gt;ExpressWebJs Authentication&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Route Authentication
&lt;/h2&gt;

&lt;p&gt;We can now authenticate our routes like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="nx"&gt;Route&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/user&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;UserController@index&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;auth&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also authenticate your route groups like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="nx"&gt;Route&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/user&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;auth&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],()&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;Route&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;UserController@index&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;Route&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/:id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;UserController@show&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;Route&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/save&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;UserController@save&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;Route&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;patch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/update&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;UserController@update&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;Route&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/delete&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;UserController@destroy&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;READ &lt;a href="https://dev.to/alexigbokwe/developing-rest-apis-with-expresswebjs-v2-a-nodejs-framework-part-1-1fg4"&gt;developing-rest-apis-with-expresswebjs-v2&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In your PostMan, access the register endpoint using a post method &lt;code&gt;127.0.0.1:5000/api/register&lt;/code&gt; and input your username, email and password.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Well done! You have learned how to secure your API routes with &lt;a href="https://expresswebjs.com/" rel="noopener noreferrer"&gt;ExpressWebjs&lt;/a&gt;. Need to use &lt;a href="https://expresswebjs.com/" rel="noopener noreferrer"&gt;ExpressWebjs&lt;/a&gt; to build your API or micro-service? I'd bet on &lt;a href="https://expresswebjs.com/" rel="noopener noreferrer"&gt;ExpressWebjs&lt;/a&gt; as the tool of choice for speed and ease of use.&lt;/p&gt;

&lt;p&gt;I will be discussing on &lt;a href="https://expresswebjs.com/2.0/guide/validation.html#defining-the-routes" rel="noopener noreferrer"&gt;ExpressWebjs Data Validation &lt;/a&gt; in my next article.&lt;br&gt;
You can follow me on twitter &lt;a href="https://twitter.com/EmekaIgbokwe" rel="noopener noreferrer"&gt;@EmekaIgbokwe&lt;/a&gt;&lt;br&gt;
You can follow ExpressWebJs on twitter &lt;a href="https://twitter.com/expresswebjs" rel="noopener noreferrer"&gt;@expresswebjs&lt;/a&gt;&lt;br&gt;
and don't forget to star on github &lt;a href="https://github.com/Alexigbokwe/ExpressWebJs" rel="noopener noreferrer"&gt;ExpressWebJs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Please, let me know if you have any questions in the comment section. 😊&lt;/p&gt;

</description>
      <category>node</category>
      <category>expresswebjs</category>
      <category>api</category>
      <category>microservices</category>
    </item>
    <item>
      <title>Documenting your ExpressWebJs API with Swagger</title>
      <dc:creator>Chukwuemeka Igbokwe</dc:creator>
      <pubDate>Fri, 26 Feb 2021 14:23:34 +0000</pubDate>
      <link>https://dev.to/chukwuemekaigbokwe/documenting-your-expresswebjs-api-with-swagger-36hf</link>
      <guid>https://dev.to/chukwuemekaigbokwe/documenting-your-expresswebjs-api-with-swagger-36hf</guid>
      <description>&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%2F9u09powimhz3p6vzgimu.jpg" 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%2F9u09powimhz3p6vzgimu.jpg" alt="Alt Text" width="800" height="225"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Almost every application today has to be connected to share data with other applications. The best way to do that is through APIs and &lt;a href="https://expresswebjs.com/" rel="noopener noreferrer"&gt;ExpressWebjs&lt;/a&gt; is the goto framework for building your node apis.&lt;/p&gt;

&lt;p&gt;In this tutorial, however, we’re going to explore Swagger usage along with &lt;a href="https://expresswebjs.com/" rel="noopener noreferrer"&gt;expressWebjs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;What is Swagger?&lt;br&gt;
On the Swagger site we can find definition of Swagger:&lt;br&gt;
Swagger is the world’s largest framework of API developer tools for the OpenAPI Specification(OAS), enabling development across the entire API lifecycle, from design and documentation, to test and deployment.&lt;/p&gt;

&lt;p&gt;In our example, we’ll be making use of the two libraries: &lt;a href="https://github.com/scottie1984/swagger-ui-express" rel="noopener noreferrer"&gt;swagger-ui-express&lt;/a&gt; and &lt;a href="https://github.com/Surnet/swagger-jsdoc" rel="noopener noreferrer"&gt;swagger-jsdoc&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The first is a module that allows you to feed a Swagger UI (auto-generated views based on the swagger-ui project) from a swagger.json file, or from an inline object.&lt;/p&gt;

&lt;p&gt;The second is about integrating Swagger using JSDoc comments in Docs directory in ExpressWebjs. This is pretty useful, especially when you have extensive APIs and dozens of models.&lt;/p&gt;
&lt;h1&gt;
  
  
  Application setup
&lt;/h1&gt;
&lt;h3&gt;
  
  
  Install ExpressWebJs
&lt;/h3&gt;

&lt;p&gt;Run the following command in your terminal to create a new project with ExpressWebJs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   npx expresswebcli new myNewApp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;cd into your newly created project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   cd myNewApp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Visit my article on &lt;a href="https://dev.to/alexigbokwe/developing-rest-apis-with-expresswebjs-v2-a-nodejs-framework-part-1-1fg4"&gt;developing rest apis with expresswebjs&lt;/a&gt; or &lt;a href="https://expresswebjs.com/" rel="noopener noreferrer"&gt;expresswebjs&lt;/a&gt; documentation for work through on how to get started with expresswebjs.&lt;/p&gt;

&lt;h1&gt;
  
  
  Adding swagger
&lt;/h1&gt;

&lt;p&gt;Now that our application is ready, &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%2Fhon1onugip8hurlncq1l.jpeg" 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%2Fhon1onugip8hurlncq1l.jpeg" alt="Alt Text" width="295" height="546"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;we can now integrate swagger by creating our swagger.json file in the root directory&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;definition&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;openapi&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;3.0.n&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;info&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;My Website API Documentation&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;version&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0.1.0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;description&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;My website API docs with ExpressWebJs and documented with Swagger&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;license&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;MIT&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;url&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://spdx.org/licenses/MIT.html&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;contact&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;servers&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;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;url&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;http://localhost:5100/api&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;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;apis&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./Docs/*.js&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This &lt;code&gt;"apis": ["./Docs/*.js"]&lt;/code&gt; section specifies the path where your actual documentations are. In our case, it is in Docs folder in the root directory.&lt;/p&gt;

&lt;p&gt;After that we can now create our swagger service in App/Service directory.&lt;/p&gt;

&lt;p&gt;In App/Service directory, lets create a Swagger folder with an index.js file. Our path will be App/Service/Swagger/index.js&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt; &lt;span class="c1"&gt;//App/Service/Swagger/index.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;swaggerJsdoc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;swagger-jsdoc&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;swaggerUi&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;swagger-ui-express&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;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../../../swagger.json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Swagger&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;specs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;swaggerJsdoc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;serverApp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/api-docs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;swaggerUi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;serve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;swaggerUi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;specs&lt;/span&gt;&lt;span class="p"&gt;,{&lt;/span&gt;&lt;span class="na"&gt;exporer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="kc"&gt;true&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;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Swagger&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  ExpressWebJs ServiceProvider
&lt;/h1&gt;

&lt;p&gt;Next we will register our swagger service in our application service provider. Navigate to App/Providers/AppServiceProvider.js file and add our swagger service to be executed at boot time&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;swagger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../Service/swagger&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

 &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AppServiceProvider&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="cm"&gt;/**
   * Register application services.
   */&lt;/span&gt;
  &lt;span class="nf"&gt;register&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="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;//&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="cm"&gt;/**
   * Bootstrap any application services.
   *
   * @return void
   */&lt;/span&gt;
  &lt;span class="nf"&gt;boot&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;swagger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&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;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;AppServiceProvider&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note: you can create your own service provider. Read more about &lt;a href="https://expresswebjs.com/2.0/guide/service-provider.html" rel="noopener noreferrer"&gt;ExpressWebjs ServiceProvider in the Documentation site&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Once all the setup is done, you can now start writing your api documentation in the Docs directory.&lt;/p&gt;

&lt;p&gt;To view your swagger docs, run your project using&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="nx"&gt;npm&lt;/span&gt; &lt;span class="nx"&gt;run&lt;/span&gt; &lt;span class="nx"&gt;dev&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and navigate to &lt;code&gt;&lt;a href="http://127.0.0.1/api/api-docs" rel="noopener noreferrer"&gt;http://127.0.0.1/api/api-docs&lt;/a&gt;&lt;/code&gt; in your browser.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Thank you for reading my article &lt;br&gt;
You can follow me on twitter &lt;a href="https://twitter.com/EmekaIgbokwe" rel="noopener noreferrer"&gt;@EmekaIgbokwe&lt;/a&gt;&lt;br&gt;
You can follow ExpressWebJs on twitter &lt;a href="https://twitter.com/expresswebjs" rel="noopener noreferrer"&gt;@expresswebjs&lt;/a&gt;&lt;br&gt;
and don't forget to star on github &lt;a href="https://github.com/Alexigbokwe/ExpressWebJs" rel="noopener noreferrer"&gt;ExpressWebJs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Please, let me know if you have any questions in the comment section. 😊&lt;/p&gt;

</description>
      <category>node</category>
      <category>expresswebjs</category>
      <category>javascript</category>
      <category>swagger</category>
    </item>
  </channel>
</rss>
