import ballerina/http;

// Service-level [CORS config](https://docs.central.ballerina.io/ballerina/http/latest/records/CorsConfig) applies
// globally to each `resource`.
@http:ServiceConfig {
    cors: {
        allowOrigins: ["http://www.m3.com", "http://www.hello.com"],
        allowCredentials: false,
        allowHeaders: ["CORELATION_ID"],
        exposeHeaders: ["X-CUSTOM-HEADER"],
        maxAge: 84900
    }
}
service /crossOriginService on new http:Listener(9092) {

    // Resource-level [CORS config](https://docs.central.ballerina.io/ballerina/http/latest/records/CorsConfig)
    // overrides the service-level CORS headers.
    @http:ResourceConfig {
        cors: {
            allowOrigins: ["http://www.bbc.com"],
            allowCredentials: true,
            allowHeaders: ["X-Content-Type-Options", "X-PINGOTHER"]
        }
    }
    resource function get company() returns json {
        return {"type": "middleware"};
    }

    // Since there are no resource-level CORS configs defined here, the global
    // service-level CORS configs will be applied to this resource.
    resource function post lang() returns json {
        return {"lang": "Ballerina"};
    }
}

CORS

This sample demonstrates the Ballerina server connector CORS configuration. CORS headers can be applied in both the service-level and the resource-level. Service-level CORS headers apply to all the resources unless there are headers configured at the resource-level. Ballerina CORS supports both simple and pre-flight requests.

For more information on the underlying module, see the HTTP module.

import ballerina/http;
@http:ServiceConfig {
    cors: {
        allowOrigins: ["http://www.m3.com", "http://www.hello.com"],
        allowCredentials: false,
        allowHeaders: ["CORELATION_ID"],
        exposeHeaders: ["X-CUSTOM-HEADER"],
        maxAge: 84900
    }
}
service /crossOriginService on new http:Listener(9092) {

Service-level CORS config applies globally to each resource.

    @http:ResourceConfig {
        cors: {
            allowOrigins: ["http://www.bbc.com"],
            allowCredentials: true,
            allowHeaders: ["X-Content-Type-Options", "X-PINGOTHER"]
        }
    }
    resource function get company() returns json {
        return {"type": "middleware"};
    }

Resource-level CORS config overrides the service-level CORS headers.

    resource function post lang() returns json {
        return {"lang": "Ballerina"};
    }
}

Since there are no resource-level CORS configs defined here, the global service-level CORS configs will be applied to this resource.

bal run http_cors.bal
[ballerina/http] started HTTP/WS listener 0.0.0.0:9092
# Run the cURL command below to send a CORS simple request. 
curl -v "http://localhost:9092/crossOriginService/company" -H "Origin:http://www.bbc.com"
> GET /crossOriginService/company HTTP/1.1
> Host: localhost:9092
> User-Agent: curl/7.64.1
> Accept: */*
> Origin:http://www.bbc.com
>
< HTTP/1.1 200 OK
< content-type: application/json
< access-control-allow-origin: http://www.bbc.com
< access-control-allow-credentials: true
< content-length: 21
< server: ballerina
<
* Connection #0 to host localhost left intact
{"type":"middleware"}* Closing connection 0
# Run the cURL command below to send a CORS preflight request. 
curl -v "http://localhost:9092/crossOriginService/lang" -X OPTIONS -H "Origin:http://www.m3.com" -H "Access-Control-Request-Method:POST"
> OPTIONS /crossOriginService/lang HTTP/1.1
> Host: localhost:9092
> User-Agent: curl/7.64.1
> Accept: */*
> Origin:http://www.m3.com
> Access-Control-Request-Method:POST
>
< HTTP/1.1 200 OK
< access-control-allow-origin: http://www.m3.com
< access-control-max-age: 84900
< access-control-allow-methods: POST
< content-length: 0
< server: ballerina
<
* Connection #0 to host localhost left intact
* Closing connection 0