<?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: genie-oh</title>
    <description>The latest articles on DEV Community by genie-oh (@genie_oh).</description>
    <link>https://dev.to/genie_oh</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F697833%2Fd8ec0125-8f2c-47bf-9644-e348b05f1387.png</url>
      <title>DEV Community: genie-oh</title>
      <link>https://dev.to/genie_oh</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/genie_oh"/>
    <language>en</language>
    <item>
      <title>using: A keyword that make be easily that resource variable management (JavaScript &amp; TypeScript)</title>
      <dc:creator>genie-oh</dc:creator>
      <pubDate>Wed, 20 Sep 2023 11:43:45 +0000</pubDate>
      <link>https://dev.to/genie_oh/using-a-keyword-that-make-be-easily-that-resource-variable-management-javascript-typescript-1pdj</link>
      <guid>https://dev.to/genie_oh/using-a-keyword-that-make-be-easily-that-resource-variable-management-javascript-typescript-1pdj</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;The opinions expressed in this article are based on individual subjective views. Since the content of this article may contain errors, your understanding is appreciated. If you find any mistakes, differences in understanding, or have alternative opinions, comments are highly welcome!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Overview
&lt;/h1&gt;

&lt;p&gt;In JavaScript, in addition to the keywords &lt;code&gt;var&lt;/code&gt;, &lt;code&gt;let&lt;/code&gt;, and &lt;code&gt;const&lt;/code&gt;, a new keyword &lt;code&gt;using&lt;/code&gt; is soon to be added for variable initialization.&lt;/p&gt;

&lt;p&gt;Variables declared with the &lt;code&gt;using&lt;/code&gt; keyword will be treated as resource variables, allowing them to automatically perform resource cleanup before going out of scope. This is expected to simplify the cumbersome task of writing explicit resource cleanup code. The ECMAScript Proposal is currently at Stage 3, and you can track its status &lt;a href="https://github.com/tc39/proposal-explicit-resource-management#status"&gt;here&lt;/a&gt;. It will become a standard when it reaches Stage 4. For more details, please refer to &lt;a href="https://tc39.es/process-document/"&gt;The TC39 Process&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Additionally, TypeScript 5.2 introduces support for the &lt;code&gt;using&lt;/code&gt; keyword. Please note that you may currently need polyfill code for this feature.&lt;/p&gt;

&lt;p&gt;This article will cover the following topics:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Basic usage&lt;/li&gt;
&lt;li&gt;Addressing previous challenges and solutions&lt;/li&gt;
&lt;li&gt;How to use &lt;code&gt;using&lt;/code&gt; in TypeScript 5.2 with code examples&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Sample Code
&lt;/h1&gt;

&lt;p&gt;You can see sample code on TypeScript 5.2 in the following GitHub repository: &lt;a href="https://github.com/genie-oh/ts-explicit-resource-management"&gt;ts-explicit-resource-management&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Background
&lt;/h1&gt;

&lt;p&gt;When handling with external resources such as file operations, database operations, and network communication (sockets), it is necessary to explicitly handle resource open and close (expose and dispose) operations.&lt;/p&gt;

&lt;p&gt;To summarize, explicit resource handling like the one mentioned above has posed a considerable burden on programmers. To address this challenge, the &lt;code&gt;using&lt;/code&gt; keyword has been proposed and is expected to become a standard specification soon.&lt;/p&gt;

&lt;p&gt;For example, when working with PostgreSQL using &lt;code&gt;node-postgres&lt;/code&gt;, you need to explicitly handle &lt;code&gt;connect()&lt;/code&gt; and &lt;code&gt;close()&lt;/code&gt; operations. Failing to call &lt;code&gt;close()&lt;/code&gt; can lead to issues where the DB connection's resources are not released, causing the process not to terminate.&lt;/p&gt;

&lt;p&gt;Other programming languages like Java have features like &lt;code&gt;AutoClosable&lt;/code&gt; to address this issue, but JavaScript has lacked such an official feature until now. Therefore, programmers have had to come up with various workarounds, with the most common pattern being using &lt;code&gt;try-finally&lt;/code&gt; as shown below:&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;// ... inside an async function&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Client&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="nx"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;({...&lt;/span&gt;&lt;span class="nx"&gt;connectionInfo&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="c1"&gt;// ... some logic&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;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// ... error handling&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;finally&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;close&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;However, even with this approach, writing &lt;code&gt;try-finally&lt;/code&gt; for each usage point or trying to avoid it and creating a Wrapper Class for automatic cleanup presented various challenges. One significant challenge was maintaining code consistency among team members when it came to resource management, which I personally found to be quite difficult.&lt;/p&gt;

&lt;h1&gt;
  
  
  Basic Syntax
&lt;/h1&gt;

&lt;p&gt;With the &lt;code&gt;using&lt;/code&gt; keyword, you can declare resource variables that have a &lt;code&gt;Symbol.dispose&lt;/code&gt; symbol key, which defines a callback function for resource cleanup. When a resource variable declared with &lt;code&gt;using&lt;/code&gt; goes out of scope, the function defined as &lt;code&gt;Symbol.dispose&lt;/code&gt; is automatically called, performing the resource cleanup.&lt;/p&gt;

&lt;p&gt;Here's an example:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getResource&lt;/span&gt; &lt;span class="o"&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="c1"&gt;// ... create initialization code for the resource you want to use&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;// Variables used with 'using' have a symbol key 'Symbol.dispose'&lt;/span&gt;
    &lt;span class="c1"&gt;// that holds a callback function for resource disposal&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dispose&lt;/span&gt;&lt;span class="p"&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="c1"&gt;// ... create resource cleanup logic&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="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;doWorkOnResource&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Declare a resource variable with the 'using' keyword&lt;/span&gt;
  &lt;span class="nx"&gt;using&lt;/span&gt; &lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;getResource&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="c1"&gt;// ... some logic&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;// When the 'using' variable goes out of scope, disposal is automatic&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want to work with asynchronous operations, similar to &lt;code&gt;async/await&lt;/code&gt;, you need to use &lt;code&gt;Symbol.asyncDispose&lt;/code&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getResource&lt;/span&gt; &lt;span class="o"&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="c1"&gt;//...&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;asyncDispose&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// ... write to dispose resource with await&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="c1"&gt;//...&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;doWorkOnResource&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;using&lt;/span&gt; &lt;span class="nx"&gt;resource&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;getResource&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;Additionally, you can implement this with classes by implementing the &lt;code&gt;Disposable&lt;/code&gt; and &lt;code&gt;AsyncDisposable&lt;/code&gt; interfaces:&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="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;SomeResource&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;Dispoable&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;//...&lt;/span&gt;
  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dispose&lt;/span&gt;&lt;span class="p"&gt;]()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;//... write to dispose resource&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;SomeResource&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;AsyncDisposable&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;//...&lt;/span&gt;
  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;asyncDispose&lt;/span&gt;&lt;span class="p"&gt;]()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;//... write to dispose resource with await&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Use Cases
&lt;/h1&gt;

&lt;p&gt;Here, we'll introduce an example of connecting to PostgreSQL using &lt;code&gt;node-postgres&lt;/code&gt;, performing a select operation, and then closing the connection.&lt;/p&gt;

&lt;p&gt;You can find sample code in the following GitHub repository: &lt;a href="https://github.com/genie-oh/ts-explicit-resource-management"&gt;ts-explicit-resource-management&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  pg-try-finally.example.ts
&lt;/h2&gt;

&lt;p&gt;This example demonstrates resource handling using the traditional &lt;code&gt;try-catch-finally&lt;/code&gt; approach:&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="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;dotenv&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;dotenv&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;dotenv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;config&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;Client&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;pg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * @throws Error: errors from pg
 */&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isAvailableDBConnection&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="na"&gt;client&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Client&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="c1"&gt;// Try to connect&lt;/span&gt;
    &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;host&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;DB_HOST&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;database&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;DB_NAME&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;user&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;DB_USER&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="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;DB_PASSWORD&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&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;DB_PORT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;// Query&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&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;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;SELECT $1::text as message&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;Hello world!&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;info&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;rows&lt;/span&gt;&lt;span class="p"&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;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Hello world!&lt;/span&gt;

    &lt;span class="c1"&gt;// Return true if the query is successful&lt;/span&gt;
    &lt;span class="k"&gt;return&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="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&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="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;finally&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Try to client.end()&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;end&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;isAvailableDBConnection&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  pg-asyncDispose-func.example.ts
&lt;/h2&gt;

&lt;p&gt;This example demonstrates the usage of &lt;code&gt;using&lt;/code&gt; and &lt;code&gt;asyncDispose&lt;/code&gt;. It is implemented as an AsyncDisposable Function:&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="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;dotenv&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;dotenv&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;dotenv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;config&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;Client&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;pg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Because dispose and asyncDispose are so new, we need to manually 'polyfill' the existence of these functions in order for TypeScript to use them&lt;/span&gt;
&lt;span class="c1"&gt;// See: https://devblogs.microsoft.com/typescript/announcing-typescript-5-2/#using-declarations-and-explicit-resource-management&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Symbol&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;dispose&lt;/span&gt; &lt;span class="o"&gt;??=&lt;/span&gt; &lt;span class="nb"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Symbol.dispose&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="nb"&gt;Symbol&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;asyncDispose&lt;/span&gt; &lt;span class="o"&gt;??=&lt;/span&gt; &lt;span class="nb"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Symbol.asyncDispose&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * @returns: { client: pg.Client, [Symbol.asyncDispose]: dispose function }
 */&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getDBConnection&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Try to connect&lt;/span&gt;


 &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;host&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;DB_HOST&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;database&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;DB_NAME&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;user&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;DB_USER&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="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;DB_PASSWORD&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&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;DB_PORT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="c1"&gt;// Return resource as disposable&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;asyncDispose&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Try to client.end()&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;end&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="cm"&gt;/**
 * @throws Error: errors from pg
 */&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isAvailableDBConnection&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Declare resource variable by the `using` keyword&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;using&lt;/span&gt; &lt;span class="nx"&gt;db&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;getDBConnection&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;res&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;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;SELECT $1::text as message&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;Hello world!&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;info&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;rows&lt;/span&gt;&lt;span class="p"&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;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
  &lt;span class="c1"&gt;// Before going out of scope, the resource will be disposed by the function of [Symbol.asyncDispose]&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nx"&gt;isAvailableDBConnection&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  pg-asyncDispose-class.example.ts
&lt;/h2&gt;

&lt;p&gt;This example demonstrates the usage of &lt;code&gt;using&lt;/code&gt; and &lt;code&gt;asyncDispose&lt;/code&gt;. It is implemented as an AsyncDisposable Class:&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="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;dotenv&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;dotenv&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;dotenv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;config&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;Client&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;pg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Because dispose and asyncDispose are so new, we need to manually 'polyfill' the existence of these functions in order for TypeScript to use them&lt;/span&gt;
&lt;span class="c1"&gt;// See: https://devblogs.microsoft.com/typescript/announcing-typescript-5-2/#using-declarations-and-explicit-resource-management&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Symbol&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;dispose&lt;/span&gt; &lt;span class="o"&gt;??=&lt;/span&gt; &lt;span class="nb"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Symbol.dispose&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="nb"&gt;Symbol&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;asyncDispose&lt;/span&gt; &lt;span class="o"&gt;??=&lt;/span&gt; &lt;span class="nb"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Symbol.asyncDispose&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * Disposable class
 */&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;DBConnection&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;AsyncDisposable&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;constructor&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;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;host&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;DB_HOST&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;database&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;DB_NAME&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;user&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;DB_USER&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="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;DB_PASSWORD&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&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;DB_PORT&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="cm"&gt;/**
   * Factory method
   * @returns: new instance of DBConnection
   */&lt;/span&gt;
  &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="p"&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;instance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;DBConnection&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;connect&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;instance&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="cm"&gt;/**
   * Implemented by the asyncDisposable interface
   */&lt;/span&gt;
  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;asyncDispose&lt;/span&gt;&lt;span class="p"&gt;]()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Try to client.end()&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&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;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;end&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;getClient&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&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;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;connect&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="cm"&gt;/**
 * @throws Error: errors from pg
 */&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isAvailableDBConnection&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Declare resource variable by the `using` keyword&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;using&lt;/span&gt; &lt;span class="nx"&gt;db&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;DBConnection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;of&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;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getClient&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;res&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;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;SELECT $1::text as message&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;Hello world!&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;info&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;rows&lt;/span&gt;&lt;span class="p"&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;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
  &lt;span class="c1"&gt;// Before going out of scope, the resource will be disposed by the function of [Symbol.asyncDispose]&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nx"&gt;isAvailableDBConnection&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Conclusion (my opinion)
&lt;/h1&gt;

&lt;p&gt;I think the most significant advantage of the &lt;code&gt;using&lt;/code&gt; keyword is the standardization it brings. While the &lt;code&gt;using&lt;/code&gt; keyword may not solve all the issues mentioned above, it is expected to bring significant improvements.&lt;/p&gt;

&lt;p&gt;In my experience, maintaining code for "resource management" in team development has often been challenging due to differences in how team members approach it and potential oversights that lead to complex runtime problems.&lt;/p&gt;

&lt;p&gt;Recently, I have been addressing this by adopting frameworks that allow for Dependency Injection (DI), managing external resources within Singleton or method-level lifecycles, and then standardizing the approach as a team. However, this approach also comes with its challenges, especially during initial development and achieving common understanding.&lt;/p&gt;

