0

I have the following webservice and want to return a message to the user but this is not working. I would like to return the message: Sorry no match

Webservice

@RestResource(urlMapping='/SalesProduct/*')
global with sharing class WebserviceSalesproducts {
    //Test workbench: /services/apexrest/SalesProduct/test-product
        @HttpGet
        webservice static List<Sales_Product__c> getSalesproductsByProductCode() {
        RestRequest request = RestContext.request;
        RestResponse response = RestContext.response;

        List<Sales_Product__c> result= new List<Sales_Product__c>();

        String ProductCode = request.requestURI.substring(request.requestURI.lastIndexOf('/')+1);
        system.debug('ProductCode '+ ProductCode);
        try{

            Sales_Product__c  SprResult =  [SELECT id,name, Productcode__c 
                                            FROM Sales_Product__c 
                                            WHERE Productcode__c  = :ProductCode ];
            result.add(SprResult);
        }catch(exception e){
            system.debug('Error'+ e);
        }
        system.debug(result);
        if(result.size()<=0 || result.size()==null){
            response.statusCode = 204;
            response.responseBody = blob.valueOf('Sorry no match');
        }
        if(result.size()>0){
            return result;
        }else{
            return null;
        }
    }
}
1
1

/apexrest/ is a REST Resource, not a Web Service resource, which is a SOAP-based call, because you're using RestContext parameters. Your code is written in a way that it cannot be a SOAP-based call.

You should change webservice to global.


    webservice static List<Sales_Product__c> getSalesproductsByProductCode() {

...

        Sales_Product__c  SprResult =  [SELECT id,name, Productcode__c 
                                        FROM Sales_Product__c 
                                        WHERE Productcode__c  = :ProductCode ];

...

You can never return a list of products, so why do this? Either return a list of products, or return a single product.


    if(result.size()<=0 || result.size()==null){

If you need to check for null, you must do so before you check anything else. In a hypothetical API where result.size() returns null, you'd end up with null <= 0, which, depending on the API version, should either be an exception, or false, but either way, not a comparison you should be making.

That aside, List.size() will always return a zero or positive integer, never a negative number or null. There's no need to check for null here.


    webservice static List<Sales_Product__c> getSalesproductsByProductCode() {

...

        response.responseBody = blob.valueOf('Sorry no match');

You can't mix RestContext.response.responseBody and a non-void return type. Choose one or the other.


        response.responseBody = blob.valueOf('Sorry no match');

This is just bad API design. You should return a structure that allows your client code to reliably determine if there was a match or not, rather than hard-coding a string like this.

A better solution would look something like this:

global class SearchResponse {
    global Boolean resultFound = false;
    global Sales_Product__c result;
    global String errorMessage;
}

...

    @HttpGet
    global static SearchResponse getSalesproductsByProductCode() {
        SearchResponse response = new SearchResponse();

...

        return response;
    }

    try{

...

    }catch(exception e){
        system.debug('Error'+ e);
    }

This is a bad habit of getting in to. You should break this habit now. If you're not going to handle the exception, you should not catch it. If you are, you should do more than a System.debug. In this case, why not just run the query and assign it to the results list?

    List<Sales_Product__c> result = [SELECT id,name, Productcode__c 
                                        FROM Sales_Product__c 
                                        WHERE Productcode__c  = :ProductCode ];

    String ProductCode = request.requestURI.substring(request.requestURI.lastIndexOf('/')+1);

You can simplify this using the newer substringAfterLast:

    String ProductCode = request.requestURI.substringAfterLast('/');

        response.statusCode = 204;

This is the "No Content" response status code. You actually cannot include a return value if you set this status code, as it breaks the rules of 204 No Content. You'll want to look up if a different status code is appropriate.


If ProductCode__c is an External ID field, you can simply call Retrieve by External Id:

/services/data/v47.0/sobjects/Sales_Product__c/ProductCode__c/test-product

This is a standard, built-in function that does everything you're looking for, with absolutely zero server-side code.


Overall, I'd recommend the REST resource above. If you're going to insist on writing Apex, don't make your code any more complicated than it needs to be.

@RestResource(urlMapping='/SalesProduct/*')
global with sharing class WebserviceSalesproducts {
    //Test workbench: /services/apexrest/SalesProduct/LINDA-JAAR
    global class SearchResponse {
        global Boolean resultFound = false;
        global Sales_Product__c searchResult;;
        global String errorMessage;
    }
    @HttpGet
    global static SearchResponse getSalesproductsByProductCode() {
        SearchResponse result = new SearchResponse();
        String ProductCode = RestContext.request.requestURI.substringAfterLast('/');
        for(Sales_Product__c record: [SELECT Name, ProductCode__c FROM Sales_Product__c WHERE ProductCode__c = :productCode LIMIT 1]) {
            result.searchResult = record;
        }
        result.resultFound = result.searchResult != null;
        if(!result.resultFound) {
            result.errorMessage = 'Sorry no match';
        }
        return result;
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.