<?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: Dominique Péré</title>
    <description>The latest articles on DEV Community by Dominique Péré (@domis66).</description>
    <link>https://dev.to/domis66</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%2F140171%2F3f5a55f5-8f2c-4896-8a01-11abc701ad1d.jpeg</url>
      <title>DEV Community: Dominique Péré</title>
      <link>https://dev.to/domis66</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/domis66"/>
    <language>en</language>
    <item>
      <title>8 simple steps to add a serverless back end to a Vue.js project</title>
      <dc:creator>Dominique Péré</dc:creator>
      <pubDate>Tue, 23 Jun 2020 10:01:26 +0000</pubDate>
      <link>https://dev.to/oxygenit/8-simple-steps-to-add-a-serverless-back-end-to-a-vue-js-project-2j60</link>
      <guid>https://dev.to/oxygenit/8-simple-steps-to-add-a-serverless-back-end-to-a-vue-js-project-2j60</guid>
      <description>&lt;p&gt;It's often recommended in the JAMstack best practices to delegate to serverless cloud functions the dynamic parts of an app. To that end, let me introduce you &lt;a href="https://scaledynamics.io/warpjs" rel="noopener noreferrer"&gt;WarpJS&lt;/a&gt;, a new serverless approach. It's a JavaScript engine to develop back ends, to bridge the gap with the front end and to deploy it as serverless functions in no time. Made for JavaScript developers with love!&lt;/p&gt;

&lt;p&gt;Without any further ado, let's get started!&lt;/p&gt;

