[SalesForce] Hello World Custom Rest Api endpoint not working

Salesforce provides a example of how to define a custom rest endpoint and how to make calls to that endpoint. It is not working for me. Why? I have successfully retrieved an OAuth token that I have successfully used with the REST Api.

Here is the Rest class in apex:

@RestResource(urlMapping='/Account/*')
global with sharing class MyRestResource {

@HttpDelete
global static void doDelete() {
    RestRequest req = RestContext.request;
    RestResponse res = RestContext.response;
    Account account = [SELECT Id FROM Account ];
    delete account;
}

@HttpGet
global static Account doGet() {
    RestRequest req = RestContext.request;
    RestResponse res = RestContext.response;
    Account result = [SELECT Id, Name, Phone, Website FROM Account];
    return result;
}

@HttpPost
global static String doPost(String name,
    String phone, String website) {
    Account account = new Account();
    account.Name = name;
    account.phone = phone;
    account.website = website;
    insert account;
    return account.Id;
}
}

and here is some python code that I am using to make the get request:

import requests

url = 'https://na15.salesforce.com/services/apexrest/Account/001i000000VdaoqAAB'
headers = {'Authorization': 'Bearer 00Di0000000iQ.....'}
r = requests.get(url, headers=headers) 
print r.text

I am getting the following error:

[{"message":"Could not find a match for URL /Account/001i000000VdaoqAAB","errorCode":"NOT_FOUND"}]

Is there some setting that I need to enable?

Best Answer

Not sure on that error but I do see a couple of potential issues that might be causing you problems

The get is setup wrongly - when I tried that, I got an error because it is not filtering by the Id you pass in - see line highlighted below from docs that you are missing. As such, it needs to returns a list of records (the code does work when you change the return type)

@HttpGet
    global static Account doGet() {
        RestRequest req = RestContext.request;
        RestResponse res = RestContext.response;
        **String accountId = req.requestURI.substring(req.requestURI.lastIndexOf('/')+1);**
        Account result = [SELECT Id, Name, Phone, Website FROM Account WHERE Id = :accountId];
        return result;
    }

Also, I probably wouldn't name the RestResource 'Account' as that is a standard resource name...wondering if that is causing a conflict?

Update: If you have a namespace enabled for your org, then it will need to be included in the url. In your case it would be:

https://na15.salesforce.com/services/apexrest/your_namespace/Account/001i000000VdaoqAAB where "your_namespace" is the namespace of your org.

Related Topic