&lt;p&gt;Additionally, the management of external resource variables, which goes beyond just databases, has been an ongoing challenge.&lt;/p&gt;

&lt;p&gt;Therefore, the introduction of the &lt;code&gt;using&lt;/code&gt; keyword as a standard feature is expected to naturally lead JavaScript and TypeScript programmers to acquire this knowledge. This, in turn, can simplify resource management in team development and help maintain code quality.&lt;/p&gt;

&lt;h1&gt;
  
  
  References
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/tc39/proposal-explicit-resource-management#status"&gt;ECMAScript:proposal-explicit-resource-management&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://devblogs.microsoft.com/typescript/announcing-typescript-5-2/#using-declarations-and-explicit-resource-management"&gt;Announcing TypeScript 5.2: using Declarations and Explicit Resource Management&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.logrocket.com/resource-management-typescript-using-keyword/"&gt;Resource management in TypeScript with the using keyword&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;



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

&lt;/div&gt;

</description>
      <category>typescript</category>
      <category>javascript</category>
    </item>
    <item>
      <title>[PHP] try to reduce overhead of debug logging using Closure(same to anonymous function)</title>
      <dc:creator>genie-oh</dc:creator>
      <pubDate>Sun, 10 Apr 2022 07:55:35 +0000</pubDate>
      <link>https://dev.to/genie_oh/php-try-to-reduce-overhead-of-debug-log-using-closuresame-to-anonymous-function-3ad4</link>
      <guid>https://dev.to/genie_oh/php-try-to-reduce-overhead-of-debug-log-using-closuresame-to-anonymous-function-3ad4</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Thanks for your visiting.&lt;br&gt;
I glad if you understand that my english level is beginner.&lt;br&gt;
I would be very happy if you find and tell me any mistake made by me.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Overview
&lt;/h1&gt;

&lt;p&gt;On this article, say about 「On PHP, use Closure(same to Anonymous Function) for trying to reduce overhead of debug logging with context data which need to operation for getting」.&lt;/p&gt;

&lt;p&gt;I will glad if this article will be useful for you because Anonymous Function is useful on various case and language. &lt;/p&gt;

&lt;p&gt;Article sections are&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1. Problems for logging debug level

&lt;ul&gt;
&lt;li&gt;say performance problems when we use debug level log on production services.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;2. Try to reduce performance overhead of it using Closure

&lt;ul&gt;
&lt;li&gt;introduce concept of Closure simply. and try to solve the problem.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;3. Conclusion&lt;/li&gt;
&lt;li&gt;APPENDIX. Things to be aware of&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;※ Please understand that I don't deeply say on this article about -Debug level log must be use or NOT?- &lt;br&gt;
※ Please understand that this article contains many subjective opinion of me. I will be happy for you to send it to me if you find wrong things or other opinions.&lt;/p&gt;
&lt;h1&gt;
  
  
  1. Problems for logging debug level
&lt;/h1&gt;
&lt;h2&gt;
  
  
  1-1. It is good that we do debug level logging very frequently?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Be careful if doing operation about data to logging when do debug level logging.&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;※ for examples: merge arrays, get data with call some methods of objects.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;it may be useful that adding debug level logging to service for modifying and maintaining a application.&lt;/p&gt;

&lt;p&gt;so, it may really cases that use debug level logging with adjusting threashold by each environments to do logging on only needed environments.&lt;/p&gt;

&lt;p&gt;but, i think we may use it with a data to logging. and we may do operation about the data subconsciously because we may tend to dump data or object as debugging.&lt;/p&gt;

&lt;p&gt;examples may are (it may be extremely examples).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;// array_merge&lt;/span&gt;
&lt;span class="nv"&gt;$logger&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"request dump"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;array_merge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="c1"&gt;// method call (with calculating)&lt;/span&gt;
&lt;span class="nv"&gt;$logger&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"processed data"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$money&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;convertCurrencyTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'USD'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="c1"&gt;// instance dump&lt;/span&gt;
&lt;span class="nv"&gt;$logger&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"instance dump"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;serialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$someObject&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;exactly, it is ineffective things when debug level is excepted from logging threshold.&lt;/p&gt;

&lt;p&gt;if then, it is best solution that we don't use debug logging with operations of data?&lt;/p&gt;

&lt;h2&gt;
  
  
  1-2. How to solve it?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;do operation only case when it is needed.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;we approach like above for this problem.&lt;br&gt;
and, we use PHP Closure Concept for it.&lt;/p&gt;
&lt;h1&gt;
  
  
  2. Try to reduce performance overhead of it using Closure
&lt;/h1&gt;
&lt;h2&gt;
  
  
  2-1. What is Closure on PHP?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.php.net/manual/en/class.closure.php"&gt;https://www.php.net/manual/en/class.closure.php&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Closure on PHP, is a class to represent Anonymous Function.&lt;/p&gt;

&lt;p&gt;Anonymous Function is a function that don't have name and can created and called on runtime.&lt;br&gt;
On PHP, we define it to variable of type of &lt;code&gt;callable&lt;/code&gt; and use it as parameter, return value, and control it on runtime.&lt;/p&gt;

&lt;p&gt;Please refer below because Nice Examples are on PHP official document.&lt;br&gt;
&lt;a href="https://www.php.net/manual/en/functions.anonymous.php"&gt;https://www.php.net/manual/en/functions.anonymous.php&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On this article, say only point of that &lt;code&gt;pass as parameter and execution it only cases which is needed - similler to lazy execution -&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;※ It not perfect but Anonymous Function can allow for us do things that is similler to functional programming.&lt;br&gt;
※ It may nice for you that refer to specifications of first-class function.&lt;/p&gt;
&lt;h2&gt;
  
  
  2-2. write method for debug logging with Closure
&lt;/h2&gt;

&lt;p&gt;try to write like below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;debugLog&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Closure&lt;/span&gt; &lt;span class="nv"&gt;$closureForContext&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// skip if logging threshold is upper from DEBUG on environment.&lt;/span&gt;
    &lt;span class="c1"&gt;// self::LOGGING_THRESHOLD refer to global setting of each environments.&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;LOGGING_THRESHOLD&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nc"&gt;Logger&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;DEBUG&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="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// call Closure as function to get Context Array we need to do logging.&lt;/span&gt;
    &lt;span class="nv"&gt;$context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$closureForContext&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="nv"&gt;$closureForContext&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;monolog&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Logger&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;DEBUG&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$context&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2-3. write code to call it
&lt;/h2&gt;

