<?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: Knut Martin Tornes</title>
    <description>The latest articles on DEV Community by Knut Martin Tornes (@canuto).</description>
    <link>https://dev.to/canuto</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%2F978929%2F975c0870-2239-4500-948a-d438e177c8e4.jpeg</url>
      <title>DEV Community: Knut Martin Tornes</title>
      <link>https://dev.to/canuto</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/canuto"/>
    <language>en</language>
    <item>
      <title>How to use ChatGPT to make an instantly deployable Node.js REST API backend</title>
      <dc:creator>Knut Martin Tornes</dc:creator>
      <pubDate>Sat, 14 Jan 2023 20:11:34 +0000</pubDate>
      <link>https://dev.to/canuto/how-to-use-chatgpt-to-make-an-instantly-deployable-nodejs-rest-api-backend-2j6n</link>
      <guid>https://dev.to/canuto/how-to-use-chatgpt-to-make-an-instantly-deployable-nodejs-rest-api-backend-2j6n</guid>
      <description>&lt;p&gt;&lt;a href="https://openai.com/blog/chatgpt/" rel="noopener noreferrer"&gt;ChatGPT&lt;/a&gt;, a variant of the popular GPT-3 language model, is revolutionizing the way we produce text and programming code. &lt;/p&gt;

&lt;p&gt;In this blog post, we will demonstrate how ChatGPT can be used to produce high-quality, easy-to-understand, and instantly deployable Node.js backend code using examples from &lt;a href="https://codehooks.io" rel="noopener noreferrer"&gt;codehooks.io&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;By the end of this post, you will have a powerful tool to quickly prototype and build various types of backends with minimal effort. Let's dive in and see how ChatGPT can enhance your development process!&lt;/p&gt;

&lt;p&gt;A variant of this blogpost was originally published on the &lt;a href="https://codehooks.io/blog" rel="noopener noreferrer"&gt;codehooks.io blog&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Making a database-powered CRUD REST API with ChatGPT
&lt;/h2&gt;

&lt;p&gt;We thought that ChatGPT could be a good match for creating code for codehooks.io due to codehooks' serverless and "instant deploy without setup" capability along with its built-in database, jobs and worker queue features. &lt;/p&gt;

&lt;p&gt;One problem we figured out we might have was due to the fact that codehooks.io was released in late 2022 and ChatGPT has only been trained on data up to 2021. However, after experimenting a bit, we figured out a way to ask ChatGPT by providing an example instantly.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to ask ChatGPT for help with coding
&lt;/h3&gt;

&lt;p&gt;If you haven't &lt;a href="https://chat.openai.com/auth/login" rel="noopener noreferrer"&gt;signed up for ChatGPT&lt;/a&gt; yet, you must do so before you can talk to it. To create our question for creating a CRUD REST API for deployment with codehooks.io using the &lt;a href="https://www.npmjs.com/package/codehooks-crudlify-yup" rel="noopener noreferrer"&gt;codehooks-crudlify-yup&lt;/a&gt; NPM package, we copied the following code from one of our &lt;a href="https://codehooks.io/blog/how-to-quickly-create-a-crud-rest-api-backend-using-codehooks-io-with-code-example#a-minimal-crud-api-code-example" rel="noopener noreferrer"&gt;blog posts&lt;/a&gt;:&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;/*
* Minimal CRUD API code example using Yup schema
*/&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;app&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;codehooks-js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;crudlify&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;codehooks-crudlify-yup&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&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;yup&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;yup&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// "product" schema allowing any json object&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;product&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;yup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;shape&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;json&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;yup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mixed&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="c1"&gt;// Add CRUD routes with yup schema for two collections&lt;/span&gt;
&lt;span class="nf"&gt;crudlify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="c1"&gt;// bind to serverless runtime&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;💡 &lt;em&gt;Create database-backed REST APIs fast with crudlify&lt;/em&gt; ⚡️&lt;br&gt;
When you need a "standard" REST API with NoSQL database support, using the library 'codehooks-crudlify-yup' must be one of the simplest ways to do it with code. The library generates the common REST API routes: GET, POST, PUT, PATCH and DELETE and persists the data in the codehooks.io NoSQL database. You can also query the data quite easily.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Then we added the following text before this code: "This is an example of codehooks.io backend code:", and we added this after the code: " Can you create a codehooks.io backend like this with a more complete example for an online shop."&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%2Fcfjrewakzsb7vdif9wp1.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%2Fcfjrewakzsb7vdif9wp1.png" alt="The question we asked ChatGPT" width="737" height="460"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And voilá! This is the code we got back from ChatGPT:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;app&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;codehooks-js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;crudlify&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;codehooks-crudlify-yup&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&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;yup&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;yup&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Define the schema for the "Product" collection&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;productSchema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;yup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;shape&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="nx"&gt;yup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;required&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;yup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="na"&gt;price&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;yup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;number&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;required&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;yup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;url&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="na"&gt;category&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;yup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;required&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="na"&gt;ratings&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;yup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;array&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="nx"&gt;yup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;number&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Define the schema for the "Order" collection&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;orderSchema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;yup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;shape&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;customerName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;yup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;required&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="na"&gt;customerEmail&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;yup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;email&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;required&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="na"&gt;products&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;yup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;array&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="nx"&gt;yup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;shape&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;productId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;yup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;required&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="na"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;yup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;number&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;required&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;})),&lt;/span&gt;
    &lt;span class="na"&gt;total&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;yup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;number&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;required&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;yup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;oneOf&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pending&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;shipped&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;delivered&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="c1"&gt;// Add CRUD routes for the "Product" and "Order" collections with the corresponding schemas&lt;/span&gt;