&lt;p&gt;(If you don't feel like reading, we've also created a &lt;a href="https://youtu.be/-1aP7LhIkdc" rel="noopener noreferrer"&gt;video tutorial&lt;/a&gt; for this!)&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;1. Initialize project&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Starting from scratch, with a freshly created Vue.js project.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cli.vuejs.org/" rel="noopener noreferrer"&gt;https://cli.vuejs.org/&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @vue/cli @vue/cli-service-global
&lt;span class="nv"&gt;$ &lt;/span&gt;vue create &amp;lt;project-name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Alternatively, you can fork the project right &lt;a href="https://github.com/WarpJS/samples/tree/master/vue" rel="noopener noreferrer"&gt;here&lt;/a&gt; and skip all the code source copy/pasting steps.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;2. Create the back end&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Let's create a &lt;code&gt;server&lt;/code&gt; directory at the root of your main project and initialize a new Node.js project inside 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="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; &amp;lt;project-name&amp;gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;server
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;server
&lt;span class="nv"&gt;$ &lt;/span&gt;npm init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we will create a Basic HTTP Proxy in Node.js in order to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fetch data from a REST API (&lt;a href="https://jsonplaceholder.typicode.com/users" rel="noopener noreferrer"&gt;https://jsonplaceholder.typicode.com/users&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Filter data to avoid to request too much data as client side&lt;/li&gt;
&lt;li&gt;Add random avatar in response&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To do so, we first need to install the &lt;a href="https://www.npmjs.com/package/axios" rel="noopener noreferrer"&gt;Axios library&lt;/a&gt; we need:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;axios
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;3. Create a serverless function&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Then I create an &lt;code&gt;index.js&lt;/code&gt;, and I retrieve first with Axios the flow. I will reduce the attributes, keeping only the id, the email… and a couple of others. I've also added a Lego random portrait (because.).&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;axios&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;axios&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;getUsers&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;// fetch users from API&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;}&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;axios&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;https://jsonplaceholder.typicode.com/users&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Pick attributes and add photo&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&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="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;phone&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;company&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;address&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;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;phone&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;city&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;city&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;work&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;company&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;photo&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://randomuser.me/api/portraits/lego/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&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="mi"&gt;10&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;.jpg&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;p&gt;But most importantly I export this function:&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;// getUsers will be the function that you will can call directly in the framework&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getUsers&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will tell WarpJS: "okay, I need this function to be turned serverless and to be hosted as a serverless function". That way we don't have at all to deal with HTTPS, we don't deal with the arguments, the errors, the endpoints, or anything else.&lt;/p&gt;

&lt;p&gt;So now let's see how to set it up!&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;4. Configure WarpJS&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;In my server project, I need to create a WarpJS configuration file, &lt;code&gt;warp.config.js&lt;/code&gt; as follows:&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="na"&gt;project&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;project-server-name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;node-module&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="c1"&gt;// path to the "node_modules" directory of your main project&lt;/span&gt;
    &lt;span class="na"&gt;projectPath&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="c1"&gt;// module name to import it in your main project&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;warp-server&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;p&gt;Thanks to the &lt;code&gt;node-module&lt;/code&gt; &lt;a href="https://warpjs.dev/docs/api/warp-config#output" rel="noopener noreferrer"&gt;output format&lt;/a&gt;, WarpJS will generate an npm package named &lt;code&gt;warp-server&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Why this option?&lt;/p&gt;

&lt;p&gt;&lt;code&gt;node\_modules&lt;/code&gt; is a safe directory: each framework uses tools like &lt;code&gt;Babel&lt;/code&gt;, &lt;code&gt;ESLint&lt;/code&gt;, … and here, you are sure that the generated code will not be transpiled or something else.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Really easy to import: no relative path to know, you can directly do: &lt;code&gt;import WarpServer from &amp;amp;quot;warp-server&amp;amp;quot&lt;/code&gt;;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;5. Setup WarpJS in project&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;We now need the &lt;a href="https://warpjs.dev/docs/api/cli" rel="noopener noreferrer"&gt;WarpJS CLI&lt;/a&gt; in the main project to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://warpjs.dev/docs/api/cli#start-emulator" rel="noopener noreferrer"&gt;Start&lt;/a&gt; the WarpJS emulator in development mode to simulate serverless function on localhost&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://warpjs.dev/docs/api/cli#build" rel="noopener noreferrer"&gt;Build&lt;/a&gt; the WarpJS client helper module in order to call the serverless function&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://warpjs.dev/docs/api/cli#deploy" rel="noopener noreferrer"&gt;Deploy&lt;/a&gt; the serverless function and optionally the static build of the main project&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the client project, you can now install the engine with all the dependencies.&lt;/p&gt;

&lt;p&gt;You can request a WarpJS account by following this [link]&lt;a href="https://scaledynamics.io/warpjs" rel="noopener noreferrer"&gt;https://scaledynamics.io/warpjs&lt;/a&gt;) 😬&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; @warpjs/engine
&lt;span class="nv"&gt;$ &lt;/span&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;warp npm-run-all &lt;span class="nt"&gt;--save-dev&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;About the parent project, I want to change the way the project is served for local run, and built for deployment. To do this, I add scripts in &lt;code&gt;package.json&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So we will go from this :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"serve"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"vue-cli-service serve"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"vue-cli-service build"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"lint"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"vue-cli-service lint"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"postinstall"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cd ./server &amp;amp;&amp;amp; npm install"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;

  &lt;/span&gt;&lt;span class="nl"&gt;"serve:client"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"vue-cli-service serve"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"serve:server"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"warp start-emulator -w ./server"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"serve"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"run-p serve:*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;

  &lt;/span&gt;&lt;span class="nl"&gt;"build:client"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"vue-cli-service build"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"build:server"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"warp build ./server"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"run-s build:server build:client"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;

  &lt;/span&gt;&lt;span class="nl"&gt;"deploy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"warp deploy --asset-dir dist/ ./server"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;

  &lt;/span&gt;&lt;span class="nl"&gt;"lint"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"vue-cli-service lint"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's break it down a bit to understand it clearly:&lt;/p&gt;

&lt;p&gt;I'm turning the existing &lt;code&gt;serve&lt;/code&gt; command to &lt;code&gt;serve:client&lt;/code&gt;, because now I will basically build at once the server and client.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"build:client"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"vue-cli-service build"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So here I have the warp emulator, helping me to emulate the serverless function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"serve:server"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"warp start-emulator -w ./server"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And here, I have the &lt;code&gt;serve&lt;/code&gt; command, that will serve both the client and server on two distinct HTTP ports:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"serve"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"run-p serve:*"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then I'm adding whatever is needed to build the clients and the server for deployment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"build:client"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"vue-cli-service build"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"build:server"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"warp build ./server"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"run-s build:server build:client"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The client doesn't change, it's still my Vue project. The server will build with Warp because it's Warp serverless function.&lt;/p&gt;

&lt;p&gt;I'm finally adding the "deploy" command, we'll how it works a bit later&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"deploy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"warp deploy --asset-dir dist/ ./server"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;6. Create the front end&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Let's see now how we can call this serverless function from our front-end project.&lt;/p&gt;

&lt;p&gt;First, you have to import the &lt;a href="https://warpjs.dev/docs/api/engine" rel="noopener noreferrer"&gt;WarpJS engine&lt;/a&gt;, once for all in the app. We recommend to initialize it in the entry point of your main project:&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;// src/main.js&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@warpjs/engine&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;Now we create a new component — let's call this &lt;code&gt;users.vue&lt;/code&gt; — and paste the template that you can find right &lt;a href="https://github.com/WarpJS/samples/blob/master/vue/src/components/Users.vue" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;There is a CSS and a bit of JavaScript which will do the trick for us. So the only part of JavaScript we need is this:&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;// init WarpJS&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;WarpServer&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;warp-server&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getUsers&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;WarpServer&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="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Users&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;data&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="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="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="na"&gt;mounted&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="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;getUsers&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;data&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;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/script&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And actually the very part of WarpJS is&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getUsers&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;WarpServer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and&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="nf"&gt;getUsers&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;data&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;where we are actually calling the function. It feels like we're calling a local function but it's not, we are calling the serverless function.&lt;/p&gt;

&lt;p&gt;Last thing I need to do is to call that component in my application, so I just replace the "HelloWorld" component from the template project, by my users component, I import the component itself, and I call the JavaScript.&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&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="s1"&gt;./components/Users.vue&lt;/span&gt;&lt;span class="dl"&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="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;App&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;components&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;Users&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;lt;&lt;/span&gt;&lt;span class="sr"&gt;/script&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So last thing to log in into WarpJS to be able to build and deploy this!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;npx warp login
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;7. Run locally&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;It's pretty easy as we prepared the command line, we just have to type &lt;code&gt;npm run serve&lt;/code&gt;, and then we serve both client and server. It opens a browser tab, and it's working!&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%2Fmiro.medium.com%2Fmax%2F1280%2F0%2ABBpvc7S_ITKY3F6Z" 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%2Fmiro.medium.com%2Fmax%2F1280%2F0%2ABBpvc7S_ITKY3F6Z" width="1280" height="630"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We got everything, our users, filtered by the proxy, with the email addresses, the names…&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;8. Deploy front on CDN and back on Serverless&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Let's see out deployed is now online. Actually, this is one of the simplest things to do with WarpJS. You just need to build, first, your project with the build command line we prepared&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;npm run build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and then we type in another command:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;We prepared it just before in be package.json. Let's have another look to that one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"deploy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"warp deploy --asset-dir dist/ ./server"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means I want WarpJS to deploy the server part from the "server" directory, and the asset directory to a CDN from the "dist" folder, which has just been built.&lt;/p&gt;

&lt;p&gt;The server project is obviously deployed with WarpJS, on the cloud, here on Google functions, the front-end is deployed on a Google CDN (more options with AWS and Cloudflare are coming though)&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%2Fmiro.medium.com%2Fmax%2F1280%2F0%2AH21bJNCL6XGYEjPo" 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%2Fmiro.medium.com%2Fmax%2F1280%2F0%2AH21bJNCL6XGYEjPo" width="999" height="506"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Your project is now live!&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;So we got a URL, with our client and server: everything is hosted. We did not have to deal with the HTTPS security, the CORS, anything. Everything is just under control there.&lt;/p&gt;

&lt;p&gt;You can find the full project code on &lt;a href="https://github.com/WarpJS/samples" rel="noopener noreferrer"&gt;GitHub under WarpJS/samples&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So we have examples with Angular as well with REACT, and obviously the full code for &lt;a href="https://github.com/WarpJS/samples/tree/master/vue" rel="noopener noreferrer"&gt;Vue.js I just did with you&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;I hope you enjoyed this tutorial, and if you have any questions, please feel free to ask in the comment section!&lt;/p&gt;

&lt;p&gt;Next in this series is a REACT and an Angular tutorial! So stay tuned ;)&lt;/p&gt;

&lt;h4&gt;
  
  
  Credits
&lt;/h4&gt;

&lt;p&gt;Big thanks to &lt;a href="[https://twitter.com/NicoPennec](https://twitter.com/NicoPennec)"&gt;Nicolas Pennec&lt;/a&gt; who developed the app we took as an example. He is a JavaScript Expert in ScaleDynamics. He co-organizes RennesJS, a French JavaScript Meetup, so if you come by Brittany you're more than welcome to join us!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Implementing a serverless API proxy in 10 minutes</title>
      <dc:creator>Dominique Péré</dc:creator>
      <pubDate>Fri, 28 Feb 2020 15:49:58 +0000</pubDate>
      <link>https://dev.to/oxygenit/implementing-a-serverless-api-proxy-in-10-minutes-4719</link>
      <guid>https://dev.to/oxygenit/implementing-a-serverless-api-proxy-in-10-minutes-4719</guid>
      <description>&lt;p&gt;&lt;em&gt;This article has been updated on May 26th, 2020, following the latest release of WarpJS serverless.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Serverless has become a hot topic lately, as it offers auto-scaling, flexibility, and a shorter time to release. If like me you don't want to manage servers on a daily basis but rather focus on the features' code, serverless is an option you might want to consider.&lt;/p&gt;

&lt;p&gt;Serverless is most commonly used for &lt;a href="https://serverless.com/blog/2018-serverless-community-survey-huge-growth-usage" rel="noopener noreferrer"&gt;web applications and back ends, but also for data processing&lt;/a&gt;. By the way, there is a lot of noise and confusion about what serverless is, so, to be precise, I only mean Function-as-a-Service (or FaaS) when speaking about serverless here.&lt;/p&gt;