&lt;p&gt;when use it, pass to Closure as parameter with data providing logic.&lt;br&gt;
use() syntax can allow for you to use variables in scope of it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$exampleLogger&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;debugLog&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;"request dump"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$request&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="nb"&gt;array_merge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2-4. describe it
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tSArNXux--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xpyjf4idgf39ulh0ji3d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tSArNXux--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xpyjf4idgf39ulh0ji3d.png" alt="Image description" width="564" height="614"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On doing debug level logging, data providing logic will be called only cases which is needed because we make it to anonymous function. &lt;/p&gt;

&lt;p&gt;only adding of determination of environment and makeing logic to closure, we may can reduce overhead because logic will be not executed on production environment.&lt;/p&gt;

&lt;h2&gt;
  
  
  2-5. Simply Performance Check
&lt;/h2&gt;

&lt;p&gt;It may extreme example, but we may see how much different are on elapsed time between using closure or not.&lt;br&gt;
I think it has potential to bring very nice effects with very simply thinking and action.&lt;/p&gt;

&lt;h3&gt;
  
  
  condition about running
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;except DEBUG level from throshold of logging on PHP Symfony&amp;amp;Monolog&lt;/li&gt;
&lt;li&gt;estimate elapsed time for related code execution using &lt;code&gt;microtime(true)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;perform 1,000,000 times for looping on same environment&lt;/li&gt;
&lt;li&gt;as context of log, set results of array_merge() as parameter.

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;array_merge($request-&amp;gt;headers, $request-&amp;gt;query, $request-&amp;gt;post)&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  result of elapsed time by cases of it.
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;-&lt;/th&gt;
&lt;th&gt;simply logging with context&lt;/th&gt;
&lt;th&gt;with Closure&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1 time&lt;/td&gt;
&lt;td&gt;1.0609450340271&lt;/td&gt;
&lt;td&gt;0.11742901802063&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2 time&lt;/td&gt;
&lt;td&gt;1.056135892868&lt;/td&gt;
&lt;td&gt;0.12697911262512&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3 time&lt;/td&gt;
&lt;td&gt;1.2411420345306&lt;/td&gt;
&lt;td&gt;0.11956310272217&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;average&lt;/td&gt;
&lt;td&gt;1.11 sec&lt;/td&gt;
&lt;td&gt;0.12 sec&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;※ it may more nice if we use profiler for analyzing it.&lt;/p&gt;

&lt;h1&gt;
  
  
  3. Conclusion
&lt;/h1&gt;

&lt;p&gt;we may can try to reduce of overhead using Closure(Anonymous Function) on PHP with Controling execution timing of operation.&lt;/p&gt;

&lt;p&gt;That's conclusion.&lt;br&gt;
if you need to learn more, it may nice to refer &lt;code&gt;Lazy Execution&lt;/code&gt; concept.&lt;/p&gt;

&lt;p&gt;we need to be careful using it with correct recognize, but it may bring improvement of productivity as well as reducing overhead  because it can allow for us to reduce strong coupling and make high reuseable module.&lt;/p&gt;

&lt;p&gt;at this article, said very small part about it. &lt;br&gt;
I will glad if you can wide your idea of solving on implements a feature becuase anonymous function is very useful for us.&lt;/p&gt;

&lt;h1&gt;
  
  
  Appendix. About things to be aware of
&lt;/h1&gt;

&lt;p&gt;in this section, say that you may get it wrong by my mistaking of describe.&lt;/p&gt;

&lt;h3&gt;
  
  
  A-1. NOT always best way that do logging DEBUG level
&lt;/h3&gt;

&lt;p&gt;My opinion is that doing debug level logging is good because very useful on maintaining application quality and throuble shooting on all environments if some rules is defined.&lt;br&gt;
But, it may be high ideals because it is difficult that define and maintain rules and quality on development as team. &lt;br&gt;
so, if do it, we should consider it be carefully. if do not it, we may meet annoying problems of overhead and many worthless loggings.&lt;/p&gt;

&lt;h3&gt;
  
  
  A-2. NOT always nice way, Closure is.
&lt;/h3&gt;

&lt;p&gt;Closure will be make a little of more overhead than simply pass array to debug log. so, not using closure may good if only consist of things that simply pass array about debug logging.&lt;/p&gt;

&lt;p&gt;For example, if we use Closure, it make things that memory allocation for making instance of Closure, creation and destroy of Callstack for call Closure Function with Context Switching.&lt;/p&gt;

&lt;p&gt;But, it is very useful when you frequency use debug logging with data that need to heavy operation like array_merge.&lt;/p&gt;

&lt;p&gt;Additionally, on some cases, it may make us to difficult to analyze source code and program flow.&lt;/p&gt;

&lt;p&gt;So, we need to use it to proper cases.&lt;/p&gt;

&lt;h3&gt;
  
  
  A-3. NOT only ways only on PHP
&lt;/h3&gt;

&lt;p&gt;Anonymous Function is concept which is used various programming languages.&lt;/p&gt;

&lt;p&gt;Some differents are. but the concept is very similler in various languages. so, please try to use it more useful to other languages.&lt;/p&gt;

</description>
      <category>php</category>
      <category>logging</category>
      <category>performance</category>
      <category>functional</category>
    </item>
    <item>
      <title>Thinking about making external API to Mock API Server with Mockoon</title>
      <dc:creator>genie-oh</dc:creator>
      <pubDate>Sun, 03 Apr 2022 02:26:12 +0000</pubDate>
      <link>https://dev.to/genie_oh/thinking-about-making-external-api-to-mock-api-server-with-mockoon-3p4</link>
      <guid>https://dev.to/genie_oh/thinking-about-making-external-api-to-mock-api-server-with-mockoon-3p4</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Thanks for your visiting.&lt;br&gt;
I glad if you understand that my english level is beginner.&lt;br&gt;
I would be very happy if you find and tell me any mistake made by me.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  0. outlines
&lt;/h1&gt;

&lt;p&gt;Integration of external API services in web services can greatly improve productivity and provide chance to make new value. but, due to the limitation of environment and specification provided from that services, I think you have various difficult experiences in maintenance and repair on integration development and continuously integration and testing.&lt;/p&gt;

&lt;p&gt;In this article, consider "How to make an external API to MockAPI to make software to more easier on testing, operating and maintain?".&lt;/p&gt;

&lt;p&gt;This article sections are &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1. Introduce Mockoon (Mock API Server)

&lt;ul&gt;
&lt;li&gt;describe about Mockoon simply&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;2. Mockoon TIP

&lt;ul&gt;
&lt;li&gt;describe useful tips to use MockAPI more helpful&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;3. Manage MockAPI on code-revision and launching on Docker

&lt;ul&gt;
&lt;li&gt;describe how to use it on team-development by code-revision management and docker environment&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;4. Discussion about doing introduction of it

