In-Database WebApps and REST Services: Difference between revisions
(Created page with "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 <code>http_handler</code> variable in the global scope. Best practice is here to overload http_handler, store the old handler in <code>old_handler</code> and cascade the router with a prefix: (define http_handler (begin (set old_handler (coalesce http_handler han...") |
|||
Line 45: | Line 45: | ||
/* now inside your HTTP handler: */ |
/* now inside your HTTP handler: */ |
||
− | (set resultrow ( |
+ | (set resultrow (res "jsonl")) /* this is the jsonl printer, but you can also use print or any lambda that takes a associative array with the results */ |
(eval my_code) /* execute query */ |
(eval my_code) /* execute query */ |
||
To read on how to handle the result object, take a look at: [[Lists and Objects]] |
To read on how to handle the result object, take a look at: [[Lists and Objects]] |
Revision as of 14:44, 19 May 2024
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 http_handler
variable in the global scope. Best practice is here to overload http_handler, store the old handler in old_handler
and cascade the router with a prefix:
(define http_handler (begin (set old_handler (coalesce http_handler handler_404)) /* here starts our custom router */ (lambda (req res) (begin /* hooked our additional paths to it */ (match (req "path") (regex "^/my_prefix(.*)$" url subpath) (begin (my_custom_handler req res path) ) /* default */ (old_handler req res)) )) ))
Now you can implement your own custom handler:
(define my_custom_handler (lambda (req res subpath) (begin /* print hello world */ ((res "header") "Content-Type" "text/html") ((res "status") 200) ((res "print") "<h1>Hello World</h1>") )))
Now you can query your endpoint with:
curl http://localhost:4321/my_prefix
In your custom handler, you can again parse your subpath to go to the single routes.
For more details, take a look at HTTP Server.
Including SQL or RDF queries in your custom REST endpoint
The SQL and RDF frontend have helper functions:
(parse_sparql schema query)
to create the code for a SPARQL query(parse_sql schema query)
to create the code for a SQL query
Basically, you do the parsing and preparation outside of your HTTP handler in order to get the best performance out of prepared statements.
In the last step, you overwrite the query parameters as well as the function resultrow
in your scope and then feed the code into eval
:
(set my_code (parse_sql "my_database" "SELECT * FROM a")) (set my_code (optimize my_code)) /* optionally run the optimizer over it */ /* now inside your HTTP handler: */ (set resultrow (res "jsonl")) /* this is the jsonl printer, but you can also use print or any lambda that takes a associative array with the results */ (eval my_code) /* execute query */
To read on how to handle the result object, take a look at: Lists and Objects
Example WebApps
You find a minimal example in the apps/ folder in the memcp sources.
You find a complex example of a RDF browser and whole template engine in: