<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Sqlite on blog.iankulin.com</title><link>https://blog.iankulin.com/tags/sqlite/</link><description>Recent content in Sqlite on blog.iankulin.com</description><generator>Hugo</generator><language>en-AU</language><lastBuildDate>Thu, 28 Dec 2023 00:00:00 +0000</lastBuildDate><atom:link href="https://blog.iankulin.com/tags/sqlite/index.xml" rel="self" type="application/rss+xml"/><item><title>Simple SQLite in Express</title><link>https://blog.iankulin.com/simple-sqlite-in-express/</link><pubDate>Thu, 28 Dec 2023 00:00:00 +0000</pubDate><guid>https://blog.iankulin.com/simple-sqlite-in-express/</guid><description>&lt;p&gt;I don&amp;rsquo;t have experience with &lt;a href="https://www.sqlite.org/index.html"&gt;SQLite&lt;/a&gt; and want to shift one of my apps over from Mongoose since apparently SQLite is &lt;a href="https://www.sqlite.org/whentouse.html"&gt;much more capable&lt;/a&gt; than I imagined. My usual tactic when trying something new is to try and get a minimal project working on it, so what follows is the simplest possible node/express REST API to demo SQLite.&lt;/p&gt;
&lt;p&gt;The simplest possible Express app is going to look something like this. Of course we would have gone to the terminal with &lt;code&gt;npm i express&lt;/code&gt; first so this could run.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#81a1c1;font-weight:bold"&gt;const&lt;/span&gt; express &lt;span style="color:#81a1c1"&gt;=&lt;/span&gt; require&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;&lt;span style="color:#a3be8c"&gt;&amp;#39;express&amp;#39;&lt;/span&gt;&lt;span style="color:#eceff4"&gt;);&lt;/span&gt;&lt;span style="color:#81a1c1;font-weight:bold"&gt;const&lt;/span&gt; app &lt;span style="color:#81a1c1"&gt;=&lt;/span&gt; express&lt;span style="color:#eceff4"&gt;();&lt;/span&gt;&lt;span style="color:#81a1c1;font-weight:bold"&gt;const&lt;/span&gt; port &lt;span style="color:#81a1c1"&gt;=&lt;/span&gt; &lt;span style="color:#b48ead"&gt;3000&lt;/span&gt;&lt;span style="color:#eceff4"&gt;;&lt;/span&gt;app&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;get&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;&lt;span style="color:#a3be8c"&gt;&amp;#39;/&amp;#39;&lt;/span&gt;&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; &lt;span style="color:#eceff4"&gt;(&lt;/span&gt;req&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; res&lt;span style="color:#eceff4"&gt;)&lt;/span&gt; &lt;span style="color:#81a1c1"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#eceff4"&gt;{&lt;/span&gt; res&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;send&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;&lt;span style="color:#a3be8c"&gt;&amp;#39;Hello, World!&amp;#39;&lt;/span&gt;&lt;span style="color:#eceff4"&gt;);});&lt;/span&gt;app&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;listen&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;port&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; &lt;span style="color:#eceff4"&gt;()&lt;/span&gt; &lt;span style="color:#81a1c1"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#eceff4"&gt;{&lt;/span&gt; console&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;log&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;&lt;span style="color:#bf616a"&gt;`&lt;/span&gt;Server is running at http&lt;span style="color:#eceff4"&gt;:&lt;/span&gt;&lt;span style="color:#81a1c1"&gt;//&lt;/span&gt;localhost&lt;span style="color:#eceff4"&gt;:&lt;/span&gt;&lt;span style="color:#81a1c1"&gt;$&lt;/span&gt;&lt;span style="color:#eceff4"&gt;{&lt;/span&gt;port&lt;span style="color:#eceff4"&gt;}&lt;/span&gt;&lt;span style="color:#bf616a"&gt;`&lt;/span&gt;&lt;span style="color:#eceff4"&gt;);});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The only thing to add to this for the moment is some middleware to allow Express to parse JSON body payloads.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;app.use(express.json());
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="body-v-query"&gt;Body v Query&lt;/h4&gt;
&lt;p&gt;I&amp;rsquo;ll just take you on a short detour here if you&amp;rsquo;re not familiar with HTTP requests. There&amp;rsquo;s a couple of common ways to send some data along with a request. The oldest one is to shove it all in the URL. You will have seen these sorts of things:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;http://localhost:3000/adduser?name=Fred&amp;amp;email=fred@example.com&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;If you want all of your data to fit in a link, these are great. They can be bookmarked and so on. You see them all the time - especially in links with heaps of tracking data. The &amp;lsquo;?&amp;rsquo; denotes it as a query.&lt;/p&gt;
&lt;p&gt;The code to process the GET request above would look like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;app&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;get&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;&lt;span style="color:#a3be8c"&gt;&amp;#39;/adduser&amp;#39;&lt;/span&gt;&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; &lt;span style="color:#eceff4"&gt;(&lt;/span&gt;req&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; res&lt;span style="color:#eceff4"&gt;)&lt;/span&gt; &lt;span style="color:#81a1c1"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#eceff4"&gt;{&lt;/span&gt; &lt;span style="color:#81a1c1;font-weight:bold"&gt;const&lt;/span&gt; name &lt;span style="color:#81a1c1"&gt;=&lt;/span&gt; req&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;query&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;name&lt;span style="color:#eceff4"&gt;;&lt;/span&gt; &lt;span style="color:#81a1c1;font-weight:bold"&gt;const&lt;/span&gt; email &lt;span style="color:#81a1c1"&gt;=&lt;/span&gt; req&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;query&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;email&lt;span style="color:#eceff4"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Note that I&amp;rsquo;ve used a GET request here, when semantically a POST would make more sense. That&amp;rsquo;s because you can only use query strings for GETs.&lt;/p&gt;
&lt;p&gt;Often the data you want to pass is going to be more complex, or you don&amp;rsquo;t want it in the URL for other reasons (for example, you wouldn&amp;rsquo;t want a user to be able to bookmark a record delete request). In that case you use the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Request/body"&gt;body&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You can stuff all sorts of text data in the body. Most times you are going to want JSON. I do for this demo, so that&amp;rsquo;s why I&amp;rsquo;ve added the &lt;code&gt;expresss.json()&lt;/code&gt; middleware - all the hard work will be done for me and I can just do this to access the information that&amp;rsquo;s passed as part of the request:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;app&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;post&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;&lt;span style="color:#a3be8c"&gt;&amp;#39;/users&amp;#39;&lt;/span&gt;&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; &lt;span style="color:#eceff4"&gt;(&lt;/span&gt;req&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; res&lt;span style="color:#eceff4"&gt;)&lt;/span&gt; &lt;span style="color:#81a1c1"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#eceff4"&gt;{&lt;/span&gt; &lt;span style="color:#81a1c1;font-weight:bold"&gt;const&lt;/span&gt; name &lt;span style="color:#81a1c1"&gt;=&lt;/span&gt; req&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;body&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;name&lt;span style="color:#eceff4"&gt;;&lt;/span&gt; &lt;span style="color:#81a1c1;font-weight:bold"&gt;const&lt;/span&gt; email &lt;span style="color:#81a1c1"&gt;=&lt;/span&gt; req&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;body&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;email&lt;span style="color:#eceff4"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="adding-sqlite"&gt;Adding SQLite&lt;/h3&gt;
&lt;p&gt;Once you&amp;rsquo;ve run &lt;code&gt;npm i sqlite3&lt;/code&gt; at the terminal to install the package, at the top of our app somewhere - probably where we&amp;rsquo;re requiring the other packages - we&amp;rsquo;ll need this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#81a1c1;font-weight:bold"&gt;const&lt;/span&gt; sqlite3 &lt;span style="color:#81a1c1"&gt;=&lt;/span&gt; require&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;&lt;span style="color:#a3be8c"&gt;&amp;#39;sqlite3&amp;#39;&lt;/span&gt;&lt;span style="color:#eceff4"&gt;)&lt;/span&gt;&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;verbose&lt;span style="color:#eceff4"&gt;();&lt;/span&gt;&lt;span style="color:#81a1c1;font-weight:bold"&gt;const&lt;/span&gt; db &lt;span style="color:#81a1c1"&gt;=&lt;/span&gt; new sqlite3&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;Database&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;&lt;span style="color:#a3be8c"&gt;&amp;#39;db/test.sqlite&amp;#39;&lt;/span&gt;&lt;span style="color:#eceff4"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is just requiring the package, and giving us &lt;code&gt;db&lt;/code&gt; as the variable for the SQLite database connection. The database is actually a file in the &lt;code&gt;db/&lt;/code&gt; directory.&lt;/p&gt;
&lt;p&gt;On the first run, obviously this will be empty, so somewhere before the listen command, we need to create a table.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;// if the &amp;#39;users&amp;#39; table doesn&amp;#39;t exist, // create it with &amp;#39;name&amp;#39; and &amp;#39;email&amp;#39; columnsdb.run(&amp;#39;CREATE TABLE IF NOT EXISTS users (name TEXT, email TEXT)&amp;#39;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If you&amp;rsquo;ve never encountered SQL before, and was expecting a bunch of methods being passing in structs to do this, this is going to be alarming. But no - in SQL we do things by sending the engine a string. This has created a massive &lt;a href="https://en.wikipedia.org/wiki/SQL_injection"&gt;attack surface&lt;/a&gt;, but it&amp;rsquo;s also a convenient and very readable convention.&lt;/p&gt;
&lt;p&gt;For our simple purposes today, that could be enough infrastructure for SQLite, but because we are good programmers, we&amp;rsquo;ll correctly close the database when the app undergoes an orderly shutdown by adding this before the &lt;code&gt;app.listen&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;// close the database connection when the app is shutting downprocess.on(&amp;#39;SIGINT&amp;#39;, () =&amp;gt; { db.close((err) =&amp;gt; { if (err) { console.error(&amp;#39;Error closing SQLite database:&amp;#39;, err.message); } else { process.exit(0); } });});
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="working-with-sqlite"&gt;Working with SQLite&lt;/h3&gt;
&lt;p&gt;That&amp;rsquo;s the infrastructure out of the way. Now, onto our CRUD (create, read, update, delete) operations to manipulate our stored data. Since this is just a demo, the simplest way to show these is just to have endpoints for each one. To exercise these endpoints you could use the development tools in your browser, but most people will use an API testing tool like Postman, or Insomnia. I much prefer &lt;a href="https://blog.iankulin.com/we-need-to-talk-about-bruno/"&gt;Bruno&lt;/a&gt; for this job, so I&amp;rsquo;ll use that (and suggest you do too, get it &lt;a href="https://www.usebruno.com/"&gt;here&lt;/a&gt;).&lt;/p&gt;
&lt;h4 id="create-add"&gt;Create (add)&lt;/h4&gt;
&lt;p&gt;We already started on that earlier, and explained the concept of passing in data via the &amp;lsquo;body&amp;rsquo; here&amp;rsquo;s the complete thing:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#81a1c1"&gt;//&lt;/span&gt; endpoint to add a user record to the users table&lt;span style="color:#81a1c1"&gt;//&lt;/span&gt; expects a name &lt;span style="color:#81a1c1;font-weight:bold"&gt;and&lt;/span&gt; email &lt;span style="color:#81a1c1;font-weight:bold"&gt;in&lt;/span&gt; the JSON body of the requestapp&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;post&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;&lt;span style="color:#a3be8c"&gt;&amp;#39;/users&amp;#39;&lt;/span&gt;&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; &lt;span style="color:#eceff4"&gt;(&lt;/span&gt;req&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; res&lt;span style="color:#eceff4"&gt;)&lt;/span&gt; &lt;span style="color:#81a1c1"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#eceff4"&gt;{&lt;/span&gt; &lt;span style="color:#81a1c1;font-weight:bold"&gt;const&lt;/span&gt; name &lt;span style="color:#81a1c1"&gt;=&lt;/span&gt; req&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;body&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;name&lt;span style="color:#eceff4"&gt;;&lt;/span&gt; &lt;span style="color:#81a1c1;font-weight:bold"&gt;const&lt;/span&gt; email &lt;span style="color:#81a1c1"&gt;=&lt;/span&gt; req&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;body&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;email&lt;span style="color:#eceff4"&gt;;&lt;/span&gt; &lt;span style="color:#81a1c1;font-weight:bold"&gt;const&lt;/span&gt; sql &lt;span style="color:#81a1c1"&gt;=&lt;/span&gt; &lt;span style="color:#bf616a"&gt;`&lt;/span&gt;INSERT INTO users &lt;span style="color:#eceff4"&gt;(&lt;/span&gt;name&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; email&lt;span style="color:#eceff4"&gt;)&lt;/span&gt; VALUES &lt;span style="color:#eceff4"&gt;(&lt;/span&gt;&lt;span style="color:#a3be8c"&gt;&amp;#34;${name}&amp;#34;&lt;/span&gt;&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; &lt;span style="color:#a3be8c"&gt;&amp;#34;${email}&amp;#34;&lt;/span&gt;&lt;span style="color:#eceff4"&gt;)&lt;/span&gt;&lt;span style="color:#bf616a"&gt;`&lt;/span&gt;&lt;span style="color:#eceff4"&gt;;&lt;/span&gt; db&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;run&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;sql&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; function&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;err&lt;span style="color:#eceff4"&gt;)&lt;/span&gt; &lt;span style="color:#eceff4"&gt;{&lt;/span&gt; &lt;span style="color:#81a1c1;font-weight:bold"&gt;if&lt;/span&gt; &lt;span style="color:#eceff4"&gt;(&lt;/span&gt;err&lt;span style="color:#eceff4"&gt;)&lt;/span&gt; &lt;span style="color:#eceff4"&gt;{&lt;/span&gt; res&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;status&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;&lt;span style="color:#b48ead"&gt;500&lt;/span&gt;&lt;span style="color:#eceff4"&gt;)&lt;/span&gt;&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;send&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;err&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;message&lt;span style="color:#eceff4"&gt;);&lt;/span&gt; &lt;span style="color:#eceff4"&gt;}&lt;/span&gt; &lt;span style="color:#81a1c1;font-weight:bold"&gt;else&lt;/span&gt; &lt;span style="color:#eceff4"&gt;{&lt;/span&gt; res&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;status&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;&lt;span style="color:#b48ead"&gt;201&lt;/span&gt;&lt;span style="color:#eceff4"&gt;)&lt;/span&gt;&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;json&lt;span style="color:#eceff4"&gt;({&lt;/span&gt; rowid&lt;span style="color:#eceff4"&gt;:&lt;/span&gt; this&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;lastID &lt;span style="color:#eceff4"&gt;});&lt;/span&gt; &lt;span style="color:#eceff4"&gt;}&lt;/span&gt; &lt;span style="color:#eceff4"&gt;});});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;So this code processes a request to our server - something like &lt;code&gt;http://localhost:3000/users&lt;/code&gt; and expects the body payload to contain some JSON with a name and email. It could look like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{ &amp;#34;name&amp;#34;: &amp;#34;John Doe&amp;#34;, &amp;#34;email&amp;#34;: &amp;#34;john.doe@example.com&amp;#34;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And when run in Bruno:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://blog.iankulin.com/images/screen-shot-2023-12-16-at-10.24.54-am.png"&gt;&lt;img src="https://blog.iankulin.com/images/screen-shot-2023-12-16-at-10.24.54-am.png" width="1000" alt=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4 id="read"&gt;Read&lt;/h4&gt;
&lt;p&gt;There&amp;rsquo;s a couple of reads we can do, one where all the data is returned, and one where only a specific record is. Let&amp;rsquo;s do the big one first, since we&amp;rsquo;ll use it a lot while we&amp;rsquo;re writing the rest!&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#81a1c1"&gt;//&lt;/span&gt; endpoint to get all users from the users table &lt;span style="color:#81a1c1;font-weight:bold"&gt;in&lt;/span&gt; the databaseapp&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;get&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;&lt;span style="color:#a3be8c"&gt;&amp;#39;/users&amp;#39;&lt;/span&gt;&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; &lt;span style="color:#eceff4"&gt;(&lt;/span&gt;req&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; res&lt;span style="color:#eceff4"&gt;)&lt;/span&gt; &lt;span style="color:#81a1c1"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#eceff4"&gt;{&lt;/span&gt; &lt;span style="color:#81a1c1;font-weight:bold"&gt;const&lt;/span&gt; sql &lt;span style="color:#81a1c1"&gt;=&lt;/span&gt; &lt;span style="color:#a3be8c"&gt;&amp;#39;SELECT rowid, * FROM users&amp;#39;&lt;/span&gt;&lt;span style="color:#eceff4"&gt;;&lt;/span&gt; db&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;all&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;sql&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; &lt;span style="color:#eceff4"&gt;(&lt;/span&gt;err&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; rows&lt;span style="color:#eceff4"&gt;)&lt;/span&gt; &lt;span style="color:#81a1c1"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#eceff4"&gt;{&lt;/span&gt; &lt;span style="color:#81a1c1;font-weight:bold"&gt;if&lt;/span&gt; &lt;span style="color:#eceff4"&gt;(&lt;/span&gt;err&lt;span style="color:#eceff4"&gt;)&lt;/span&gt; &lt;span style="color:#eceff4"&gt;{&lt;/span&gt; res&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;status&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;&lt;span style="color:#b48ead"&gt;500&lt;/span&gt;&lt;span style="color:#eceff4"&gt;)&lt;/span&gt;&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;send&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;err&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;message&lt;span style="color:#eceff4"&gt;);&lt;/span&gt; &lt;span style="color:#eceff4"&gt;}&lt;/span&gt; &lt;span style="color:#81a1c1;font-weight:bold"&gt;else&lt;/span&gt; &lt;span style="color:#eceff4"&gt;{&lt;/span&gt; res&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;status&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;&lt;span style="color:#b48ead"&gt;200&lt;/span&gt;&lt;span style="color:#eceff4"&gt;)&lt;/span&gt;&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;send&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;rows&lt;span style="color:#eceff4"&gt;);&lt;/span&gt; &lt;span style="color:#eceff4"&gt;}&lt;/span&gt; &lt;span style="color:#eceff4"&gt;});});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Which looks like this in Bruno:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://blog.iankulin.com/images/screen-shot-2023-12-16-at-10.35.56-am.png"&gt;&lt;img src="https://blog.iankulin.com/images/screen-shot-2023-12-16-at-10.35.56-am.png" width="1000" alt=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Or if we just want one in particular, we&amp;rsquo;ll pass the id in the URL.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#81a1c1"&gt;//&lt;/span&gt; endpoint to get a single user from the users table &lt;span style="color:#81a1c1;font-weight:bold"&gt;in&lt;/span&gt; the database&lt;span style="color:#81a1c1"&gt;//&lt;/span&gt; expects an id &lt;span style="color:#81a1c1;font-weight:bold"&gt;in&lt;/span&gt; the URLapp&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;get&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;&lt;span style="color:#a3be8c"&gt;&amp;#39;/user/:id&amp;#39;&lt;/span&gt;&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; &lt;span style="color:#eceff4"&gt;(&lt;/span&gt;req&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; res&lt;span style="color:#eceff4"&gt;)&lt;/span&gt; &lt;span style="color:#81a1c1"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#eceff4"&gt;{&lt;/span&gt; &lt;span style="color:#81a1c1;font-weight:bold"&gt;const&lt;/span&gt; id &lt;span style="color:#81a1c1"&gt;=&lt;/span&gt; req&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;params&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;id&lt;span style="color:#eceff4"&gt;;&lt;/span&gt; &lt;span style="color:#81a1c1;font-weight:bold"&gt;const&lt;/span&gt; sql &lt;span style="color:#81a1c1"&gt;=&lt;/span&gt; &lt;span style="color:#bf616a"&gt;`&lt;/span&gt;SELECT rowid&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; &lt;span style="color:#81a1c1"&gt;*&lt;/span&gt; FROM users WHERE rowid &lt;span style="color:#81a1c1"&gt;=&lt;/span&gt; &lt;span style="color:#81a1c1"&gt;$&lt;/span&gt;&lt;span style="color:#eceff4"&gt;{&lt;/span&gt;id&lt;span style="color:#eceff4"&gt;}&lt;/span&gt;&lt;span style="color:#bf616a"&gt;`&lt;/span&gt;&lt;span style="color:#eceff4"&gt;;&lt;/span&gt; db&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;get&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;sql&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; &lt;span style="color:#eceff4"&gt;(&lt;/span&gt;err&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; row&lt;span style="color:#eceff4"&gt;)&lt;/span&gt; &lt;span style="color:#81a1c1"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#eceff4"&gt;{&lt;/span&gt; &lt;span style="color:#81a1c1;font-weight:bold"&gt;if&lt;/span&gt; &lt;span style="color:#eceff4"&gt;(&lt;/span&gt;err&lt;span style="color:#eceff4"&gt;)&lt;/span&gt; &lt;span style="color:#eceff4"&gt;{&lt;/span&gt; res&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;status&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;&lt;span style="color:#b48ead"&gt;500&lt;/span&gt;&lt;span style="color:#eceff4"&gt;)&lt;/span&gt;&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;send&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;err&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;message&lt;span style="color:#eceff4"&gt;);&lt;/span&gt; &lt;span style="color:#eceff4"&gt;}&lt;/span&gt; &lt;span style="color:#81a1c1;font-weight:bold"&gt;else&lt;/span&gt; &lt;span style="color:#eceff4"&gt;{&lt;/span&gt; res&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;status&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;&lt;span style="color:#b48ead"&gt;200&lt;/span&gt;&lt;span style="color:#eceff4"&gt;)&lt;/span&gt;&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;send&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;row&lt;span style="color:#eceff4"&gt;);&lt;/span&gt; &lt;span style="color:#eceff4"&gt;}&lt;/span&gt; &lt;span style="color:#eceff4"&gt;});});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;a href="https://blog.iankulin.com/images/screen-shot-2023-12-16-at-10.55.25-am.png"&gt;&lt;img src="https://blog.iankulin.com/images/screen-shot-2023-12-16-at-10.55.25-am.png" width="1000" alt=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4 id="update"&gt;Update&lt;/h4&gt;
&lt;p&gt;You&amp;rsquo;re probably getting the hang of this now.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#81a1c1"&gt;//&lt;/span&gt; endpoint to update a user record &lt;span style="color:#81a1c1;font-weight:bold"&gt;in&lt;/span&gt; the users table &lt;span style="color:#81a1c1;font-weight:bold"&gt;in&lt;/span&gt; the database&lt;span style="color:#81a1c1"&gt;//&lt;/span&gt; expects a name&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; &lt;span style="color:#81a1c1;font-weight:bold"&gt;and&lt;/span&gt; email &lt;span style="color:#81a1c1;font-weight:bold"&gt;in&lt;/span&gt; the JSON body of the request&lt;span style="color:#81a1c1"&gt;//&lt;/span&gt; expects an id &lt;span style="color:#81a1c1;font-weight:bold"&gt;in&lt;/span&gt; the URLapp&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;put&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;&lt;span style="color:#a3be8c"&gt;&amp;#39;/user/:id&amp;#39;&lt;/span&gt;&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; &lt;span style="color:#eceff4"&gt;(&lt;/span&gt;req&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; res&lt;span style="color:#eceff4"&gt;)&lt;/span&gt; &lt;span style="color:#81a1c1"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#eceff4"&gt;{&lt;/span&gt; &lt;span style="color:#81a1c1;font-weight:bold"&gt;const&lt;/span&gt; id &lt;span style="color:#81a1c1"&gt;=&lt;/span&gt; req&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;params&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;id&lt;span style="color:#eceff4"&gt;;&lt;/span&gt; &lt;span style="color:#81a1c1;font-weight:bold"&gt;const&lt;/span&gt; name &lt;span style="color:#81a1c1"&gt;=&lt;/span&gt; req&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;body&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;name&lt;span style="color:#eceff4"&gt;;&lt;/span&gt; &lt;span style="color:#81a1c1;font-weight:bold"&gt;const&lt;/span&gt; email &lt;span style="color:#81a1c1"&gt;=&lt;/span&gt; req&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;body&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;email&lt;span style="color:#eceff4"&gt;;&lt;/span&gt; &lt;span style="color:#81a1c1;font-weight:bold"&gt;const&lt;/span&gt; sql &lt;span style="color:#81a1c1"&gt;=&lt;/span&gt; &lt;span style="color:#bf616a"&gt;`&lt;/span&gt;UPDATE users SET name &lt;span style="color:#81a1c1"&gt;=&lt;/span&gt; &lt;span style="color:#a3be8c"&gt;&amp;#34;${name}&amp;#34;&lt;/span&gt;&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; email &lt;span style="color:#81a1c1"&gt;=&lt;/span&gt; &lt;span style="color:#a3be8c"&gt;&amp;#34;${email}&amp;#34;&lt;/span&gt; WHERE rowid &lt;span style="color:#81a1c1"&gt;=&lt;/span&gt; &lt;span style="color:#81a1c1"&gt;$&lt;/span&gt;&lt;span style="color:#eceff4"&gt;{&lt;/span&gt;id&lt;span style="color:#eceff4"&gt;}&lt;/span&gt;&lt;span style="color:#bf616a"&gt;`&lt;/span&gt;&lt;span style="color:#eceff4"&gt;;&lt;/span&gt; db&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;run&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;sql&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; &lt;span style="color:#eceff4"&gt;(&lt;/span&gt;err&lt;span style="color:#eceff4"&gt;)&lt;/span&gt; &lt;span style="color:#81a1c1"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#eceff4"&gt;{&lt;/span&gt; &lt;span style="color:#81a1c1;font-weight:bold"&gt;if&lt;/span&gt; &lt;span style="color:#eceff4"&gt;(&lt;/span&gt;err&lt;span style="color:#eceff4"&gt;)&lt;/span&gt; &lt;span style="color:#eceff4"&gt;{&lt;/span&gt; res&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;status&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;&lt;span style="color:#b48ead"&gt;500&lt;/span&gt;&lt;span style="color:#eceff4"&gt;)&lt;/span&gt;&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;send&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;err&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;message&lt;span style="color:#eceff4"&gt;);&lt;/span&gt; &lt;span style="color:#eceff4"&gt;}&lt;/span&gt; &lt;span style="color:#81a1c1;font-weight:bold"&gt;else&lt;/span&gt; &lt;span style="color:#eceff4"&gt;{&lt;/span&gt; res&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;status&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;&lt;span style="color:#b48ead"&gt;200&lt;/span&gt;&lt;span style="color:#eceff4"&gt;)&lt;/span&gt;&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;send&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;&lt;span style="color:#a3be8c"&gt;&amp;#39;User updated.&amp;#39;&lt;/span&gt;&lt;span style="color:#eceff4"&gt;);&lt;/span&gt; &lt;span style="color:#eceff4"&gt;}&lt;/span&gt; &lt;span style="color:#eceff4"&gt;});});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="delete"&gt;Delete&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#81a1c1"&gt;//&lt;/span&gt; endpoint to delete a user record from the users table &lt;span style="color:#81a1c1;font-weight:bold"&gt;in&lt;/span&gt; the database&lt;span style="color:#81a1c1"&gt;//&lt;/span&gt; expects an id &lt;span style="color:#81a1c1;font-weight:bold"&gt;in&lt;/span&gt; the URL&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt; Doesn&lt;span style="color:#a3be8c"&gt;&amp;#39;t complain if the id doesn&amp;#39;&lt;/span&gt;t exist&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;app&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;delete&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;&lt;span style="color:#a3be8c"&gt;&amp;#39;/user/:id&amp;#39;&lt;/span&gt;&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; &lt;span style="color:#eceff4"&gt;(&lt;/span&gt;req&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; res&lt;span style="color:#eceff4"&gt;)&lt;/span&gt; &lt;span style="color:#81a1c1"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#eceff4"&gt;{&lt;/span&gt; &lt;span style="color:#81a1c1;font-weight:bold"&gt;const&lt;/span&gt; id &lt;span style="color:#81a1c1"&gt;=&lt;/span&gt; req&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;params&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;id&lt;span style="color:#eceff4"&gt;;&lt;/span&gt; &lt;span style="color:#81a1c1;font-weight:bold"&gt;const&lt;/span&gt; sql &lt;span style="color:#81a1c1"&gt;=&lt;/span&gt; &lt;span style="color:#bf616a"&gt;`&lt;/span&gt;DELETE FROM users WHERE rowid &lt;span style="color:#81a1c1"&gt;=&lt;/span&gt; &lt;span style="color:#81a1c1"&gt;$&lt;/span&gt;&lt;span style="color:#eceff4"&gt;{&lt;/span&gt;id&lt;span style="color:#eceff4"&gt;}&lt;/span&gt;&lt;span style="color:#bf616a"&gt;`&lt;/span&gt;&lt;span style="color:#eceff4"&gt;;&lt;/span&gt; db&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;run&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;sql&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; &lt;span style="color:#eceff4"&gt;(&lt;/span&gt;err&lt;span style="color:#eceff4"&gt;)&lt;/span&gt; &lt;span style="color:#81a1c1"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#eceff4"&gt;{&lt;/span&gt; &lt;span style="color:#81a1c1;font-weight:bold"&gt;if&lt;/span&gt; &lt;span style="color:#eceff4"&gt;(&lt;/span&gt;err&lt;span style="color:#eceff4"&gt;)&lt;/span&gt; &lt;span style="color:#eceff4"&gt;{&lt;/span&gt; res&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;status&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;&lt;span style="color:#b48ead"&gt;500&lt;/span&gt;&lt;span style="color:#eceff4"&gt;)&lt;/span&gt;&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;send&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;err&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;message&lt;span style="color:#eceff4"&gt;);&lt;/span&gt; &lt;span style="color:#eceff4"&gt;}&lt;/span&gt; &lt;span style="color:#81a1c1;font-weight:bold"&gt;else&lt;/span&gt; &lt;span style="color:#eceff4"&gt;{&lt;/span&gt; res&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;status&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;&lt;span style="color:#b48ead"&gt;200&lt;/span&gt;&lt;span style="color:#eceff4"&gt;)&lt;/span&gt;&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;send&lt;span style="color:#eceff4"&gt;();&lt;/span&gt; &lt;span style="color:#eceff4"&gt;}&lt;/span&gt; &lt;span style="color:#eceff4"&gt;});});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="hardening"&gt;Hardening&lt;/h3&gt;
&lt;p&gt;To keep things simple (since I was just trying to show basic examples of using sqlite) I used string interpolation when making the SQL to run against the database. That&amp;rsquo;s not a great technique because of the danger of SQL injection; so we should routinely use parameterized queries instead. Here&amp;rsquo;s how adding a user looks if we use parameterized queries:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#81a1c1"&gt;//&lt;/span&gt; endpoint to add a user record to the users table&lt;span style="color:#81a1c1"&gt;//&lt;/span&gt; expects a name &lt;span style="color:#81a1c1;font-weight:bold"&gt;and&lt;/span&gt; email &lt;span style="color:#81a1c1;font-weight:bold"&gt;in&lt;/span&gt; the JSON body of the requestapp&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;post&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;&lt;span style="color:#a3be8c"&gt;&amp;#39;/users&amp;#39;&lt;/span&gt;&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; &lt;span style="color:#eceff4"&gt;(&lt;/span&gt;req&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; res&lt;span style="color:#eceff4"&gt;)&lt;/span&gt; &lt;span style="color:#81a1c1"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#eceff4"&gt;{&lt;/span&gt; &lt;span style="color:#81a1c1;font-weight:bold"&gt;const&lt;/span&gt; name &lt;span style="color:#81a1c1"&gt;=&lt;/span&gt; req&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;body&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;name&lt;span style="color:#eceff4"&gt;;&lt;/span&gt; &lt;span style="color:#81a1c1;font-weight:bold"&gt;const&lt;/span&gt; email &lt;span style="color:#81a1c1"&gt;=&lt;/span&gt; req&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;body&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;email&lt;span style="color:#eceff4"&gt;;&lt;/span&gt; &lt;span style="color:#81a1c1;font-weight:bold"&gt;const&lt;/span&gt; sql &lt;span style="color:#81a1c1"&gt;=&lt;/span&gt; &lt;span style="color:#bf616a"&gt;`&lt;/span&gt;INSERT INTO users &lt;span style="color:#eceff4"&gt;(&lt;/span&gt;name&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; email&lt;span style="color:#eceff4"&gt;)&lt;/span&gt; VALUES &lt;span style="color:#eceff4"&gt;(&lt;/span&gt;&lt;span style="color:#bf616a"&gt;?&lt;/span&gt;&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; &lt;span style="color:#bf616a"&gt;?&lt;/span&gt;&lt;span style="color:#eceff4"&gt;)&lt;/span&gt;&lt;span style="color:#bf616a"&gt;`&lt;/span&gt;&lt;span style="color:#eceff4"&gt;;&lt;/span&gt; db&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;run&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;sql&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; &lt;span style="color:#eceff4"&gt;[&lt;/span&gt;name&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; email&lt;span style="color:#eceff4"&gt;],&lt;/span&gt; function&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;err&lt;span style="color:#eceff4"&gt;)&lt;/span&gt; &lt;span style="color:#eceff4"&gt;{&lt;/span&gt; &lt;span style="color:#81a1c1;font-weight:bold"&gt;if&lt;/span&gt; &lt;span style="color:#eceff4"&gt;(&lt;/span&gt;err&lt;span style="color:#eceff4"&gt;)&lt;/span&gt; &lt;span style="color:#eceff4"&gt;{&lt;/span&gt; res&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;status&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;&lt;span style="color:#b48ead"&gt;500&lt;/span&gt;&lt;span style="color:#eceff4"&gt;)&lt;/span&gt;&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;send&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;err&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;message&lt;span style="color:#eceff4"&gt;);&lt;/span&gt; &lt;span style="color:#eceff4"&gt;}&lt;/span&gt; &lt;span style="color:#81a1c1;font-weight:bold"&gt;else&lt;/span&gt; &lt;span style="color:#eceff4"&gt;{&lt;/span&gt; res&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;status&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;&lt;span style="color:#b48ead"&gt;201&lt;/span&gt;&lt;span style="color:#eceff4"&gt;)&lt;/span&gt;&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;json&lt;span style="color:#eceff4"&gt;({&lt;/span&gt; rowid&lt;span style="color:#eceff4"&gt;:&lt;/span&gt; this&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;lastID &lt;span style="color:#eceff4"&gt;});&lt;/span&gt; &lt;span style="color:#eceff4"&gt;}&lt;/span&gt; &lt;span style="color:#eceff4"&gt;});});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;With parameterized queries, whatever the user passes in ends up in the database rather than being executed as part of the query string.&lt;/p&gt;
&lt;p&gt;For example, imagine if an API user tried to add a user with this body:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{ &amp;#34;name&amp;#34;: &amp;#34;John&amp;#34;, &amp;#34;email&amp;#34;: &amp;#34;john@example.com\&amp;#34;); DROP TABLE users; --&amp;#34;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then my original add code:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;app&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;post&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;&lt;span style="color:#a3be8c"&gt;&amp;#39;/users&amp;#39;&lt;/span&gt;&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; &lt;span style="color:#eceff4"&gt;(&lt;/span&gt;req&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; res&lt;span style="color:#eceff4"&gt;)&lt;/span&gt; &lt;span style="color:#81a1c1"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#eceff4"&gt;{&lt;/span&gt; &lt;span style="color:#81a1c1;font-weight:bold"&gt;const&lt;/span&gt; name &lt;span style="color:#81a1c1"&gt;=&lt;/span&gt; req&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;body&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;name&lt;span style="color:#eceff4"&gt;;&lt;/span&gt; &lt;span style="color:#81a1c1;font-weight:bold"&gt;const&lt;/span&gt; email &lt;span style="color:#81a1c1"&gt;=&lt;/span&gt; req&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;body&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;email&lt;span style="color:#eceff4"&gt;;&lt;/span&gt; &lt;span style="color:#81a1c1;font-weight:bold"&gt;const&lt;/span&gt; sql &lt;span style="color:#81a1c1"&gt;=&lt;/span&gt; &lt;span style="color:#bf616a"&gt;`&lt;/span&gt;INSERT INTO users &lt;span style="color:#eceff4"&gt;(&lt;/span&gt;name&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; email&lt;span style="color:#eceff4"&gt;)&lt;/span&gt; VALUES &lt;span style="color:#eceff4"&gt;(&lt;/span&gt;&lt;span style="color:#a3be8c"&gt;&amp;#34;${name}&amp;#34;&lt;/span&gt;&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; &lt;span style="color:#a3be8c"&gt;&amp;#34;${email}&amp;#34;&lt;/span&gt;&lt;span style="color:#eceff4"&gt;)&lt;/span&gt;&lt;span style="color:#bf616a"&gt;`&lt;/span&gt;&lt;span style="color:#eceff4"&gt;;&lt;/span&gt; db&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;run&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;sql&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; function&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;err&lt;span style="color:#eceff4"&gt;)&lt;/span&gt; &lt;span style="color:#eceff4"&gt;{&lt;/span&gt; &lt;span style="color:#81a1c1;font-weight:bold"&gt;if&lt;/span&gt; &lt;span style="color:#eceff4"&gt;(&lt;/span&gt;err&lt;span style="color:#eceff4"&gt;)&lt;/span&gt; &lt;span style="color:#eceff4"&gt;{&lt;/span&gt; res&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;status&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;&lt;span style="color:#b48ead"&gt;500&lt;/span&gt;&lt;span style="color:#eceff4"&gt;)&lt;/span&gt;&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;send&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;err&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;message&lt;span style="color:#eceff4"&gt;);&lt;/span&gt; &lt;span style="color:#eceff4"&gt;}&lt;/span&gt; &lt;span style="color:#81a1c1;font-weight:bold"&gt;else&lt;/span&gt; &lt;span style="color:#eceff4"&gt;{&lt;/span&gt; res&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;status&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;&lt;span style="color:#b48ead"&gt;201&lt;/span&gt;&lt;span style="color:#eceff4"&gt;)&lt;/span&gt;&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;json&lt;span style="color:#eceff4"&gt;({&lt;/span&gt; rowid&lt;span style="color:#eceff4"&gt;:&lt;/span&gt; this&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;lastID &lt;span style="color:#eceff4"&gt;});&lt;/span&gt; &lt;span style="color:#eceff4"&gt;}&lt;/span&gt; &lt;span style="color:#eceff4"&gt;});});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;would result in executing this against the database:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;INSERT INTO users (name, email) VALUES (&amp;#34;John&amp;#34;, &amp;#34;john@example.com&amp;#34;); DROP TABLE users; --&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;which would delete the entire users table from the database. This is &lt;a href="https://xkcd.com/327/"&gt;widely known as the &amp;ldquo;Bobby Tables&amp;rdquo; problem&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;With the parameterized version, you just end up with an ugly user record.&lt;/p&gt;
&lt;p&gt;Changing all of these doesn&amp;rsquo;t add much code, but does make it a little bit harder to follow, hence showing you the old version first.&lt;/p&gt;
&lt;h3 id="rest-api-conventions"&gt;REST API conventions&lt;/h3&gt;
&lt;p&gt;You may have noticed in this code I&amp;rsquo;ve used a variety of HTTP request types - GET, POST, PUT, DELETE etc. There&amp;rsquo;s no rules for these things, but if someone else (including future you) is going to have to maintain or use your API, it&amp;rsquo;s a good idea to follow the conventions.&lt;/p&gt;
&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Situation&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Request&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;URL&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Return&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Add a record&lt;/td&gt;&lt;td&gt;POST&lt;/td&gt;&lt;td&gt;/users&lt;/td&gt;&lt;td&gt;record id&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Replace a whole record&lt;/td&gt;&lt;td&gt;PUT&lt;/td&gt;&lt;td&gt;/users/:id&lt;/td&gt;&lt;td&gt;the whole record&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Replace part of a record&lt;/td&gt;&lt;td&gt;PATCH&lt;/td&gt;&lt;td&gt;/users/:id&lt;/td&gt;&lt;td&gt;the whole record&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Get all the records&lt;/td&gt;&lt;td&gt;GET&lt;/td&gt;&lt;td&gt;/users&lt;/td&gt;&lt;td&gt;all the records&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Get a particular record&lt;/td&gt;&lt;td&gt;GET&lt;/td&gt;&lt;td&gt;/users/:id&lt;/td&gt;&lt;td&gt;that record&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Delete a record&lt;/td&gt;&lt;td&gt;DELETE&lt;/td&gt;&lt;td&gt;/users/:id&lt;/td&gt;&lt;td&gt;nothing&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;You might have noticed that I haven&amp;rsquo;t done the PATCH - the difference between that and the PUT is that with the PATCH we don&amp;rsquo;t supply the whole record, just the fields we want to change. I&amp;rsquo;m not going to worry about that for this API since our record is so small.&lt;/p&gt;
&lt;p&gt;But I also don&amp;rsquo;t return the whole record after a PUT. Unfortunately, it means a second request - but there&amp;rsquo;s probably not much of a performance hit since it will be in the cache.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#81a1c1"&gt;//&lt;/span&gt; endpoint to update a user record &lt;span style="color:#81a1c1;font-weight:bold"&gt;in&lt;/span&gt; the users table &lt;span style="color:#81a1c1;font-weight:bold"&gt;in&lt;/span&gt; the database&lt;span style="color:#81a1c1"&gt;//&lt;/span&gt; expects a name&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; &lt;span style="color:#81a1c1;font-weight:bold"&gt;and&lt;/span&gt; email &lt;span style="color:#81a1c1;font-weight:bold"&gt;in&lt;/span&gt; the JSON body of the request&lt;span style="color:#81a1c1"&gt;//&lt;/span&gt; expects an id &lt;span style="color:#81a1c1;font-weight:bold"&gt;in&lt;/span&gt; the URLapp&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;put&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;&lt;span style="color:#a3be8c"&gt;&amp;#39;/user/:id&amp;#39;&lt;/span&gt;&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; &lt;span style="color:#eceff4"&gt;(&lt;/span&gt;req&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; res&lt;span style="color:#eceff4"&gt;)&lt;/span&gt; &lt;span style="color:#81a1c1"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#eceff4"&gt;{&lt;/span&gt; &lt;span style="color:#81a1c1;font-weight:bold"&gt;const&lt;/span&gt; id &lt;span style="color:#81a1c1"&gt;=&lt;/span&gt; req&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;params&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;id&lt;span style="color:#eceff4"&gt;;&lt;/span&gt; &lt;span style="color:#81a1c1;font-weight:bold"&gt;const&lt;/span&gt; name &lt;span style="color:#81a1c1"&gt;=&lt;/span&gt; req&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;body&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;name&lt;span style="color:#eceff4"&gt;;&lt;/span&gt; &lt;span style="color:#81a1c1;font-weight:bold"&gt;const&lt;/span&gt; email &lt;span style="color:#81a1c1"&gt;=&lt;/span&gt; req&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;body&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;email&lt;span style="color:#eceff4"&gt;;&lt;/span&gt; &lt;span style="color:#81a1c1;font-weight:bold"&gt;const&lt;/span&gt; updateSql &lt;span style="color:#81a1c1"&gt;=&lt;/span&gt; &lt;span style="color:#bf616a"&gt;`&lt;/span&gt;UPDATE users SET name &lt;span style="color:#81a1c1"&gt;=&lt;/span&gt; &lt;span style="color:#bf616a"&gt;?&lt;/span&gt;&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; email &lt;span style="color:#81a1c1"&gt;=&lt;/span&gt; &lt;span style="color:#bf616a"&gt;?&lt;/span&gt; WHERE rowid &lt;span style="color:#81a1c1"&gt;=&lt;/span&gt; &lt;span style="color:#bf616a"&gt;?`&lt;/span&gt;&lt;span style="color:#eceff4"&gt;;&lt;/span&gt; db&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;run&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;updateSql&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; &lt;span style="color:#eceff4"&gt;[&lt;/span&gt;name&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; email&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; id&lt;span style="color:#eceff4"&gt;],&lt;/span&gt; &lt;span style="color:#eceff4"&gt;(&lt;/span&gt;err&lt;span style="color:#eceff4"&gt;)&lt;/span&gt; &lt;span style="color:#81a1c1"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#eceff4"&gt;{&lt;/span&gt; &lt;span style="color:#81a1c1;font-weight:bold"&gt;if&lt;/span&gt; &lt;span style="color:#eceff4"&gt;(&lt;/span&gt;err&lt;span style="color:#eceff4"&gt;)&lt;/span&gt; &lt;span style="color:#eceff4"&gt;{&lt;/span&gt; res&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;status&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;&lt;span style="color:#b48ead"&gt;500&lt;/span&gt;&lt;span style="color:#eceff4"&gt;)&lt;/span&gt;&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;send&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;err&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;message&lt;span style="color:#eceff4"&gt;);&lt;/span&gt; &lt;span style="color:#eceff4"&gt;}&lt;/span&gt; &lt;span style="color:#81a1c1;font-weight:bold"&gt;else&lt;/span&gt; &lt;span style="color:#eceff4"&gt;{&lt;/span&gt; &lt;span style="color:#81a1c1;font-weight:bold"&gt;const&lt;/span&gt; selectSql &lt;span style="color:#81a1c1"&gt;=&lt;/span&gt; &lt;span style="color:#bf616a"&gt;`&lt;/span&gt;SELECT rowid&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; &lt;span style="color:#81a1c1"&gt;*&lt;/span&gt; FROM users WHERE rowid &lt;span style="color:#81a1c1"&gt;=&lt;/span&gt; &lt;span style="color:#bf616a"&gt;?`&lt;/span&gt;&lt;span style="color:#eceff4"&gt;;&lt;/span&gt; db&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;get&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;selectSql&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; &lt;span style="color:#eceff4"&gt;[&lt;/span&gt;id&lt;span style="color:#eceff4"&gt;],&lt;/span&gt; &lt;span style="color:#eceff4"&gt;(&lt;/span&gt;err&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; row&lt;span style="color:#eceff4"&gt;)&lt;/span&gt; &lt;span style="color:#81a1c1"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#eceff4"&gt;{&lt;/span&gt; &lt;span style="color:#81a1c1;font-weight:bold"&gt;if&lt;/span&gt; &lt;span style="color:#eceff4"&gt;(&lt;/span&gt;err&lt;span style="color:#eceff4"&gt;)&lt;/span&gt; &lt;span style="color:#eceff4"&gt;{&lt;/span&gt; res&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;status&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;&lt;span style="color:#b48ead"&gt;500&lt;/span&gt;&lt;span style="color:#eceff4"&gt;)&lt;/span&gt;&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;send&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;err&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;message&lt;span style="color:#eceff4"&gt;);&lt;/span&gt; &lt;span style="color:#eceff4"&gt;}&lt;/span&gt; &lt;span style="color:#81a1c1;font-weight:bold"&gt;else&lt;/span&gt; &lt;span style="color:#eceff4"&gt;{&lt;/span&gt; res&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;status&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;&lt;span style="color:#b48ead"&gt;200&lt;/span&gt;&lt;span style="color:#eceff4"&gt;)&lt;/span&gt;&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;json&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;row&lt;span style="color:#eceff4"&gt;);&lt;/span&gt; &lt;span style="color:#eceff4"&gt;}&lt;/span&gt; &lt;span style="color:#eceff4"&gt;});&lt;/span&gt; &lt;span style="color:#eceff4"&gt;}&lt;/span&gt; &lt;span style="color:#eceff4"&gt;});});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;a href="https://github.com/IanKulin/sqlite-rest-demo/blob/main/app.js"&gt;Link to the completed project on Github&lt;/a&gt;.&lt;/p&gt;</description></item></channel></rss>