&lt;ul&gt;
&lt;li&gt;describe about that -why we need?, what positive effects are?, what options are?, why choice it?-&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;5. Conclusion&lt;/li&gt;

&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;※ If you already have the experiences about Mock API Serveror know it, you can start to read from section 4.&lt;br&gt;
※ This is NOT actual example. this is based on pre-investigation &amp;amp; discussion before actual introduction to team-development.&lt;br&gt;
※ Please notice that this article contains many subjective opinion of me. I will be happy for you to send it to me if you find wrong things or other opinions.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  1. Introduce Mockoon (Mock API Server)
&lt;/h1&gt;

&lt;p&gt;On this section, describe steps of installation and running  with simply test about Mock API Server.&lt;/p&gt;

&lt;p&gt;I want to you gain the sympathy of that How to easy adding and modify Mock API for simulating and testing.&lt;/p&gt;

&lt;h2&gt;
  
  
  1-1. what is Mockoon?
&lt;/h2&gt;

&lt;p&gt;Mockoon is one of &lt;code&gt;API Simulating Solutions(Tools)&lt;/code&gt;.&lt;br&gt;
it is ok to say to &lt;code&gt;Mock API Server Solution&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;it provide methods of making HTTP protocol based API features and server on Mockup Level more simply.&lt;/p&gt;
&lt;h2&gt;
  
  
  1-2. installation
&lt;/h2&gt;

&lt;p&gt;you can use &lt;code&gt;brew&lt;/code&gt; if you use MacOS.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;brew install --cask mockoon
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you can refer installation about other environments on official references.&lt;br&gt;
&lt;a href="https://mockoon.com/download/" rel="noopener noreferrer"&gt;https://mockoon.com/download/&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  1-3. run Mock API Server on local environment
&lt;/h2&gt;

&lt;p&gt;You can run Mockoon after installation.&lt;br&gt;
at the first run, Demo APIs are provided as default.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fm7v46rnyx40zkfwa38fh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fm7v46rnyx40zkfwa38fh.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can try to connect &amp;amp; see results on Demo API's to &lt;code&gt;Start Server&lt;/code&gt; on toolbar or menu.&lt;/p&gt;
&lt;h2&gt;
  
  
  1-4. try to connect &amp;amp; see result
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fjxvgx0bqnh1fqrdj5qhq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fjxvgx0bqnh1fqrdj5qhq.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This image presents that Server is running.&lt;br&gt;
try to connect to &lt;code&gt;/users&lt;/code&gt; in Demo API.&lt;/p&gt;

&lt;p&gt;you can find &lt;code&gt;0.0.0.0:3000&lt;/code&gt; is API Server's host&amp;amp;port from left side of program window. it is mean that you can connect as &lt;code&gt;http://localhost:3000/users&lt;/code&gt;. so, try it and see results.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ curl &lt;span class="nt"&gt;-v&lt;/span&gt; http://localhost:3000/users
&lt;span class="k"&gt;*&lt;/span&gt;   Trying 127.0.0.1...
&lt;span class="k"&gt;*&lt;/span&gt; TCP_NODELAY &lt;span class="nb"&gt;set&lt;/span&gt;
&lt;span class="k"&gt;*&lt;/span&gt; Connected to localhost &lt;span class="o"&gt;(&lt;/span&gt;127.0.0.1&lt;span class="o"&gt;)&lt;/span&gt; port 3000 &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="c"&gt;#0)&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; GET /users HTTP/1.1
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Host: localhost:3000
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; User-Agent: curl/7.64.1
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Accept: &lt;span class="k"&gt;*&lt;/span&gt;/&lt;span class="k"&gt;*&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&amp;lt; HTTP/1.1 200 OK
&amp;lt; Content-Type: application/json&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;charset&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;utf-8
&amp;lt; Content-Length: 4393
&amp;lt; Date: Mon, 21 Mar 2022 07:00:21 GMT
&amp;lt; Connection: keep-alive
&amp;lt; Keep-Alive: &lt;span class="nb"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;5
&amp;lt;
&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"Templating example"&lt;/span&gt;: &lt;span class="s2"&gt;"For more information about templating, click the blue 'i' above this editor"&lt;/span&gt;,
  &lt;span class="s2"&gt;"users"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;
      &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"userId"&lt;/span&gt;: &lt;span class="s2"&gt;"16861"&lt;/span&gt;,
        &lt;span class="s2"&gt;"firstname"&lt;/span&gt;: &lt;span class="s2"&gt;"Jerry"&lt;/span&gt;,
        &lt;span class="s2"&gt;"lastname"&lt;/span&gt;: &lt;span class="s2"&gt;"Simonis"&lt;/span&gt;,
        &lt;span class="s2"&gt;"friends"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;

&lt;span class="c"&gt;# ...skip&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and, you can see logs on Mockoon GUI that contains request informations.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Flgimrjvnffafnkwb2cud.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Flgimrjvnffafnkwb2cud.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;just like it, we can see API Results of Demo API.&lt;br&gt;
and at this time, it has been prepared that we make Mock API using Mockoon.&lt;/p&gt;
&lt;h2&gt;
  
  
  1-5. Add Custom Environment and Mock API
&lt;/h2&gt;

&lt;p&gt;in this part, show steps of adding Environment and MockAPI, saying how to make API and what basic features are. &lt;/p&gt;
&lt;h3&gt;
  
  
  1-5-a. Add new Environment on Mockoon
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;Environment&lt;/code&gt; mean that specifications of definitions of Mock API and Server. it's ok you recognize as One Project File of Mockoon. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F5qcwtybrowiw6230i00i.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F5qcwtybrowiw6230i00i.gif" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;like the gif, we can make new environment.&lt;/p&gt;

&lt;p&gt;and, we can run server and connect new environment because API having path &lt;code&gt;/&lt;/code&gt; and response &lt;code&gt;{}&lt;/code&gt; is generated as default.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ curl http://localhost:3001
&lt;span class="o"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  1-5-b. Add Mock API (set Route, Header, Body)
&lt;/h3&gt;

&lt;p&gt;Try to add Mock API that has &lt;code&gt;/hello&lt;/code&gt; route path and will response &lt;code&gt;world&lt;/code&gt; with &lt;code&gt;text/plain&lt;/code&gt; Content-Type Header.&lt;/p&gt;

&lt;p&gt;steps are&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;click &lt;code&gt;new route&lt;/code&gt; in menu bar&lt;/li&gt;
&lt;li&gt;set &lt;code&gt;hello&lt;/code&gt; on the path at right up side.&lt;/li&gt;
&lt;li&gt;set &lt;code&gt;world&lt;/code&gt; on the body at right down side.&lt;/li&gt;
&lt;li&gt;set &lt;code&gt;Content-type: text/plain&lt;/code&gt; at Headers TAB.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I can added Mock API easily.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F8690acy34nzmthlx7rru.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F8690acy34nzmthlx7rru.gif" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  1-5-c. test API
&lt;/h3&gt;

