<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://www.memcp.org/index.php?action=history&amp;feed=atom&amp;title=In-Database_WebApps_and_REST_Services</id>
	<title>In-Database WebApps and REST Services - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://www.memcp.org/index.php?action=history&amp;feed=atom&amp;title=In-Database_WebApps_and_REST_Services"/>
	<link rel="alternate" type="text/html" href="https://www.memcp.org/index.php?title=In-Database_WebApps_and_REST_Services&amp;action=history"/>
	<updated>2026-04-24T10:36:06Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.39.1</generator>
	<entry>
		<id>https://www.memcp.org/index.php?title=In-Database_WebApps_and_REST_Services&amp;diff=138&amp;oldid=prev</id>
		<title>Carli: /* Example WebApps */</title>
		<link rel="alternate" type="text/html" href="https://www.memcp.org/index.php?title=In-Database_WebApps_and_REST_Services&amp;diff=138&amp;oldid=prev"/>
		<updated>2024-10-08T20:54:24Z</updated>

		<summary type="html">&lt;p&gt;&lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;Example WebApps&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 22:54, 8 October 2024&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l55&quot;&gt;Line 55:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 55:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;https://github.com/launix-de/rdfop&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;https://github.com/launix-de/rdfop&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;Another example can be found in [[Websockets in MemCP]]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;!-- diff cache key memcp_wiki-mediawiki-:diff::1.12:old-93:rev-138 --&gt;
&lt;/table&gt;</summary>
		<author><name>Carli</name></author>
	</entry>
	<entry>
		<id>https://www.memcp.org/index.php?title=In-Database_WebApps_and_REST_Services&amp;diff=93&amp;oldid=prev</id>
		<title>Carli: Carli moved page In-Database WebApps to In-Database WebApps and REST Services</title>
		<link rel="alternate" type="text/html" href="https://www.memcp.org/index.php?title=In-Database_WebApps_and_REST_Services&amp;diff=93&amp;oldid=prev"/>
		<updated>2024-05-19T13:46:23Z</updated>

		<summary type="html">&lt;p&gt;Carli moved page &lt;a href=&quot;/wiki/In-Database_WebApps&quot; class=&quot;mw-redirect&quot; title=&quot;In-Database WebApps&quot;&gt;In-Database WebApps&lt;/a&gt; to &lt;a href=&quot;/wiki/In-Database_WebApps_and_REST_Services&quot; title=&quot;In-Database WebApps and REST Services&quot;&gt;In-Database WebApps and REST Services&lt;/a&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 15:46, 19 May 2024&lt;/td&gt;
				&lt;/tr&gt;
