In-Database WebApps and REST Services: Difference between revisions
(One intermediate revision by the same user not shown) | |||
Line 55: | Line 55: | ||
https://github.com/launix-de/rdfop |
https://github.com/launix-de/rdfop |
||
+ | |||
+ | Another example can be found in [[Websockets in MemCP]] |
Latest revision as of 21:54, 8 October 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:
https://github.com/launix-de/rdfop
Another example can be found in Websockets in MemCP