import ballerina/http;endpoint http:Listener crossOriginServiceEP {
    port:9092
};
@http:ServiceConfig {
    cors: {
        allowOrigins :["http://www.m3.com", "http://www.hello.com"],
        allowCredentials : false,
        allowHeaders:["CORELATION_ID"],
        exposeHeaders : ["X-CUSTOM-HEADER"],
        maxAge : 84900
    }
}
service<http:Service> crossOriginService bind crossOriginServiceEP {
    @http:ResourceConfig {
        methods:["GET"],
        path:"/company",
        cors : {
            allowOrigins :["http://www.bbc.com"],
            allowCredentials : true,
            allowHeaders: ["X-Content-Type-Options", "X-PINGOTHER"]
        }
    }
   companyInfo (endpoint conn, http:Request req) {
        http:Response res = new;
        json responseJson = {"type":"middleware"};
        res.setJsonPayload(responseJson);
        _ = conn -> respond(res);
    }
    @http:ResourceConfig {
        methods:["POST"],
        path:"/lang"
    }
    langInfo (endpoint conn, http:Request req) {
        http:Response res = new;
        json responseJson = {"lang":"Ballerina"};
        res.setJsonPayload(responseJson);
        _ = conn -> respond(res);
    }
}

HTTP CORS

Example depicts ballerina server connector CORS configuration. CORS headers can apply in both service/resouce levels. Service level CORS headers applies to all the resources, unless it is not configured at resource level. Ballerina CORS supports for both simple and pre-flight requests.

import ballerina/http;
endpoint http:Listener crossOriginServiceEP {
    port:9092
};
@http:ServiceConfig {
    cors: {
        allowOrigins :["http://www.m3.com", "http://www.hello.com"],
        allowCredentials : false,
        allowHeaders:["CORELATION_ID"],
        exposeHeaders : ["X-CUSTOM-HEADER"],
        maxAge : 84900
    }
}
service<http:Service> crossOriginService bind crossOriginServiceEP {

Service level CORS headers applies globally for each resource

    @http:ResourceConfig {
        methods:["GET"],
        path:"/company",
        cors : {
            allowOrigins :["http://www.bbc.com"],
            allowCredentials : true,
            allowHeaders: ["X-Content-Type-Options", "X-PINGOTHER"]
        }
    }
   companyInfo (endpoint conn, http:Request req) {
        http:Response res = new;
        json responseJson = {"type":"middleware"};
        res.setJsonPayload(responseJson);
        _ = conn -> respond(res);
    }

CORS headers are defined at resource level are overrides the service level headers

    @http:ResourceConfig {
        methods:["POST"],
        path:"/lang"
    }
    langInfo (endpoint conn, http:Request req) {
        http:Response res = new;
        json responseJson = {"lang":"Ballerina"};
        res.setJsonPayload(responseJson);
        _ = conn -> respond(res);
    }
}

Service level CORS headers are applies to this resource as cors are not defined at resource level

$ ballerina run http-cors.bal
ballerina: initiating service(s) in 'http-cors.bal'
ballerina: started HTTP/WS server connector 0.0.0.0:9092
$ curl -v "http://localhost:9092/crossOriginService/company" -H "Origin:http://www.bbc.com"

simple request

< 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
{"type":"middleware"}
$ curl -v "http://localhost:9092/crossOriginService/lang" -X OPTIONS -H "Origin:http://www.m3.com" -H "Access-Control-Request-Method:POST"

preflight request

< HTTP/1.1 200 OK
< Access-Control-Allow-Origin: http://www.m3.com
< Access-Control-Allow-Methods: POST
< Access-Control-Max-Age: 84900
< Content-Length: 0