&lt;!-- diff cache key memcp_wiki-mediawiki-:diff::1.12:old-91:rev-93 --&gt;
&lt;/table&gt;</summary>
		<author><name>Carli</name></author>
	</entry>
	<entry>
		<id>https://www.memcp.org/index.php?title=In-Database_WebApps_and_REST_Services&amp;diff=91&amp;oldid=prev</id>
		<title>Carli: /* Including SQL or RDF queries in your custom REST endpoint */</title>
		<link rel="alternate" type="text/html" href="https://www.memcp.org/index.php?title=In-Database_WebApps_and_REST_Services&amp;diff=91&amp;oldid=prev"/>
		<updated>2024-05-19T13:44:50Z</updated>

		<summary type="html">&lt;p&gt;&lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;Including SQL or RDF queries in your custom REST endpoint&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 15:44, 19 May 2024&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l45&quot;&gt;Line 45:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 45:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;   &lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;   &lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;  /* now inside your HTTP handler: */&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;  /* now inside your HTTP handler: */&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;  (set resultrow (&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;req &lt;/del&gt;&amp;quot;jsonl&amp;quot;)) /* this is the jsonl printer, but you can also use print or any lambda that takes a associative array with the results */&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;  (set resultrow (&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;res &lt;/ins&gt;&amp;quot;jsonl&amp;quot;)) /* this is the jsonl printer, but you can also use print or any lambda that takes a associative array with the results */&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;  (eval my_code) /* execute query */&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;  (eval my_code) /* execute query */&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;To read on how to handle the result object, take a look at: [[Lists and Objects]]&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;To read on how to handle the result object, take a look at: [[Lists and Objects]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;!-- diff cache key memcp_wiki-mediawiki-:diff::1.12:old-90:rev-91 --&gt;
&lt;/table&gt;</summary>
		<author><name>Carli</name></author>
	</entry>
	<entry>
		<id>https://www.memcp.org/index.php?title=In-Database_WebApps_and_REST_Services&amp;diff=90&amp;oldid=prev</id>
		<title>Carli: Created page with &quot;In-Database WebApps are a huge game changer in REST API performance since the web app runs in the same context as the   == REST Endpoint setup == You basically set up a REST endpoint by overwriting the &lt;code&gt;http_handler&lt;/code&gt; variable in the global scope. Best practice is here to overload http_handler, store the old handler in &lt;code&gt;old_handler&lt;/code&gt; and cascade the router with a prefix:  (define http_handler (begin          (set old_handler (coalesce http_handler han...&quot;</title>
		<link rel="alternate" type="text/html" href="https://www.memcp.org/index.php?title=In-Database_WebApps_and_REST_Services&amp;diff=90&amp;oldid=prev"/>
		<updated>2024-05-19T09:08:30Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;In-Database WebApps are a huge game changer in REST API performance since the web app runs in the same context as the   == REST Endpoint setup == You basically set up a REST endpoint by overwriting the &amp;lt;code&amp;gt;http_handler&amp;lt;/code&amp;gt; variable in the global scope. Best practice is here to overload http_handler, store the old handler in &amp;lt;code&amp;gt;old_handler&amp;lt;/code&amp;gt; and cascade the router with a prefix:  (define http_handler (begin          (set old_handler (coalesce http_handler han...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;In-Database WebApps are a huge game changer in REST API performance since the web app runs in the same context as the &lt;br /&gt;
&lt;br /&gt;
== REST Endpoint setup ==&lt;br /&gt;
You basically set up a REST endpoint by overwriting the &amp;lt;code&amp;gt;http_handler&amp;lt;/code&amp;gt; variable in the global scope. Best practice is here to overload http_handler, store the old handler in &amp;lt;code&amp;gt;old_handler&amp;lt;/code&amp;gt; and cascade the router with a prefix:&lt;br /&gt;
 (define http_handler (begin&lt;br /&gt;
         (set old_handler (coalesce http_handler handler_404))&lt;br /&gt;
 &lt;br /&gt;
         /* here starts our custom router */&lt;br /&gt;
         (lambda (req res) (begin&lt;br /&gt;
                 /* hooked our additional paths to it */&lt;br /&gt;
                 (match (req &amp;quot;path&amp;quot;)&lt;br /&gt;
                         (regex &amp;quot;^/my_prefix(.*)$&amp;quot; url subpath) (begin&lt;br /&gt;
                                 (my_custom_handler req res path)&lt;br /&gt;
                         )&lt;br /&gt;
                         /* default */&lt;br /&gt;
                         (old_handler req res))&lt;br /&gt;
 &lt;br /&gt;
         ))&lt;br /&gt;
 ))&lt;br /&gt;
Now you can implement your own custom handler:&lt;br /&gt;
 (define my_custom_handler (lambda (req res subpath) (begin&lt;br /&gt;
         /* print hello world */&lt;br /&gt;
         ((res &amp;quot;header&amp;quot;) &amp;quot;Content-Type&amp;quot; &amp;quot;text/html&amp;quot;)&lt;br /&gt;
         ((res &amp;quot;status&amp;quot;) 200)&lt;br /&gt;
         ((res &amp;quot;print&amp;quot;) &amp;quot;&amp;lt;nowiki&amp;gt;&amp;lt;h1&amp;gt;Hello World&amp;lt;/h1&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;quot;)&lt;br /&gt;
 )))&lt;br /&gt;
Now you can query your endpoint with:&lt;br /&gt;
 curl &amp;lt;nowiki&amp;gt;http://localhost:4321/my_prefix&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
In your custom handler, you can again parse your subpath to go to the single routes.&lt;br /&gt;
&lt;br /&gt;
For more details, take a look at [[Scheme: serve|HTTP Server]].&lt;br /&gt;
&lt;br /&gt;
== Including SQL or RDF queries in your custom REST endpoint ==&lt;br /&gt;
The SQL and RDF frontend have helper functions:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;(parse_sparql schema query)&amp;lt;/code&amp;gt; to create the code for a SPARQL query&lt;br /&gt;
* &amp;lt;code&amp;gt;(parse_sql schema query)&amp;lt;/code&amp;gt; to create the code for a SQL query&lt;br /&gt;
&lt;br /&gt;
Basically, you do the parsing and preparation outside of your HTTP handler in order to get the best performance out of prepared statements.&lt;br /&gt;
&lt;br /&gt;
In the last step, you overwrite the query parameters as well as the function &amp;lt;code&amp;gt;resultrow&amp;lt;/code&amp;gt; in your scope and then feed the code into &amp;lt;code&amp;gt;eval&amp;lt;/code&amp;gt;:&lt;br /&gt;
 (set my_code (parse_sql &amp;quot;my_database&amp;quot; &amp;quot;SELECT * FROM a&amp;quot;))&lt;br /&gt;
 (set my_code (optimize my_code)) /* optionally run the optimizer over it */&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 /* now inside your HTTP handler: */&lt;br /&gt;
 (set resultrow (req &amp;quot;jsonl&amp;quot;)) /* this is the jsonl printer, but you can also use print or any lambda that takes a associative array with the results */&lt;br /&gt;
 (eval my_code) /* execute query */&lt;br /&gt;
To read on how to handle the result object, take a look at: [[Lists and Objects]]&lt;br /&gt;
&lt;br /&gt;
== Example WebApps ==&lt;br /&gt;
You find a minimal example in the apps/ folder in the memcp sources.&lt;br /&gt;
&lt;br /&gt;
You find a complex example of a RDF browser and whole template engine in:&lt;br /&gt;
&lt;br /&gt;
https://github.com/launix-de/rdfop&lt;/div&gt;</summary>
		<author><name>Carli</name></author>
	</entry>
</feed>