[SalesForce] Can we create multiple @Http Methods (REST) annotations of the same type in a single class

In REST API, can we create multiple @Http Methods (for e.g. @HttpGet) annotations of the same type in a single class? i have a need where i need to write more than one get method in the same class? is that possible and if it is how?

One of my friend started debating with me that it is possible as long as the method signatures are different. For example,

@RestResource(urlMapping='/RestResearch/v1/Test')
global with sharing class RestResearch {

@HttpGet
global static String getAllCourses(String s) {
        RestRequest req  = RestContext.request;
        RestResponse res  = RestContext.response;
        String id  = req.requestURI.substring(req.requestURI.lastIndexOf('/')+1);
        System.debug('id :'+id);
        return 'Success';
}

@HttpGet
global static String getMyCourses(String s1, String s2, String s3, String s4, String s5, String s6) {
        RestRequest req  = RestContext.request;
        RestResponse res  = RestContext.response;
        String id  = req.requestURI.substring(req.requestURI.lastIndexOf('/')+1);
        return 'Success';
}

}

But, i am getting an error "@HttpGet already used elsewhere in this class" if i tried to save it in Eclipse.

Any help is much appreciated…

Best Answer

Expanding on Mohith's answer, you may only define a single @HttpGet annotated method on your class, but, according to the docs,

Methods annotated with @HttpGet or @HttpDelete should have no parameters. This is because GET and DELETE requests have no request body, so there's nothing to deserialize.

So you should have a single REST method that examines query parameters and responds accordingly:

@RestResource(urlMapping='/RestResearch/v1/Test')
global with sharing class RestResearch {
    @HttpGet
    global static Account doGet() {
        RestRequest req = RestContext.request;
        RestResponse res = RestContext.response;

        // Was the method called like http://na1.salesforce.com/services/apexrest/RestResearch/v1/Test?s2=something
        String s2 = req.params.get('s2');
        if (s2 != null) {
            // Process s2 version
        } else {
            // Do something else
        }

        return result;
    }
}

Similarly, for a @HttpPost method, you would deserialize the body and examine it:

@HttpPost
global static String doPost(){
    RestRequest req = RestContext.request;
    RestResponse res = Restcontext.response;

    Blob body = req.requestBody;

    Map<String, Object> m = (Map<String, Object>)JSON.deserializeUntyped(body.toString());

    if (m.get('s2')) {
        // Process s2 version
    } else {
        // Do something else
    }

    return result;
}