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
Denis O'LearyDenis O'Leary 

Apex Rest Error

Hi,

Can some one help with my next steps on an Apex Rest Class? 

I have the following class: 
public with sharing class AccountToFACustomer {
    
    public class Response{
        public integer code {get; set;}
        public String body {get; set;}
        public boolean success {get; set;}
        public String errorText {get; set;}
        
        public Response (integer code, String body){
                this.code = code;
        		this.body = body;
        		this.success = (code == 200 || code == 201);
        }
    }
	
    public class customerResponse{
        
        public string uuid {get; set;}
        public string link {get; set;}
        public string location {get; set;}
    }
    
    public Response CreateCustomer (string description){
        
        Response resp;
        
        string endpoint = 'https://apistaging.website.net/';
        string token = 'Token XXXXXX';
        string method = 'POST';
        
        HttpRequest req = new HttpRequest();
        HttpResponse res = new HttpResponse();
        Http h = new http();
        
        req.setEndpoint(endpoint);
        req.setMethod(method);
        req.setHeader('Autorization', token);
		req.setHeader('Content-Type', 'application/json');
        req.setHeader('Accept-Type', 'application/json');
        
        req.setBody(
            '{"name":"'+ Account.Name +'",' +
            '"email":"'+ Account.Email__c + '",'+
             '"phone":"'+ Account.Phone +'",'+
             '"website":"'+ Account.Website +'",'+
             '"location":{'+
                 	'"name":"Account No: '+ Account.Sage_ID__c +'",'+
                    '"streetName":"'+ Account.BillingStreet +'",'+
                    '"locality":"'+ Account.BillingCity +'",'+
                    '"postcode":"'+ Account.BillingState +'",'+
                    '"country":"'+ Account.BillingCountry +'" }}' 
        );
        try{
            
		res = h.send(req);
        resp = new Response(res.getStatusCode(), res.getBody()); 
            
            if (resp.success) {
                customerResponse custResp = (customerResponse)JSON.deserialize(res.getBody(), customerResponse.class);
            }
            
        }
        	 catch(System.CalloutException e) {
   				 System.debug('Callout error: '+ e);
           		 return resp;
        }        
        return resp;   
    
    }
}

And i'm using a blank visualforce page to run the class when a button is pushed: 
 
<apex:page standardController="Account" action="AccountToFACustomer" >
    
</apex:page>

When I push the button i get the following error: Formula Expression is required on the action attributes. 

Is the blank VF page ok, or should i have more detail in here? 
Best Answer chosen by Denis O'Leary
James LoghryJames Loghry
This isn't an Apex REST error as your title suggests, but more of a Visualforce markup error.

Looks like you have your attributes a bit mixed up.  Action should point to a method in your apex class, that gets kicked off as the page loads.  I don't see any method named "AccountToFACustomer" in your class.  Instead, it looks like you want to use the "AccountToFACustomer" as an extension class.

You'll need to do a few things.

1) Add an extension controller to your class like I did around line 3 in the example below:
 
public with sharing class AccountToFACustomer {

    public AccountToFACustomer(ApexPages.StandardController sc){
    }
    
    public class Response{
        public integer code {get; set;}
        public String body {get; set;}
        public boolean success {get; set;}
        public String errorText {get; set;}
        
        public Response (integer code, String body){
                this.code = code;
        		this.body = body;
        		this.success = (code == 200 || code == 201);
        }
    }
	
    public class customerResponse{
        
        public string uuid {get; set;}
        public string link {get; set;}
        public string location {get; set;}
    }
    
    public Response CreateCustomer (string description){
        
        Response resp;
        
        string endpoint = 'https://apistaging.website.net/';
        string token = 'Token XXXXXX';
        string method = 'POST';
        
        HttpRequest req = new HttpRequest();
        HttpResponse res = new HttpResponse();
        Http h = new http();
        
        req.setEndpoint(endpoint);
        req.setMethod(method);
        req.setHeader('Autorization', token);
		req.setHeader('Content-Type', 'application/json');
        req.setHeader('Accept-Type', 'application/json');
        
        req.setBody(
            '{"name":"'+ Account.Name +'",' +
            '"email":"'+ Account.Email__c + '",'+
             '"phone":"'+ Account.Phone +'",'+
             '"website":"'+ Account.Website +'",'+
             '"location":{'+
                 	'"name":"Account No: '+ Account.Sage_ID__c +'",'+
                    '"streetName":"'+ Account.BillingStreet +'",'+
                    '"locality":"'+ Account.BillingCity +'",'+
                    '"postcode":"'+ Account.BillingState +'",'+
                    '"country":"'+ Account.BillingCountry +'" }}' 
        );
        try{
            
		res = h.send(req);
        resp = new Response(res.getStatusCode(), res.getBody()); 
            
            if (resp.success) {
                customerResponse custResp = (customerResponse)JSON.deserialize(res.getBody(), customerResponse.class);
            }
            
        }
        	 catch(System.CalloutException e) {
   				 System.debug('Callout error: '+ e);
           		 return resp;
        }        
        return resp;   
    
    }
}