&lt;p&gt;try to make request to &lt;code&gt;http://localhost:3001/hello&lt;/code&gt;.&lt;br&gt;
you can see successfully connected &amp;amp; received response from mock API.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ curl &lt;span class="nt"&gt;-v&lt;/span&gt; http://localhost:3001/hello
&lt;span class="c"&gt;# ...skip&lt;/span&gt;
&amp;lt; Content-Type: text/plain&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;charset&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;utf-8
&amp;lt; Content-Length: 5
&lt;span class="c"&gt;# ...skip&lt;/span&gt;
world
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  2. Mockoon Tips
&lt;/h1&gt;

&lt;p&gt;I have told how to make MockAPI with very simple case.&lt;br&gt;
I think it is very easy to make MockAPI with Mockoon. I glad if you have same thinking.&lt;/p&gt;

&lt;p&gt;But, we need to more features to develop services although objective are simulating and testing.&lt;/p&gt;

&lt;p&gt;so, in this parts, introduce helpful tips to add and modify Mock API more simply, more widely.&lt;/p&gt;
&lt;h2&gt;
  
  
  2-1. Routing
&lt;/h2&gt;

&lt;p&gt;Mockoon provides some features about Routing of URI path.&lt;br&gt;
if you want, can see it at below official document.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://mockoon.com/docs/latest/routing/" rel="noopener noreferrer"&gt;https://mockoon.com/docs/latest/routing/&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  2-1-a. API route prefix
&lt;/h3&gt;

&lt;p&gt;Common prefix is provided that effects entire path on one environment.&lt;/p&gt;

&lt;p&gt;it can setted on &lt;code&gt;Settings-&amp;gt;API URL-&amp;gt;prefix&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  2-1-b. Route Patterns
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;Pattern Matching on uri path&lt;/code&gt; is provided like &lt;code&gt;?&lt;/code&gt;, &lt;code&gt;+&lt;/code&gt;.&lt;br&gt;
it will be possible to dynamically perform like various path by one defining. &lt;/p&gt;

&lt;p&gt;the expression is follow &lt;code&gt;express.js&lt;/code&gt; specs. &lt;/p&gt;
&lt;h3&gt;
  
  
  2-1-c. Route Parameters
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;parameter using uri segmentation&lt;/code&gt; is provided.&lt;br&gt;
can use by defining &lt;code&gt;/:parameter_name&lt;/code&gt; on route path.&lt;br&gt;
can get and use by defining &lt;code&gt;{{urlParam 'paramName'}}&lt;/code&gt;.(feature of templating on Mockoon)&lt;/p&gt;
&lt;h3&gt;
  
  
  2-1-d. Query Parameters
&lt;/h3&gt;

&lt;p&gt;can use QueryString as Parameter&lt;/p&gt;

&lt;p&gt;can get and use by defining &lt;code&gt;{{queryParam 'paramName'}}&lt;/code&gt;.(feature of templating on Mockoon)&lt;/p&gt;
&lt;h2&gt;
  
  
  2-2. Helpers
&lt;/h2&gt;

&lt;p&gt;Mockoon provides more feature as Helper to make Mock API more dynamically and widely.&lt;/p&gt;

&lt;p&gt;to use helpers on response body or others, we need to call  following template likes &lt;code&gt;{{helperName param1 param2}}&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Helpers consist of parts of HandleBars Helper, Mockoon Custom Helper, Request Helper and faker.js Helper.&lt;/p&gt;
&lt;h3&gt;
  
  
  2-2-a. HandleBars Helper
&lt;/h3&gt;

&lt;p&gt;Mockoon provides features of &lt;code&gt;HandleBars&lt;/code&gt;.&lt;br&gt;
so, you can use expression of &lt;code&gt;if, else, each, with and others&lt;/code&gt; provided by HandlerBars.&lt;/p&gt;

&lt;p&gt;more informations, please refer to&lt;br&gt;
&lt;a href="https://handlebarsjs.com/guide/builtin-helpers.html" rel="noopener noreferrer"&gt;https://handlebarsjs.com/guide/builtin-helpers.html&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  2-2-b. Mockoon Custom helper
&lt;/h3&gt;

&lt;p&gt;Custom Helper provide by Mockoon.&lt;br&gt;
you can use utilities related &lt;code&gt;Array, Math, String, Date and others&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;more informations, please refer to&lt;br&gt;
&lt;a href="https://mockoon.com/docs/latest/templating/mockoon-helpers/" rel="noopener noreferrer"&gt;https://mockoon.com/docs/latest/templating/mockoon-helpers/&lt;/a&gt; &lt;/p&gt;
&lt;h3&gt;
  
  
  2-2-c. Request Helper
&lt;/h3&gt;

&lt;p&gt;can get and use request informations likes &lt;code&gt;body payload, query parameter, cookie, host information and others&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;more informations, please refer to&lt;br&gt;
&lt;a href="https://mockoon.com/docs/latest/templating/mockoon-request-helpers/" rel="noopener noreferrer"&gt;https://mockoon.com/docs/latest/templating/mockoon-request-helpers/&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  2-2-d. faker.js Helper
&lt;/h3&gt;

&lt;p&gt;Mockoon provides &lt;code&gt;faker.js&lt;/code&gt; features.&lt;br&gt;
it is helpful to generate random informations of &lt;code&gt;e-mail, name, address and others&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;more informations, please refer to&lt;br&gt;
&lt;a href="https://mockoon.com/docs/latest/templating/fakerjs-helpers/" rel="noopener noreferrer"&gt;https://mockoon.com/docs/latest/templating/fakerjs-helpers/&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  2-3. Other features.
&lt;/h2&gt;

&lt;p&gt;Mockoon provides various features likes &lt;code&gt;File Serving, TLS, CORS, Multi Response and others&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;more informations, please refer to&lt;br&gt;
&lt;a href="https://mockoon.com/docs/latest/about/" rel="noopener noreferrer"&gt;https://mockoon.com/docs/latest/about/&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  3. Code-Revision management and Running on Docker
&lt;/h1&gt;

&lt;p&gt;In this section, try to know that how to share Mock API and Environment to team and use more efficiently.&lt;/p&gt;
&lt;h2&gt;
  
  
  3-1. Code-Revision Management of Mockoon Environment File
&lt;/h2&gt;

&lt;p&gt;Environment File is that presents specifications of MockAPI and Server as i said earlier.&lt;/p&gt;

&lt;p&gt;it follows JSON format.&lt;br&gt;
if you see contents of file we make on section 2, we can find that '/hello' API and Server specifications is described.&lt;/p&gt;