&lt;p&gt;Most JavaScript full-stack developers develop their applications with React, Vue.js, or Angular,  served by Node.js + Express. With the serverless approach, I see the opportunity of making development iterations shorter to free up time for what matters: the features' code.&lt;/p&gt;

&lt;p&gt;In this post, I will explain how to implement a proxy server for REST APIs within a few minutes using a serverless platform.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why would I implement a serverless API proxy?
&lt;/h2&gt;

&lt;p&gt;In my use case, I wanted to create an app to request the &lt;a href="https://developer.github.com/v3/search/" rel="noopener noreferrer"&gt;GitHub Search API&lt;/a&gt; and NPM at once. I wanted to perform a search on JavaScript + TypeScript repositories to display GitHub stars and the NPM weekly downloads in the same view. It's useful to make a basic evaluation of package popularity.&lt;/p&gt;

&lt;p&gt;We could do all this job in a browser. So why should we create a serverless HTTP proxy on top of the GitHub and NPM APIs?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reason 1: security&lt;/strong&gt;. API keys cannot lie in the front-end code. Malicious developers could use it to access my account, I would expose myself to renew it frequently or to be blocked by the API provider. Also, the Cross-Origin Resource Sharing (&lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS" rel="noopener noreferrer"&gt;CORS&lt;/a&gt;) is blocked by many providers. In both situations, there's no choice than to implement a proxy server.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reason 2: performance.&lt;/strong&gt; To make my GitHub+NPM data feature available, we need to request GitHub twice and NPM a lot. My browser would then perform multiple requests for each user search. A proxy server in the cloud will have much lower latency and larger bandwidth to perform these requests faster. Additionally, the JSON returned by APIs contains much more data than we need. We only need from the GitHub API 7 properties and not the 50+ the original endpoints return for each repo.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reason 3: separation of concerns&lt;/strong&gt;. Whenever an API is updated, go down or I want to switch for another instead, my client code remains unchanged, I will only change my serverless functions' code.&lt;/p&gt;

&lt;p&gt;Some other reasons to implement a proxy server include API modernization, caching, resilience, and error management, but it's another topic.&lt;/p&gt;

&lt;p&gt;You may argue those are reasons to implement a proxy, not reasons to run it on a serverless platform, and you may be right. However, an API proxy is by definition a piece of our architecture that needs to be very elastic. It takes the first hit behind a user click so it needs to be ready to scale as the number of users grows. Good news: &lt;strong&gt;serverless scales horizontally by design&lt;/strong&gt;, we won't need to know anything about Docker or Kubernetes to scale and fit with the traffic.&lt;/p&gt;

&lt;p&gt;Now, let's see how we can implement that API proxy. To this end, I could use any serverless platform, such as &lt;a href="https://aws.amazon.com/fr/lambda/" rel="noopener noreferrer"&gt;AWS Lambda&lt;/a&gt; or &lt;a href="https://cloud.google.com/functions/" rel="noopener noreferrer"&gt;Google Functions&lt;/a&gt;. However, I recently joined the company powering &lt;a href="https://scaledynamics.io/warpjs" rel="noopener noreferrer"&gt;WarpJS serverless&lt;/a&gt; and I have to admit that their stack, built on top of the cloud providers, saves many steps like the serverless function declarations, the endpoint management or the deployment to a public URL. This JavaScript serverless platform is kind of all-in-one: front end and back end are deployed at once.&lt;/p&gt;

&lt;p&gt;Let's get to it now!&lt;/p&gt;

&lt;h2&gt;
  
  
  Steps to turn a native JavaScript function into a serverless function
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Linux, macOS or Windows&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://nodejs.org/" rel="noopener noreferrer"&gt;Node.js&lt;/a&gt; &amp;gt;= 8&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git-scm.com/downloads" rel="noopener noreferrer"&gt;Git&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;A &lt;a href="https://github.com/join?source=header-home" rel="noopener noreferrer"&gt;GitHub account&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Stack
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Vue.js&lt;/li&gt;
&lt;li&gt;Axios&lt;/li&gt;
&lt;li&gt;WarpJS serverless&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Together, we will go through the different steps of initializing our GitHub Search project, walk through the specific GitHub+NPM search feature we want, and see how to turn a pure JavaScript function - here the search function - into a serverless function that will behave as an HTTP proxy. We will run everything on our local computer before deploying both front end and back end on a cloud platform with a command-line to get a live URL.&lt;/p&gt;

&lt;p&gt;We have developed a small Vue.js application to list the repositories matching a certain keyword. Here is what it looks like:&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%2F2dubu48z1h0aditylmjb.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%2F2dubu48z1h0aditylmjb.png" alt="a serverless app to search for JS+TS projects on GitHub displaying" width="800" height="426"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can download this project using the following command-line&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git clone https://github.com/WarpJS/github-repo-search.git 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...and set up our project&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;github-repo-search
&lt;span class="nv"&gt;$ &lt;/span&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While it's downloading, let's have a look under the hood. If you have any trouble with node-gyp after install, see the official &lt;a href="https://github.com/nodejs/node-gyp#installation" rel="noopener noreferrer"&gt;"node-gyp" installation doc&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  The back-end serverless function
&lt;/h3&gt;

&lt;p&gt;First, the back end. The script api/index.js contains only the server-side logic, No HTTP, no endpoint, no argument control, no serialization: only the function "juice".&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;/**
* Search repositories
*
* @param {string} query
* @param {number} page
*/&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;search&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;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&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="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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;search&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The "search" function needs to be exported to tell WarpJS it needs to be exposed as a serverless function. After deployment, such functions will run on Node.js on your preferred serverless platform, such as AWS Lambda, Google functions, or others as long as &lt;a href="https://scaledynamics.io/warpjs" rel="noopener noreferrer"&gt;WarpJS serverless&lt;/a&gt; supports it.&lt;/p&gt;

&lt;h3&gt;
  
  
  The helper module to call the serverless function
&lt;/h3&gt;

&lt;p&gt;Next, we need a way to tie our front end to our soon-to-be-deployed serverless function. This is the job of WarpJS. To do this, we first need to create a WarpJS account, as the builder also deals with cloud serverless FaaS providers: that’s why you need a cloud account (this step also prevents you from creating an AWS or a GCP account).&lt;/p&gt;

&lt;p&gt;If you don’t already have one, you request &lt;a href="https://scaledynamics.io/warpjs" rel="noopener noreferrer"&gt;a WarpJS serverless account&lt;/a&gt;. As I write these lines, WarpJS is in private beta, so I just gave you my personal invitation link. Please make good use of it ;) Then you just need to log in to WarpJS within your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;npx warp login
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It saves your credentials to a local file so you only need to do this once for all your projects.&lt;/p&gt;

