Hyperlambda HTTP interceptors allows you to intercept some HTTP endpoint, and add logic that should be executed before or after your original endpoint. This opens up a lot of interesting use cases, such as for instance.
- Logging invocations to your original endpoint
- Attaching additional input data to your original endpoint
- Return additional data from your endpoint required by the client
- Changing the data specified by the client before invoking original endpoint
- Changing authorisation requirements to your original endpoint
- Add caching to your intercepted endpoint
- Etc, etc, etc
This becomes almost the HTTP equivalent of AOP software development, which of course implies "Aspect Oriented Programming", and is a more declarative way of creating software, due to allowing you to attach additional functionality, both before and after the invocation to your original endpoint.
Other use cases might be adding business logic to an HTTP endpoint you cannot add business logic to, such as for instance a GraphQL or PostgREST endpoints, such as those given to you by Hasura or Supabase. Logically this becomes the HTTP and Hyperlambda equivalent of OOP "polymorphism", since it allows you to take some static thing, and modify how it behaves by "overriding" your original HTTP method. In the video below I am showing you how such interceptors works.
The idea is easily understood; Take some "whatever" HTTP endpoint. Create a new interceptor endpoint that invokes your original endpoint, and attach code to your interceptor endpoint allowing you to do things both before and after your intercepted endpoint is invoked. Then forward the arguments given to your interceptor to your intercepted endpoint, and optionally attach the Authorization header if any before invoking the intercepted endpoint.
Now the only thing you need to do to start using your interceptor, is to change the URL your client is using while invoking the original endpoint. The signature and logic should be the same, assuming your interceptor endpoint can accept any arguments.
You can find the code I am using in the above video below.
.arguments:* .description:Intercepts our foo endpoint // Endpoint we're intercepting. .endpoint:"https://tiger-polterguy.gb.aista.com/magic/modules/faq/foo" /* * Retrieving Authorization header to transmit to * intercepted endpoint. */ request.headers.get:Authorization /* * Lambda object executed as an "intercepted lambda object" * before invocation to HTTP endpoint. */ .before log.info:BEFORE!! /* * This is where you would parametrise your above [.before] object * with for instance arguments given by the client. */ // Evaluating [.before] lambda object. eval:x:@.before // Forwarding arguments given to endpoint to intercepted endpoint. add:x:../*/http.post/*/payload get-nodes:x:@.arguments/* /* * Checking if we've got an Authorization HTTP header, * at which point we forward it to the original HTTP endpoint. */ if not-null:x:@request.headers.get .lambda add:x:../*/http.post/*/headers . Authorization:x:@request.headers.get // Invoking the intercepted HTTP endpoint. http.post:x:@.endpoint headers Content-Type:application/json convert:true payload // Sanity checking invocation to endpoint. if not and mte:x:@http.post .:int:200 lt:x:@http.post .:int:400 .lambda log.error:Something went wrong as we invoked our intercepted HTTP endpoint endpoint:x:@.endpoint status:x:@http.post result:x:@http.post/*/content throw:Intercepted endpoint did not return success public:true status:502 /* * Lambda object to execute after invocation to * intercepted endpoint. */ .after log.info:AFTER!! /* * This is where you would parametrise your above [.after] object * with for instance arguments given by the client. */ // Evaluating [.before] lambda object. eval:x:@.after // Return result to caller. add:x:+ get-nodes:x:@http.post/*/content/* return
.arguments name:string auth.ticket.verify:root log.info:Foo endpoint was executed strings.concat .:"Hello " get-value:x:@.arguments/*/name unwrap:x:+/* return result:x:@strings.concat