&lt;span class="nf"&gt;crudlify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;products&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;productSchema&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;orders&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;orderSchema&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Bind the app to the serverless runtime&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This was the explanation ChatGPT helpfully provided:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This code creates two collections for Product and Order, defined by the productSchema and orderSchema respectively. The schema of product includes name, description, price, image, category and ratings. The schema of order includes customerName, customerEmail, products, total, status.It also demonstrates the use of different validation techniques like required, email, url and oneOf() for various fields in the collection.&lt;br&gt;
It can be more fine-tuned based on the specific needs of the backend.&lt;br&gt;
Please note that this is just an example to give you an idea of how you can define your collections and schemas, and you may need to adjust it to fit the specific requirements of your application.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Deploying the AI-generated Node.js JavaScript code directly without touching it 💥🤖
&lt;/h3&gt;

&lt;p&gt;This code certainly looks correct at first glance. I have, however, several times caught ChatGPT "inventing" totally new libraries and methods and got an excuse afterwards when I pinpointed it 😂&lt;/p&gt;

&lt;p&gt;Let's deploy the code! If you want to do this yourself, follow the instructions in our &lt;a href="https://codehooks.io/docs" rel="noopener noreferrer"&gt;Quick Start&lt;/a&gt; to get ready. It only takes a few seconds.&lt;/p&gt;

&lt;p&gt;First, create a new project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;codehooks create shopbackend
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This &lt;a href="https://codehooks.io/docs/cli" rel="noopener noreferrer"&gt;CLI command&lt;/a&gt; creates a codehooks project, adds a folder named "shopbackend" and initializes a "hello world" index.js JavaScript file.&lt;/p&gt;

&lt;p&gt;Replace the contents of the "index.js" file with ChatGPTs generated code above and save it.&lt;/p&gt;

&lt;p&gt;You also need to install the necessary npm packages:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;In the same folder as index.js, run the deploy command:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Project: shopbackend-h3r5  Space: dev
Deployed Codehook successfully! 🙌 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Yes! 🙌 &lt;/p&gt;

&lt;p&gt;It worked...or rather it compiled and was deployed correctly by codehooks.io.&lt;/p&gt;

&lt;p&gt;Let's test the backend by adding some products using cURL (we also recommend &lt;a href="https://postman.com" rel="noopener noreferrer"&gt;Postman&lt;/a&gt;).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Postman Import button&lt;/strong&gt;&lt;br&gt;
Using the "Import" button in Postman, you can directly import cURL commands and then use it to test your API endpoints.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This 'info' command is very useful when we need more information about our space AND need some cURL examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;codehooks info &lt;span class="nt"&gt;--examples&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is what we get:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Project name: shopbackend-h3r5
Team: Martin Tornes &lt;span class="o"&gt;(&lt;/span&gt;personal account&lt;span class="o"&gt;)&lt;/span&gt;

API endpoint:  https://shopbackend-h3r5.api.codehooks.io/dev

Examples &lt;span class="k"&gt;in &lt;/span&gt;cURL:

curl https://shopbackend-h3r5.api.codehooks.io/dev/myroute &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'x-apikey: 27b3822e-ecf3-4263-bcee-24acd6aed2d0'&lt;/span&gt; &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt;