&lt;p&gt;The following command-line &lt;a href="https://github.com/WarpJS/github-repo-search/blob/master/package.json#L7" rel="noopener noreferrer"&gt;calls "npx warp build"&lt;/a&gt;, which creates a JavaScript helper module for the client (a "stub") according to the configuration set in the &lt;a href="https://github.com/WarpJS/github-repo-search/blob/master/api/warp.config.js" rel="noopener noreferrer"&gt;api/warp.config.js&lt;/a&gt;. Here, we generate it as an npm module in the parent project, but we could output it as a JavaScript file as well, and import it with a  tag, as &amp;lt;a href="https://warpjs.dev/docs/api/cli#output-formats"&amp;gt;detailed in the doc&amp;lt;/a&amp;gt;.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;Run this command-line to generate a serverless adapter as a module in our client project:&amp;lt;br&amp;gt;
&amp;lt;/p&amp;gt;
&amp;lt;div class="highlight"&amp;gt;&amp;lt;pre class="highlight shell"&amp;gt;&amp;lt;code&amp;gt;&amp;lt;span class="nv"&amp;gt;$ &amp;lt;/span&amp;gt;npm run build
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;This is replacing the HTTP layer. We don’t need to refer to an API doc nor to code any HTTP request. Our client file is now ready to be imported into any JavaScript project.&amp;lt;/p&amp;gt;
&amp;lt;h3&amp;gt;
  &amp;lt;a name="the-front-end" href="#the-front-end" class="anchor"&amp;gt;
  &amp;lt;/a&amp;gt;
  The Front end