And 2) Update your VF page to use the extension instead of an invalid action:
 
<apex:page standardController="Account" extensions="AccountToFACustomer" >
    
</apex:page>

 

All Answers

James LoghryJames Loghry
This isn't an Apex REST error as your title suggests, but more of a Visualforce markup error.

Looks like you have your attributes a bit mixed up.  Action should point to a method in your apex class, that gets kicked off as the page loads.  I don't see any method named "AccountToFACustomer" in your class.  Instead, it looks like you want to use the "AccountToFACustomer" as an extension class.

You'll need to do a few things.

1) Add an extension controller to your class like I did around line 3 in the example below:
 
public with sharing class AccountToFACustomer {

    public AccountToFACustomer(ApexPages.StandardController sc){
    }
    
    public class Response{
        public integer code {get; set;}
        public String body {get; set;}
        public boolean success {get; set;}
        public String errorText {get; set;}
        
        public Response (integer code, String body){
                this.code = code;
        		this.body = body;
        		this.success = (code == 200 || code == 201);
        }
    }
	
    public class customerResponse{
        
        public string uuid {get; set;}
        public string link {get; set;}
        public string location {get; set;}
    }
    
    public Response CreateCustomer (string description){
        
        Response resp;
        
        string endpoint = 'https://apistaging.website.net/';
        string token = 'Token XXXXXX';
        string method = 'POST';
        
        HttpRequest req = new HttpRequest();
        HttpResponse res = new HttpResponse();
        Http h = new http();
        
        req.setEndpoint(endpoint);
        req.setMethod(method);
        req.setHeader('Autorization', token);
		req.setHeader('Content-Type', 'application/json');
        req.setHeader('Accept-Type', 'application/json');
        
        req.setBody(
            '{"name":"'+ Account.Name +'",' +
            '"email":"'+ Account.Email__c + '",'+
             '"phone":"'+ Account.Phone +'",'+
             '"website":"'+ Account.Website +'",'+
             '"location":{'+
                 	'"name":"Account No: '+ Account.Sage_ID__c +'",'+
                    '"streetName":"'+ Account.BillingStreet +'",'+
                    '"locality":"'+ Account.BillingCity +'",'+
                    '"postcode":"'+ Account.BillingState +'",'+
                    '"country":"'+ Account.BillingCountry +'" }}' 
        );
        try{
            
		res = h.send(req);
        resp = new Response(res.getStatusCode(), res.getBody()); 
            
            if (resp.success) {
                customerResponse custResp = (customerResponse)JSON.deserialize(res.getBody(), customerResponse.class);
            }
            
        }
        	 catch(System.CalloutException e) {
   				 System.debug('Callout error: '+ e);
           		 return resp;
        }        
        return resp;   
    
    }
}

And 2) Update your VF page to use the extension instead of an invalid action:
 
<apex:page standardController="Account" extensions="AccountToFACustomer" >
    
</apex:page>

 
This was selected as the best answer
Denis O'LearyDenis O'Leary
These changes do let the visualforce page run without an error but i'm not getting the expected results of the post request in my 3rd party app...