function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Marc D BehrMarc D Behr 

Sending email address in REST GET call

Hi,

I am writing a custom REST API and I can not get past the following and wanted to see if anybody had a solution.

I need to be able to lookup custom records that belong to a customer. The customer can be identified either by an externalID field or thier email address. I have a GET method written that works as follows:

     GET /services/apexrest/Thermostat/byUser/{user}
        where {user} can be either the externalID (an integer), a SF RecordID or an email address

So, if I do a GET of /services/apexrest/Thermostat/byUser/157 (157 being the externalIDI get back the thermostats that belong to user 157 exactly as expected with a 200 HTTP Status code. Sending a SF AccountID also works fine.  But, if I instead send a GET /services/apexrest/Thermostat/byUser/user@here.com I get back a HTTP Status of 404 with the message

     "The requested resource does not exist"

I tried URL encoding the string so I was sending GET /services/apexrest/Thermostat/byUser/user%40here.com to see if that was causing the issue, but I still get the same results. In the code, I added several system.debug messages so I can see what s happening and it looks like in both cases, the code runs 100% sucessfully to the end and exits cleanly, but yet I get an error only when sending the email address.

As far as I can tell, there seems to be an issue with the SF REST parsing when the URL contains the '@' sign.

Has anybody else seen this or maybe have a suggested solution?

Here is the code:
@HttpGet
	global static List<Device__c> getDevice() {
		RestRequest req = RestContext.request;
		RestResponse res = RestContext.response;
		res.statusCode = 400; //failure

		// get the parameters from the command line
 		String[] command = req.requestURI.substringAfter('Thermostat/').split('/');
 		String action = (command.size() >= 1) ? command[0] : '';
        String userID = (command.size() >= 2) ? command[1] : '';
        List<Device__c> devices = new List<Device__c>();

		if(userID == '' ) {
			return devices;
		}
		
		if(action == 'byUser') {
			res.statusCode = 200; //set return status to good
			if(userID.contains('@')) {
				devices = [Select Name, System_ID__c, Zip_Postal_Code__c From Device__c  where Customer__r.PersonEmail = :userID];
			} else if (userID.length() >= 15){
				// we received a SF ID
				devices = [Select Name, System_ID__c, Zip_Postal_Code__c From Device__c  where Customer__c = :ID.valueOf(userID)];
			} else {
				devices = [Select Name, System_ID__c, Zip_Postal_Code__c From Device__c  where Customer__r.WebCustomerID__c = :Decimal.valueof(userID)];
			}
		}
		
		return devices;
	}


Best Answer chosen by Marc D Behr
Marc D BehrMarc D Behr
After a week of working with SalesForce Support, it was determined that there is a bug in the RegEx parser that reads the incoming REST calls. The problem actually has nothing to do with the '@' sign in the email address as I suspected, but instead has to do with the parser seeing an 'extension' on the URI that it does not recognize, in my examples, the extension being '.com'.

The parser will only accept '.xml' or '.json' as 'extensions', so by having an email address at the end of the line (which will always end in some TLD), you get the error.

The workaround? Simply end the URI with a '/'. So my example of '/services/apexrest/Thermostat/byUser/user%40here.com' becomes '/services/apexrest/Thermostat/byUser/user%40here.com/' and everything is peachy fine.

All Answers

Grazitti TeamGrazitti Team
Hi,

Can you try doing URL Encode while sending the email id as Rest parameter. Most probably it is not understanding @ parameter. You can encode the email string with UTF-8 format and it should work fine.

Please Mark this as Answer if it helps you

--
Regards,
Grazitti Team
Web: www.grazitti.com
Marc D BehrMarc D Behr
Hi Grazitti Team,

As I said, I did try to encode the @ sign as %40 (/services/apexrest/Thermostat/byUser/user%40here.com) and I still get the same results :-(

Thanks anyway

Marc
Grazitti TeamGrazitti Team
Oops. I totally missed that Url encode line. I know you must have printed already but just to check that did you try to do urldecode in salesforce. It might be possible that the string userID still contains %40 and not @. Did you try to put a system.debug to print what value it contains. If it contains %40, then u can try EncodingUtil.urlDecode to decode it.



--
Regards,
Grazitti Team
Web: www.grazitti.com
Marc D BehrMarc D Behr
I added some debug code as shown:

String userID = (command.size() >= 2) ? System.Encodingutil.urlDecode(command[1], 'UTF-8') : '';
        List<Device__c> devices = new List<Device__c>();

		if(userID == '' ) {
			return devices;
		}
		
		system.debug('\n\nuserId = '+userID);

		
		if(action == 'byUser') {
			res.statusCode = 200; //set return status to good
			if(userID.contains('@')) {
				devices = [Select Name, System_ID__c, Zip_Postal_Code__c From Device__c  where Customer__r.PersonEmail = :userID];
			} else if (userID.length() >= 15){
				// we received a SF ID
				devices = [Select Name, System_ID__c, Zip_Postal_Code__c From Device__c  where Customer__c = :ID.valueOf(userID)];
			} else {
				devices = [Select Name, System_ID__c, Zip_Postal_Code__c From Device__c  where Customer__r.WebCustomerID__c = :Decimal.valueof(userID)];
			}
		}

		system.debug(devices);

		return devices;
 
Then I sent /services/apexrest/Thermostat/byUser/user%40here.com
and the debug logs showed:
08:52:30.077 (77587639)|SYSTEM_METHOD_ENTRY|[364]|System.debug(ANY)
08:52:30.077 (77616385)|USER_DEBUG|[364]|DEBUG|

userId = user@here.com

...

08:52:30.134 (134050981)|SYSTEM_METHOD_ENTRY|[377]|System.debug(ANY)
08:52:30.134 (134193221)|USER_DEBUG|[377]|DEBUG|(Device__c:{Name=Home, Zip_Postal_Code__c=63026, Id=a0HC000000VLvSbMAL}, Device__c:{Name=Home2, Zip_Postal_Code__c=03855, Id=a0HM00000083v7DMAQ}, Device__c:{Name=Home3, Zip_Postal_Code__c=03855, Id=a0HM00000083wKrMAI})
08:52:30.134 (134216130)|SYSTEM_METHOD_EXIT|[377]|System.debug(ANY)

So you can see that it decoded the address and found 3 thermostats.

What I got as a result was HTTP Status "404 Not Found" and 

[{"errorCode":"NOT_FOUND","message":"The requested resource does not exist"}]

Baffling.

 
Marc D BehrMarc D Behr
After a week of working with SalesForce Support, it was determined that there is a bug in the RegEx parser that reads the incoming REST calls. The problem actually has nothing to do with the '@' sign in the email address as I suspected, but instead has to do with the parser seeing an 'extension' on the URI that it does not recognize, in my examples, the extension being '.com'.

The parser will only accept '.xml' or '.json' as 'extensions', so by having an email address at the end of the line (which will always end in some TLD), you get the error.

The workaround? Simply end the URI with a '/'. So my example of '/services/apexrest/Thermostat/byUser/user%40here.com' becomes '/services/apexrest/Thermostat/byUser/user%40here.com/' and everything is peachy fine.
This was selected as the best answer