&amp;lt;/h3&amp;gt;

&amp;lt;p&amp;gt;The front end is a classic &amp;lt;a href="https://vuejs.org/"&amp;gt;Vue.js&amp;lt;/a&amp;gt; single page app with a search box followed by a list when the results come. We would find details about the front-end app in the app.vue file. We import the &amp;amp;quot;github-repo-search-api&amp;amp;quot; module, a &amp;amp;quot;stub&amp;amp;quot; to call our serverless function.&amp;lt;br&amp;gt;
&amp;lt;/p&amp;gt;
&amp;lt;div class="highlight"&amp;gt;&amp;lt;pre class="highlight javascript"&amp;gt;&amp;lt;code&amp;gt;&amp;lt;span class="c1"&amp;gt;// init WarpJS&amp;lt;/span&amp;gt;
&amp;lt;span class="k"&amp;gt;import&amp;lt;/span&amp;gt; &amp;lt;span class="nx"&amp;gt;Warp&amp;lt;/span&amp;gt; &amp;lt;span class="k"&amp;gt;from&amp;lt;/span&amp;gt; &amp;lt;span class="dl"&amp;gt;'&amp;lt;/span&amp;gt;&amp;lt;span class="s1"&amp;gt;github-repo-search-api&amp;lt;/span&amp;gt;&amp;lt;span class="dl"&amp;gt;'&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;;&amp;lt;/span&amp;gt;
&amp;lt;span class="kd"&amp;gt;const&amp;lt;/span&amp;gt; &amp;lt;span class="nx"&amp;gt;api&amp;lt;/span&amp;gt; &amp;lt;span class="o"&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class="k"&amp;gt;new&amp;lt;/span&amp;gt; &amp;lt;span class="nc"&amp;gt;Warp&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;();&amp;lt;/span&amp;gt;
&amp;lt;span class="p"&amp;gt;...&amp;lt;/span&amp;gt;
&amp;lt;span class="c1"&amp;gt;// fetch api with warp&amp;lt;/span&amp;gt;
&amp;lt;span class="kd"&amp;gt;const&amp;lt;/span&amp;gt; &amp;lt;span class="p"&amp;gt;{&amp;lt;/span&amp;gt; &amp;lt;span class="nx"&amp;gt;repositories&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;,&amp;lt;/span&amp;gt; &amp;lt;span class="nx"&amp;gt;total&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;,&amp;lt;/span&amp;gt; &amp;lt;span class="nx"&amp;gt;error&amp;lt;/span&amp;gt; &amp;lt;span class="p"&amp;gt;}&amp;lt;/span&amp;gt; &amp;lt;span class="o"&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class="k"&amp;gt;await&amp;lt;/span&amp;gt; &amp;lt;span class="nx"&amp;gt;api&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class="nf"&amp;gt;search&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class="k"&amp;gt;this&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class="nx"&amp;gt;search&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;);&amp;lt;/span&amp;gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;The &amp;amp;quot;api&amp;amp;quot; object, an instance of Warp, is our FaaS adapter - our helper module - to call our serverless function. This way it is super easy to call any back-end function with no HTTP headache, no endpoint codification, no argument serialization, and no response deserialization.&amp;lt;/p&amp;gt;
&amp;lt;h2&amp;gt;
  &amp;lt;a name="how-to-run-a-serverless-function-on-a-local-environment" href="#how-to-run-a-serverless-function-on-a-local-environment" class="anchor"&amp;gt;
  &amp;lt;/a&amp;gt;
  How to run a serverless function on a local environment
