import ballerina/http;

// Header name to be set to the request in the request interceptor.
final string interceptor_header1 = "X-requestHeader1";
final string interceptor_header2 = "X-requestHeader2";

// Header value to be set to the request in the request interceptor.
final string interceptor_header_value1 = "RequestInterceptor1";
final string interceptor_header_value2 = "RequestInterceptor2";

service class RequestInterceptor1 {
    *http:RequestInterceptor;

    resource function 'default [string... path](http:RequestContext ctx, 
                            http:Request req) returns http:NextService|error? {
        // Sets a header to the request inside the interceptor service.
        req.setHeader(interceptor_header1, interceptor_header_value1);
        return ctx.next();
    }
}

RequestInterceptor1 requestInterceptor1 = new;

// Interceptor service class with specific path. This interceptor can only be engaged at service
// level.
service class RequestInterceptor2 {
    *http:RequestInterceptor;

    // This interceptor is only executed for GET requests with the relative path "greeting". 
    resource function get greeting(http:RequestContext ctx, 
                            http:Request req) returns http:NextService|error? {
        req.setHeader(interceptor_header2, interceptor_header_value2);
        return ctx.next();
    }
}

RequestInterceptor2 requestInterceptor2 = new;

listener http:Listener interceptorListener = new http:Listener(9090);

// Engage interceptors at service level.
@http:ServiceConfig {
    // The base path of interceptor services is same as the target service.
    interceptors: [requestInterceptor1, requestInterceptor2]
}
service /user on interceptorListener {

    resource function get greeting(http:Request req) 
            returns http:Response|error? {
        // Create a new response.
        http:Response response = new;
        // Set the interceptor headers from request
        response.setHeader(interceptor_header1, 
                            check req.getHeader(interceptor_header1));
        response.setHeader(interceptor_header2, 
                            check req.getHeader(interceptor_header2));
        response.setTextPayload("Greetings!");
        return response;
    }
}

Request interceptor at service level

When you want to engage a RequestInterceptor for a specific service path, you can engage interceptors at the service level through the ServiceConfig annotation. The interceptors engaged at the service level will have the base path same as the target service. For more information, see the HTTP module.

import ballerina/http;
final string interceptor_header1 = "X-requestHeader1";
final string interceptor_header2 = "X-requestHeader2";

Header name to be set to the request in the request interceptor.

final string interceptor_header_value1 = "RequestInterceptor1";
final string interceptor_header_value2 = "RequestInterceptor2";

Header value to be set to the request in the request interceptor.

service class RequestInterceptor1 {
    *http:RequestInterceptor;
    resource function 'default [string... path](http:RequestContext ctx, 
                            http:Request req) returns http:NextService|error? {
        req.setHeader(interceptor_header1, interceptor_header_value1);
        return ctx.next();
    }
}

Sets a header to the request inside the interceptor service.

RequestInterceptor1 requestInterceptor1 = new;
service class RequestInterceptor2 {
    *http:RequestInterceptor;

Interceptor service class with specific path. This interceptor can only be engaged at service level.

    resource function get greeting(http:RequestContext ctx, 
                            http:Request req) returns http:NextService|error? {
        req.setHeader(interceptor_header2, interceptor_header_value2);
        return ctx.next();
    }
}

This interceptor is only executed for GET requests with the relative path “greeting”.

RequestInterceptor2 requestInterceptor2 = new;
listener http:Listener interceptorListener = new http:Listener(9090);
@http:ServiceConfig {

Engage interceptors at service level.

    interceptors: [requestInterceptor1, requestInterceptor2]
}
service /user on interceptorListener {

The base path of interceptor services is same as the target service.

    resource function get greeting(http:Request req) 
            returns http:Response|error? {
        http:Response response = new;

Create a new response.

        response.setHeader(interceptor_header1, 
                            check req.getHeader(interceptor_header1));
        response.setHeader(interceptor_header2, 
                            check req.getHeader(interceptor_header2));
        response.setTextPayload("Greetings!");
        return response;
    }
}

Set the interceptor headers from request

# Run the service
bal run http_request_interceptor_at_service.bal
# Invoke the service.
curl -v http://localhost:9090/user/greeting
*   Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 9090 (#0)
> GET /user/greeting HTTP/1.1
> Host: localhost:9090
> User-Agent: curl/7.64.1
> Accept: */*
> 
< HTTP/1.1 200 OK
< X-requestHeader1: RequestInterceptor1
< X-requestHeader2: RequestInterceptor2
< content-type: text/plain
< content-length: 10
< server: ballerina
< date: Tue, 23 Nov 2021 17:16:16 +0530
< 
* Connection #0 to host localhost left intact
Greetings!* Closing connection 0