curl &lt;span class="nt"&gt;--request&lt;/span&gt; POST https://shopbackend-h3r5.api.codehooks.io/dev/myroute &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'x-apikey: 27b3822e-ecf3-4263-bcee-24acd6aed2d0'&lt;/span&gt; &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt; &lt;span class="nt"&gt;--data-raw&lt;/span&gt; &lt;span class="s1"&gt;'{"name": "Mr. Code Hooks", "active": true }'&lt;/span&gt;

Spaces:
┌──────────────┬────────────────────────────────────────────┬───────────────┬──────┬──────┐
│ Name         │  Tokens                                    │ Allowed Hosts │ Jwks │  Env │
├──────────────┼────────────────────────────────────────────┼───────────────┼──────┼──────┤
│ dev &lt;span class="o"&gt;(&lt;/span&gt;active&lt;span class="o"&gt;)&lt;/span&gt; │ 27b3822e-ecf3-4263-bcee-24acd6aed2d0 &lt;span class="o"&gt;(&lt;/span&gt;RW&lt;span class="o"&gt;)&lt;/span&gt;  │               │      │      │
└──────────────┴────────────────────────────────────────────┴───────────────┴──────┴──────┘

Project members:
┌────────────────────┬──────────────────────────────────┬───────┐
│ name               │ email                            │ role  │
├────────────────────┼──────────────────────────────────┼───────┤
│ Martin Tornes      │ martintornesdev@gmail.com        │ ADMIN │
└────────────────────┴──────────────────────────────────┴───────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's modify the POST cUrl to add some product data. We'll add a JSON structure with at least the fields ChatGPT marked as required:&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;--request&lt;/span&gt; POST https://shopbackend-h3r5.api.codehooks.io/dev/products &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'x-apikey: 27b3822e-ecf3-4263-bcee-24acd6aed2d0'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--data-raw&lt;/span&gt; &lt;span class="s1"&gt;'{"name": "Codehook", "price": 0, "category": "TOOLS" }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Result:&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="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"name"&lt;/span&gt;:&lt;span class="s2"&gt;"Codehook"&lt;/span&gt;,&lt;span class="s2"&gt;"price"&lt;/span&gt;:0,&lt;span class="s2"&gt;"category"&lt;/span&gt;:&lt;span class="s2"&gt;"TOOLS"&lt;/span&gt;,&lt;span class="s2"&gt;"_id"&lt;/span&gt;:&lt;span class="s2"&gt;"185a3157a34-u96ow26u9zcxd0"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It worked! You can now use your preferred programming language and library to interact with this REST API and database. &lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;codehooks.io is a good fit for getting a lot of help from ChatGPT, you just need to show it an example before you ask a question. The way we demonstrated it here works fine, but there are probably multiple ways to get the most out of it. &lt;/p&gt;

&lt;p&gt;We also asked it to create a scheduled "CRON" job using codehooks.io job "hooks", which should Tweet each afternoon at 5pm. It produced working code using Twitter's library and the correct codehooks.io JavaScript code. Ready to deploy!&lt;/p&gt;

&lt;p&gt;We could have asked it to do more to elaborate on the code it created. This type of dialog is in fact the recommended way to work with it to produce the best results. We'll leave that to a later blogpost or a whole dedicated section where we add ChatGPT examples.&lt;/p&gt;

&lt;p&gt;ChatGPT is a glimpse into an exciting future of AI-assisted programming. It's not exactly NoCode, but it surely is automated and saves a ton of time. &lt;/p&gt;

&lt;p&gt;Disclaimer... Some parts of this blog post was written with help from ChatGPT 😉&lt;/p&gt;

</description>
      <category>webcomponents</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Simple serverless GraphQL using codehooks.io</title>
      <dc:creator>Knut Martin Tornes</dc:creator>
      <pubDate>Thu, 05 Jan 2023 11:53:24 +0000</pubDate>
      <link>https://dev.to/canuto/simple-serverless-graphql-using-codehooksio-360o</link>
      <guid>https://dev.to/canuto/simple-serverless-graphql-using-codehooksio-360o</guid>
      <description>&lt;p&gt;Codehooks.io is an easy to use serverless backend tool for Node.js. In this very short blog post, we'll show you how to create a really simple GraphQL-powered persistent backend using a little JavaScript and codehooks.io's built-in NoSQL database.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can use &lt;a href="https://postman.com"&gt;Postman&lt;/a&gt; to test the API. Postman automatically fetches the GraphQL schema and gives you auto-completion 🤠&lt;/li&gt;