&lt;p&gt;so, we can manage it on Github or other code-revision-management-solutions.&lt;br&gt;
it help us to use Mock API Server more efficiently on team-development projects.&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="nb"&gt;cat &lt;/span&gt;test-mockoon.json | jq
&lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="c"&gt;#...skip&lt;/span&gt;
  &lt;span class="s2"&gt;"port"&lt;/span&gt;: 3001,
  &lt;span class="s2"&gt;"hostname"&lt;/span&gt;: &lt;span class="s2"&gt;"0.0.0.0"&lt;/span&gt;,
&lt;span class="c"&gt;#...skip&lt;/span&gt;
  &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="c"&gt;#...skip&lt;/span&gt;
      &lt;span class="s2"&gt;"method"&lt;/span&gt;: &lt;span class="s2"&gt;"get"&lt;/span&gt;,
      &lt;span class="s2"&gt;"endpoint"&lt;/span&gt;: &lt;span class="s2"&gt;"hello"&lt;/span&gt;,
      &lt;span class="s2"&gt;"responses"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;
        &lt;span class="o"&gt;{&lt;/span&gt;
          &lt;span class="s2"&gt;"uuid"&lt;/span&gt;: &lt;span class="s2"&gt;"7e4e0df8-5b58-4655-98dc-dc912009f665"&lt;/span&gt;,
          &lt;span class="s2"&gt;"body"&lt;/span&gt;: &lt;span class="s2"&gt;"world"&lt;/span&gt;,
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3-2. Running Mock API Server on Docker with a Environment file we made.
&lt;/h2&gt;

&lt;p&gt;It may be inconvenient that installing and using GUI of Mockoon on all team members.&lt;/p&gt;

&lt;p&gt;fortunately, Mockoon provides docker image for running and testing api made by it.&lt;/p&gt;

&lt;p&gt;just like below, we can run it with local environment files or file's url of github repository .&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;# using local file path&lt;/span&gt;
docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;--mount&lt;/span&gt; &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;bind&lt;/span&gt;,source&lt;span class="o"&gt;=&lt;/span&gt;/absolute/path/to/data.json,target&lt;span class="o"&gt;=&lt;/span&gt;/data,readonly &lt;span class="nt"&gt;-p&lt;/span&gt; 3000:3000 mockoon/cli:latest &lt;span class="nt"&gt;-d&lt;/span&gt; data &lt;span class="nt"&gt;-p&lt;/span&gt; 3000

&lt;span class="c"&gt;# using file's url of github repository&lt;/span&gt;
docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 3000:3000 mockoon/cli:latest &lt;span class="nt"&gt;-d&lt;/span&gt; https://raw.githubusercontent.com/mockoon/mock-samples/main/samples/generate-mock-data.json &lt;span class="nt"&gt;-p&lt;/span&gt; 3000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you can refer more specific informations at below.&lt;br&gt;
&lt;a href="https://mockoon.com/tutorials/run-mock-api-anywhere-cli/" rel="noopener noreferrer"&gt;https://mockoon.com/tutorials/run-mock-api-anywhere-cli/&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  3-3. testing API with running with Docker
&lt;/h2&gt;

&lt;p&gt;try to run server using docker with environment file we make at section 2.&lt;/p&gt;

&lt;p&gt;below presents result of 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="nb"&gt;head &lt;/span&gt;test-mockoon.json
&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"uuid"&lt;/span&gt;: &lt;span class="s2"&gt;"0415ae77-0fe7-4baf-b92b-07819280d4d6"&lt;/span&gt;,
  &lt;span class="s2"&gt;"lastMigration"&lt;/span&gt;: 19,
  &lt;span class="s2"&gt;"name"&lt;/span&gt;: &lt;span class="s2"&gt;"Test"&lt;/span&gt;,
  &lt;span class="s2"&gt;"endpointPrefix"&lt;/span&gt;: &lt;span class="s2"&gt;""&lt;/span&gt;,
  &lt;span class="s2"&gt;"latency"&lt;/span&gt;: 0,
  &lt;span class="s2"&gt;"port"&lt;/span&gt;: 3001,
  &lt;span class="s2"&gt;"hostname"&lt;/span&gt;: &lt;span class="s2"&gt;"0.0.0.0"&lt;/span&gt;,
  &lt;span class="s2"&gt;"routes"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;
    &lt;span class="o"&gt;{&lt;/span&gt;
❯
❯ docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;--mount&lt;/span&gt; &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;bind&lt;/span&gt;,source&lt;span class="o"&gt;=&lt;/span&gt;/Users/oh/Develop/test-mockoon.json,target&lt;span class="o"&gt;=&lt;/span&gt;/data,readonly &lt;span class="nt"&gt;-p&lt;/span&gt; 3001:3001 mockoon/cli:latest &lt;span class="nt"&gt;-d&lt;/span&gt; data &lt;span class="nt"&gt;-p&lt;/span&gt; 3001
de956b5a8b15415b5c46ff008d5b0db404a5d2670055fde14cf6621d0746821b
❯
❯ docker ps
CONTAINER ID   IMAGE                COMMAND                  CREATED              STATUS              PORTS                    NAMES
de956b5a8b15   mockoon/cli:latest   &lt;span class="s2"&gt;"mockoon-cli start -…"&lt;/span&gt;   About a minute ago   Up About a minute   0.0.0.0:3001-&amp;gt;3001/tcp   goofy_cohen
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

❯ curl http://localhost:3001/hello
world
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3-4. About using more efficiently on Team-Development
&lt;/h2&gt;

&lt;p&gt;I think it is good on developing on team that using Mock API Server. just like below.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;define Mock API and Environment using Mockoon&lt;/li&gt;
&lt;li&gt;push to Github Repository&lt;/li&gt;
&lt;li&gt;share it to team&lt;/li&gt;
&lt;li&gt;each member, try to run Mock API Server using Docker command with environment file url on Github Repository&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;it will be useful because we can use same Mock API environment on all members.&lt;/p&gt;

&lt;h1&gt;
  
  
  4.Discussion about doing introduction of it
&lt;/h1&gt;

&lt;p&gt;in this section, say about introduction of Mock API Server by below 3 points.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Why we need to make external API to Mock API Server?&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;What positive effects are?&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;What other options are? Why choose Mock API Server as solution?&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  4-1. Why we need to make external API to Mock API Server?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;To cut off strong coupling of them&lt;/strong&gt;&lt;br&gt;
that is important purpose of making it to mock.&lt;/p&gt;

&lt;p&gt;In now, integrating external API to our services have been necessary.&lt;/p&gt;

&lt;p&gt;for example, we use it frequently that social login, payment gateway, e-mail sending, service monitoring and others for user convenience or business strategy.&lt;/p&gt;

&lt;p&gt;it is very valuable things because we can deliver value to user that we can't it by only our's power originally.&lt;/p&gt;

&lt;p&gt;But, I think integrating of external API may make some annoying features like below.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;features that has very strongly coupling with external API on our services. (it may make testing and separation of concerns to hard)&lt;/li&gt;
&lt;li&gt;features that are very difficult for us to control. (API provider has all ownership.)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;it will be negative factors on maintaining software quality and developing as team.&lt;br&gt;
so, we need to discuss about -How we cut off coupling of them and make maintaining and developing to be easy-.&lt;/p&gt;

&lt;p&gt;-Mock API Server- is one solution for that question.&lt;/p&gt;

&lt;h2&gt;
  
  
  4-2. What positive effects are?
&lt;/h2&gt;

&lt;p&gt;say two points in many things may are.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a. improvement development productivity as team&lt;/li&gt;
&lt;li&gt;b. improvement usability about CI and Auto-Testing&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4-2-a. improvement development productivity as team
&lt;/h3&gt;

&lt;p&gt;I think it is problem we meet commonly on integrating external API.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Waiting time about preparing API environment from Provider.&lt;/li&gt;
&lt;li&gt;Limitation of access to API&lt;/li&gt;
&lt;li&gt;Mis-matching understanding about API specs between team members.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I think that pre-developing of Mock API will relief it because we can try to cut off coupling of them and manage API specs with centralizing.&lt;/p&gt;

&lt;h3&gt;
  
  
  4-2-b. improvement usability about CI and Auto-Testing
&lt;/h3&gt;

&lt;p&gt;We can regard Mock API Server as stand-alone service.&lt;br&gt;
so, we can try to cut off coupling between application and mock logic almost perfectly unlike MockClass or MockLibrary.&lt;/p&gt;

&lt;p&gt;due to it, we can expect below&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Can make as coverage on Auto-Testing and CI&lt;/li&gt;
&lt;li&gt;Can separate concerns about application and mock logic. so, it will make adding and modifying of software to more easily.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;it will relief our burdens about existing problems we have met on CI and Auto-Testing.&lt;br&gt;
and, it will be make maintaining software quality to be more efficiently.&lt;/p&gt;

&lt;h2&gt;
  
  
  4-3. What other options are? Why choose Mock API Server as solution?
&lt;/h2&gt;

&lt;p&gt;i think there are below solutions generally.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;① （choice） Mock API Server&lt;/li&gt;
&lt;li&gt;② DON'T make mock. exclude it from coverage of auto-testing.&lt;/li&gt;
&lt;li&gt;③ make MockClass&lt;/li&gt;
&lt;li&gt;④ use Mock Library with separating layer about business logic.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4-3-a. The reason of choosing Mock API Server
&lt;/h3&gt;

&lt;p&gt;in options, I think Mock API Server has nice merit compare with others.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Very easy to add and modify Mock API.&lt;/li&gt;
&lt;li&gt;Can separate concerns almost perfectly between application and mock logic.&lt;/li&gt;
&lt;li&gt;Very helpful to make understanding to be equalative in team-members.&lt;/li&gt;
&lt;li&gt;Very helpful to manage and maintain of informations.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4-3.b. What problem are in others?
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;■ ② DON'T make mock. exclude it from coverage of auto-testing.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It may frequently things in development.&lt;/p&gt;

&lt;p&gt;I think The reasons are &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Need more times for developing.&lt;/li&gt;
&lt;li&gt;Level of difficulty about it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;but, Mock API Server is specialized solution to make it with very small times and very simply.&lt;/p&gt;

&lt;p&gt;if we don't it although it's easily and simply, we may lose nice opportunities that brought by mock.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;■ ③ make MockClass, ④ use Mock Library with separating layer about business logic&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;this options have merit that we can develop freely.&lt;br&gt;
but, i think it has below problems may annoy to us for long time.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Burdens about developing Mock Logic&lt;/li&gt;
&lt;li&gt;Level of Difficulty about software design, developing, maintaining software quality&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;actually, the method of ③ is always needed concerns of maintaining clean architecture using knowledges of OOP, Design Patterns -for examples, making Provider Class likes Factory, design class relationship with Dependency Injection-.&lt;/p&gt;

&lt;p&gt;additionally, about ④, may be needed DDD design knowledges for separation of layer of business logics.&lt;/p&gt;

&lt;p&gt;if we don't do it, we will meet more annoying problems about  badly software quality than that we don't make mock.&lt;br&gt;
and, it will be more difficulty problems if we develop software as team.&lt;/p&gt;

&lt;p&gt;i think one key reason is -strong coupling between application and mock logics.&lt;/p&gt;

&lt;p&gt;we can cut off coupling about external API system to develop mock logic.&lt;br&gt;
but, it may make new problem that make newly coupling between application and mock logic. and it will make developing more hardly because we need to think same concern about application and mock logic.&lt;/p&gt;

&lt;p&gt;it may not problem if service is micro.&lt;br&gt;
but, it will increase very rapidly according to be bigger of service. I think that's very difficulty problem to us.&lt;/p&gt;

&lt;h1&gt;
  
  
  5. Conclusion
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;We would try to it because it will be bring nice merits about developing as team, maintaining software quality if we need to integrate external API and we need to service continuously&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;that's my conclusion.&lt;/p&gt;

&lt;p&gt;of course, it may has some problems and don't solve all problems. for example, it may are that -cases we can't solve using it, handle to exceptional cases, increase management point about service-.&lt;/p&gt;

&lt;p&gt;but, I think merits are bigger than de-merit.&lt;/p&gt;

&lt;p&gt;actually, i have met many problems with developing and operating complicated service that integrated with several external API to one service and has served for long term and is monolithic service.&lt;/p&gt;

&lt;p&gt;By Introducing Mock API Server, we can try to -cut off coupling about external API- and -make developing as team, Auto-Testing, and CI to be more efficiently-.&lt;br&gt;
so, I expect that it contributes to refactoring of monolithic service architecture with improvement of development.&lt;/p&gt;

&lt;h1&gt;
  
  
  References
&lt;/h1&gt;

&lt;p&gt;I have referred below for studying it.&lt;br&gt;
please refer to if you have interesting about it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Comparison_of_API_simulation_tools" rel="noopener noreferrer"&gt;https://en.wikipedia.org/wiki/Comparison_of_API_simulation_tools&lt;/a&gt;&lt;br&gt;
&lt;a href="https://developers.amadeus.com/blog/helpful-tools-to-create-mock-servers" rel="noopener noreferrer"&gt;https://developers.amadeus.com/blog/helpful-tools-to-create-mock-servers&lt;/a&gt;&lt;/p&gt;

</description>
      <category>mock</category>
      <category>mockoon</category>
      <category>api</category>
      <category>mockserver</category>
    </item>
  </channel>
</rss>