&amp;lt;/h2&amp;gt;

&amp;lt;p&amp;gt;Before we can run this code, we first need to generate an access token for GitHub&amp;lt;/p&amp;gt;
&amp;lt;h3&amp;gt;
  &amp;lt;a name="generate-a-github-access-token" href="#generate-a-github-access-token" class="anchor"&amp;gt;
  &amp;lt;/a&amp;gt;
  Generate a GitHub access token
&amp;lt;/h3&amp;gt;

&amp;lt;p&amp;gt;We need to authenticate to generate a GitHub access token that will be used in our application.&amp;lt;/p&amp;gt;

&amp;lt;ul&amp;gt;
&amp;lt;li&amp;gt;Navigate to GitHub to &amp;lt;a href="https://github.com/settings/tokens/new"&amp;gt;generate a new access token&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;Give it a name&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;Only check the &amp;amp;quot;public_repo&amp;amp;quot; scope (this is all we need in our example)&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;Generate Token&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;Get back to the api/index.js and replace YOUR_API_TOKEN with yours.
&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;
&amp;lt;div class="highlight"&amp;gt;&amp;lt;pre class="highlight javascript"&amp;gt;&amp;lt;code&amp;gt;&amp;lt;span class="c1"&amp;gt;// ./src/api.js&amp;lt;/span&amp;gt;

&amp;lt;span class="c1"&amp;gt;// GitHub auth token&amp;lt;/span&amp;gt;
&amp;lt;span class="kd"&amp;gt;const&amp;lt;/span&amp;gt; &amp;lt;span class="nx"&amp;gt;GITHUB_ACCESS_TOKEN&amp;lt;/span&amp;gt; &amp;lt;span class="o"&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class="dl"&amp;gt;'&amp;lt;/span&amp;gt;&amp;lt;span class="s1"&amp;gt;YOUR_API_TOKEN&amp;lt;/span&amp;gt;&amp;lt;span class="dl"&amp;gt;'&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;;&amp;lt;/span&amp;gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;h3&amp;gt;
  &amp;lt;a name="local-run" href="#local-run" class="anchor"&amp;gt;
  &amp;lt;/a&amp;gt;
  Local Run
&amp;lt;/h3&amp;gt;

&amp;lt;p&amp;gt;We&amp;amp;#39;re all set, let&amp;amp;#39;s now test locally. We open a terminal in the project folder and run&amp;lt;br&amp;gt;
&amp;lt;/p&amp;gt;
&amp;lt;div class="highlight"&amp;gt;&amp;lt;pre class="highlight shell"&amp;gt;&amp;lt;code&amp;gt;&amp;lt;span class="nv"&amp;gt;$ &amp;lt;/span&amp;gt;npm run dev
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;This opens our app in a new browser&amp;amp;#39;s tab. We can take a minute to play with it...&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;At any time, we can change the code and save, the session refreshes the browser, so we don&amp;amp;#39;t have to relaunch our local server thanks to a live reload feature. Actually, in development mode, the &amp;lt;a href="https://warpjs.dev/docs/api/cli#start-emulator"&amp;gt;WarpJS serverless emulator&amp;lt;/a&amp;gt; dynamically injects the functions in the server to prevent it from rebuilding and restarting. This saves us a lot of time on the development/debugging phase. Feel free to make any changes you wish to customize our little app.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;The local run is cool to test, but let&amp;amp;#39;s deploy now.&amp;lt;/p&amp;gt;
&amp;lt;h2&amp;gt;
  &amp;lt;a name="how-to-run-a-proxy-in-a-serverless-environment" href="#how-to-run-a-proxy-in-a-serverless-environment" class="anchor"&amp;gt;
  &amp;lt;/a&amp;gt;
  How to run a proxy in a serverless environment