&lt;li&gt;Data is persisted in the NoSQL document database.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Visit &lt;a href="https://www.graphql.com/"&gt;the official GraphQL site&lt;/a&gt; to learn more about GraphQL.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The following steps assume you have a codehooks.io account and the &lt;a href="https://www.npmjs.com/package/codehooks"&gt;CLI&lt;/a&gt; installed. You can install it with: &lt;code&gt;npm install codehooks -g&lt;/code&gt;. Codehooks.io is free to use up to a limit of 5000 API calls and 5000 data objects. &lt;/p&gt;

&lt;p&gt;Here we go:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a project with the &lt;code&gt;coho create&lt;/code&gt; CLI command. &lt;/li&gt;
&lt;li&gt;Change to the project directory and install using  &lt;code&gt;npm i codehooks-js graphql graphql-tools&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Open the index.js file in your favorite code editor and enter the following code. &lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Main file (index.js)
&lt;/h2&gt;

&lt;p&gt;The index.js file defines the schema, the resolvers and the single GraphQL route we need.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Datastore&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="s1"&gt;codehooks-js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;graphql&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="s1"&gt;graphql&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;makeExecutableSchema&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="s1"&gt;graphql-tools&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Construct a schema, using GraphQL schema language&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;typeDefs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`
  type Member {
    id: ID
    name: String!
    age: Int
    active: Boolean
  }
  type Query {
    ping: String
    member(id: ID!): Member!
    allMembers: [Member]
  }
  type Mutation {
    addMember(name: String! age:Int active:Boolean): Member!
    updateMember(id: ID! name: String age:Int active:Boolean): Member!
    deleteMember(id: ID!): ID
  }
`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// implement resolvers for queries and mutations&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;resolvers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;Query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;ping&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="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Pong!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;member&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;db&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="kd"&gt;const&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="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;rest&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;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getOne&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;members&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="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;id&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="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;rest&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;allMembers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;db&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;const&lt;/span&gt; &lt;span class="nx"&gt;members&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;getArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;members&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;members&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&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="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;member&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="na"&gt;id&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="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;member&lt;/span&gt; &lt;span class="p"&gt;}));&lt;/span&gt; &lt;span class="c1"&gt;// map _id to id&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;Mutation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;addMember&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;db&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;const&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="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;rest&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;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;insertOne&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;members&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;input&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;id&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="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;rest&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;updateMember&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&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="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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;db&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;return&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;updateOne&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;members&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="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="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;deleteMember&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;db&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;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;removeOne&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;members&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;result&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="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;const&lt;/span&gt; &lt;span class="nx"&gt;schema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;makeExecutableSchema&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;typeDefs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;resolvers&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="c1"&gt;// Create the default graphql POST route&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/graphql&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&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="o"&gt;=&amp;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;conn&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;Datastore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;open&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;response&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;graphql&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="nx"&gt;schema&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&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="na"&gt;contextValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;db&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;conn&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;init&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Bind functions to the serverless cloud&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Deployment
&lt;/h2&gt;

&lt;p&gt;Codehooks.io JavaScript code is easy to deploy. Just change directory to your development folder and deploy the code with this &lt;a href="https://codehooks.io/docs/cli#deploy"&gt;CLI command&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;coho deploy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Test the deployed GraphQL endpoint
&lt;/h2&gt;