&amp;lt;/h2&amp;gt;

&amp;lt;p&amp;gt;All we need now is to build our project, front and back ends:&amp;lt;br&amp;gt;
&amp;lt;/p&amp;gt;
&amp;lt;div class="highlight"&amp;gt;&amp;lt;pre class="highlight shell"&amp;gt;&amp;lt;code&amp;gt;&amp;lt;span class="nv"&amp;gt;$ &amp;lt;/span&amp;gt;npm run build
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;... and then, the awesome command-line to deploy it all at once 🤓&amp;lt;br&amp;gt;
&amp;lt;/p&amp;gt;
&amp;lt;div class="highlight"&amp;gt;&amp;lt;pre class="highlight shell"&amp;gt;&amp;lt;code&amp;gt;&amp;lt;span class="nv"&amp;gt;$ &amp;lt;/span&amp;gt;npm run deploy
&amp;lt;span class="o"&amp;gt;&amp;amp;gt;&amp;lt;/span&amp;gt; github-repo-search@1.0.0 deploy /Users/dom/src/github-repo-search
&amp;lt;span class="o"&amp;gt;&amp;amp;gt;&amp;lt;/span&amp;gt; warp-deploy &amp;lt;span class="nt"&amp;gt;--asset-dir&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;=&amp;lt;/span&amp;gt;dist &amp;lt;span class="nb"&amp;gt;.&amp;lt;/span&amp;gt;

Deploying..............................
Deployed project &amp;lt;span class="s1"&amp;gt;'github-repo-search'&amp;lt;/span&amp;gt; at:
https://warpjs-xxxxxxxxxxxxxx.storage.googleapis.com/index.html
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;And it&amp;amp;#39;s done! Our web app is now live on a public URL. We can copy/paste the last line in our favorite browser and share it with coworkers or friends.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;As we can see in the URL, it&amp;amp;#39;s deployed on GCP. WarpJS runs above the cloud providers, so we can run it where we need to.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;Regarding the cloud credits, the beta version does limit usage with a strict limit, just &amp;amp;quot;fair use&amp;amp;quot;. Whatever, it&amp;amp;#39;s all free for now 🤑&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;If you want to get inspiration to develop some other kind of serverless app, we have a bunch of serverless &amp;lt;a href="https://github.com/WarpJS/samples"&amp;gt;code samples&amp;lt;/a&amp;gt; to deal with authentication, storage, and even in-browser Machine Learning...&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;As I write this article, WarpJS is still in the beta stage but the platform will soon offer options to:&amp;lt;/p&amp;gt;

&amp;lt;ul&amp;gt;
&amp;lt;li&amp;gt;deploy on a customized domain name (removing the banner by the way)&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;deploy on multiple clouds for the same function such as AWS Lambda and Azure function serverless platforms,&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;deploy on-premise or on hybrid cloud.&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;

&amp;lt;p&amp;gt;Those are probably topics for a next post 😁&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;I hope you enjoyed this reading, learned, had fun, and you now like serverless as much as I do. Feel free to comment on this article to let me know what you think or to share your experience.&amp;lt;/p&amp;gt;
&amp;lt;h4&amp;gt;
  &amp;lt;a name="credits" href="#credits" class="anchor"&amp;gt;
  &amp;lt;/a&amp;gt;
  Credits
&amp;lt;/h4&amp;gt;

&amp;lt;p&amp;gt;Big thanks to &amp;lt;a href="https://twitter.com/NicoPennec"&amp;gt;Nicolas Pennec&amp;lt;/a&amp;gt; who developed the app we took as an example. He is a JavaScript Expert in ScaleDynamics. He co-organizes RennesJS, a French JavaScript Meetup, so if you come by Brittany you&amp;amp;#39;re more than welcome to join us!&amp;lt;/p&amp;gt;
&lt;/p&gt;

</description>
      <category>serverless</category>
      <category>proxy</category>
      <category>javascript</category>
      <category>node</category>
    </item>
  </channel>
</rss>