&lt;p&gt;We recommend that you test your deployed code with &lt;a href="https://www.postman.com/graphql"&gt;Postman using GraphQL support&lt;/a&gt; (recommended). Postman reads the schema from the codehooks.io &lt;code&gt;/graphql&lt;/code&gt; endpoint and gives you code completion.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Use the CLI command &lt;code&gt;coho info&lt;/code&gt; to see the HTTP endpoint and the API tokens for the project space.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  You can also use cURL to use the GraphQL API to add and read data
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Add one member mutation&lt;/strong&gt;&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;--location&lt;/span&gt; &lt;span class="nt"&gt;--request&lt;/span&gt; POST &lt;span class="s1"&gt;'https://graphqltest-4pmq.api.codehooks.io/dev/graphql'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s1"&gt;'x-apikey: 66e33428-45d3-4811-be21-58fa6d5d5e91'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--data-raw&lt;/span&gt; &lt;span class="s1"&gt;'{"query":"mutation { addMember(name: \"Mr Codehook\", age: 33) { id name }}"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Get all members query&lt;/strong&gt;&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;--location&lt;/span&gt; &lt;span class="nt"&gt;--request&lt;/span&gt; POST &lt;span class="s1"&gt;'https://graphqltest-4pmq.api.codehooks.io/dev/graphql'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s1"&gt;'x-apikey: 66e33428-45d3-4811-be21-58fa6d5d5e91'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--data-raw&lt;/span&gt; &lt;span class="s1"&gt;'{"query":"{allMembers {id name }}"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Use a local server instead of deploying
&lt;/h2&gt;

&lt;p&gt;If you don't want to create an account yet, you can also test your codehooks.io GraphQL backend locally using this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;coho localserver
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;We've demonstrated how you can set up a simple serverless GraphQL server using very little JavaScript code. We hope this has inspired you to check out what is possible to do with codehooks.io's compact backend and database. &lt;/p&gt;

&lt;p&gt;To learn more about creating backends with Node.js and codehooks.io, check out the &lt;a href="https://codehooks.io/docs"&gt;documentation&lt;/a&gt; or the &lt;a href="https://codehooks.io/blog"&gt;blog&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>serverless</category>
      <category>graphql</category>
      <category>node</category>
    </item>
    <item>
      <title>JAMstack - an introduction</title>
      <dc:creator>Knut Martin Tornes</dc:creator>
      <pubDate>Fri, 16 Dec 2022 21:39:28 +0000</pubDate>
      <link>https://dev.to/canuto/jamstack-an-introduction-74d</link>
      <guid>https://dev.to/canuto/jamstack-an-introduction-74d</guid>
      <description>&lt;p&gt;The JAMstack architecture is gaining popularity among frontend developers for its ability to provide a modern, fast, and secure web development experience.&lt;/p&gt;

&lt;p&gt;In order to achieve better performance, developers have had to look at different ways and tools that together could increase speed and at the same time maintain a high level of security. Traditional and dynamic CMS-based websites have the disadvantage that data must be retrieved from a database or similar in order to deliver content on the websites. Using so-called reverse proxies and caches (i.e., "fast storage") such as Varnish and nginx, was one of the few options to increase performance. That is, until the JAMstack architecture (and frameworks) arrived.&lt;/p&gt;

&lt;p&gt;(You'll also find this article on the &lt;a href="https://codehooks.io/blog"&gt;codehooks.io blog.&lt;/a&gt;)&lt;/p&gt;

&lt;h2&gt;
  
  
  What is JAMstack?
&lt;/h2&gt;

&lt;p&gt;At its core, the JAMstack is a web development approach that focuses on using client-side JavaScript, reusable APIs, and prebuilt Markup to create web applications. This architecture allows for faster and more secure web development by using prebuilt and pre-rendered pages, which are then delivered to the user via a content delivery network (CDN).&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://JAMstack.org"&gt;JAMstack.org&lt;/a&gt; website defines the term as:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Jamstack is an architectural approach that decouples the web experience layer from data and business logic, improving flexibility, scalability, performance, and maintainability. JAMstack removes the need for business logic to dictate the web experience. It enables a composable architecture for the web where custom logic and 3rd party services are consumed through APIs."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;JAMstack, as an architectural concept, was created by Mathias Biilmann Christensen, co-founder of Netlify - a rapidly growing Cloud Computing company offering hosting and serverless backend services for static websites. It can be used to build static websites that are significantly faster and more stable than dynamic ones, but are still dynamic in the sense that the web pages are updated when new content is published or the source code changes. JAMstack is thus not a specific tool, but an architecture and ecosystem that makes it efficient to create lightning-fast websites.&lt;/p&gt;

&lt;h2&gt;
  
  
  What does JAMstack mean?
&lt;/h2&gt;

&lt;p&gt;JAM stands for "Javascript", "APIs" and "Markup":&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Javascript&lt;/strong&gt; handles all parts of the website that should be dynamic once the web pages are first loaded. Modern front-end frameworks such as VueJS, React or Angular are well suited to use for this.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;APIs&lt;/strong&gt; are required because a JAMstack app/website does not have a server. This means that no self-developed "backend" code is necessarily needed in this architecture. Developers can focus on implementing front-end logic. If you need to store user input, process images, authenticate users, perform content search, transform images, handle payment and the like, this can be handled with external services via standardized or custom APIs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Markup&lt;/strong&gt; is the HTML code that is generated in the build step. This code is pure static HTML, but it can be dynamic in the sense that the HTML is built from data retrieved from APIs combined with HTML templates. In many frameworks, Javascript (React, Vue) can also be used to create this static part. So-called headless CMS APIs are often used for the dynamic content. In such a setup, the construction of markup will be initiated when the source code is checked into version control (such as Github) or by web hooks triggered when the CMS API receives new or updated content.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the illustration of the JAMstack architecture below, we see that the combination of templates and content is compiled into static HTML pages/content which is then distributed to a Content Network (CDN). The CDN helps ensure that the pages are loaded fast and as close to the user as possible.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JQgP7iTU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://codehooks.io/assets/images/jamstack-architecture-codehooks-4120383b8527d6111e6d535f8d25515c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JQgP7iTU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://codehooks.io/assets/images/jamstack-architecture-codehooks-4120383b8527d6111e6d535f8d25515c.png" alt="JAMStack architecture" width="880" height="442"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why should you start using JAMstack?
&lt;/h2&gt;

&lt;p&gt;JAMstack is a modern and efficient way to develop websites. Compared to centralized, database-dependent websites, JAMstack-based websites have the following advantages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Speed - Pages load lightning fast&lt;/li&gt;
&lt;li&gt;Lower cost - static websites are much cheaper compared to dedicated servers/databases&lt;/li&gt;
&lt;li&gt;Scalability - content is static and not loaded from a central server&lt;/li&gt;
&lt;li&gt;Maintenance - there is no need to monitor any servers&lt;/li&gt;
&lt;li&gt;Security - there are no secrets on a static website - only access to APIs needs to be secured&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  SEO - Google favors JAM
&lt;/h2&gt;

&lt;p&gt;From an SEO perspective, there are few reasons to use anything other than JAMstack for content-rich sites. Google favors websites that load quickly and users don't click the "back button" to the same extent. From the developer's point of view, JAMstack will provide a better experience as they can focus on developing the best user experience, use the latest technology and worry less about performance and scalability.&lt;/p&gt;

&lt;h2&gt;
  
  
  Developers love it
&lt;/h2&gt;

&lt;p&gt;One of the key benefits of the JAMstack for frontend developers is the ability to focus on building user interfaces without the need for server-side rendering or complex backend logic. This allows for a more agile and efficient development process, as well as the ability to leverage a wide range of third-party APIs and services to build dynamic and engaging user experiences. They can use their favorite UI frameworks (Like React, Vue, Svelte). If there is a need for a custom backend API (other than a headless CMS), there are plenty of tools which makes this relatively simple like for example &lt;a href="https://heroku.com"&gt;Heroku&lt;/a&gt;, &lt;a href="https://firebase.google.com/"&gt;Firebase&lt;/a&gt;, &lt;a href="https://xata.io"&gt;Xata&lt;/a&gt;, &lt;a href="https://restdb.io"&gt;restdb.io&lt;/a&gt; and &lt;a href="https://codehooks.io"&gt;codehooks.io&lt;/a&gt; 😄&lt;/p&gt;

&lt;h2&gt;
  
  
  Popular frameworks
&lt;/h2&gt;

&lt;p&gt;You'll find the most popular generators for JAMstack Sites on the &lt;a href="https://jamstack.org/generators/"&gt;JAMstack website&lt;/a&gt;. These are the top contenders:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://nextjs.org"&gt;Next.js&lt;/a&gt; - very popular in the React community - supports static site generation and server-side-rendered (SSR) dynamic applications.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://gohugo.io"&gt;Hugo&lt;/a&gt; - Insanely fast builds and many features - optimized for speed, ease of use and configurability. Built on the Go programming language.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://gatsbyjs.org"&gt;Gatsby&lt;/a&gt; - React based with a huge ecosystem of content/data plugins - uses GraphQL to provide content/data.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://nuxtjs.org"&gt;Nuxt&lt;/a&gt; - the Vue alternative to NextJS - supports both static site generation and SSR.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docusaurus.io"&gt;Docusaurus&lt;/a&gt; - Use React and Markdown to create powerful static sites for documentation or whatever (this blog uses Docusaurus).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Summary and conclusion
&lt;/h2&gt;

&lt;p&gt;In short, the JAMstack is a powerful and efficient web development architecture that is ideal for frontend developers looking to build modern, fast, and secure web applications. With its focus on client-side JavaScript, reusable APIs, and prebuilt Markup, the JAMstack offers a range of benefits that make it an attractive option for frontend developers looking to create engaging and dynamic user experiences.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>react</category>
      <category>jamstack</category>
    </item>
  </channel>
</rss>
