NOTE: This can be very confusing at first, take your time in understanding what's happening.

Let's break down this chapter in two parts: First, we will write the entire code and call a REST API Second, we make a template to make REST API calls so we can resuse the block of code over and over again.

Part 1

Before we even write the code, we need to whitelist the doman we will be making calls to. In our case, we will be running calls to https://admin2dev.com . Head over to Setup and in Quick Find Box search for Remote Site and add new remote site.

Now that the domain is whitelisted, let's access our JSON available at https://admin2dev.com/rest/response.json . While this is a static link, this is exactly how a response would work. First, let's make a GET call from Postman and see what the response is:

{
  	"bird": {
  		"id": 1,
  		"name": "chicken",
  		"food": "wheat",
  		"product": "eggs"
  	}
  }

Let's break down this JSON:

  • We have 1 object called bird
    • It has 4 values. 1 Integer called id and 3 String called name, food and product

For this, we first write a class named Bird and declare variables named as they are in the JSON with their respective data types.

public class responseClass{

  	public class Bird {
          public Integer id;
          public String name, food, product;
      }

  }

The name of the variables must exactly match the ones in the JSON file.

Since these values are inside an object, we need to make another class that holds the object as a class:

public class responseClass{


      public class JSONResponse {
          public Bird bird;
      }

      public class Bird {
          public Integer id;
          public String name, food, product;
      }
  }

What we have done here is recreate the JSON in Apex terms. The public Bird bird defines the variable bird as a Bird class type so now it has access to id, name, food and product. This is the most important step of dealing with JSON response, as it should be structured and named exactly as the main JSON file. In the background, what we have done in Apex terms is

class Bird(){
  	Integer Id;
  	String name, food, product;
  }

I usually name the parent class JSONResponse because that's the class we will be using to navigate our JSON response.

Now we make a method, where we build and make our HTTP request:

Http http = new Http();
  HttpRequest request = new HttpRequest();

  request.setEndpoint('https://admin2dev.com/rest/response.json');
  request.setMethod('GET');

Now we need to make the request and store it in a HttpResponse type variable:

HttpResponse response = http.send(request);

Now our class should look something like this:

public class responseClass {

      public class JSONResponse {
          public Bird bird;
      }

      public class Bird {
          public Integer id;
          public String name, food, product;
      }

      public static String methodName() {


          Http http = new Http();
          HttpRequest request = new HttpRequest();

          request.setEndpoint('https://admin2dev.com/rest/response.json');
          request.setMethod('GET');

          HttpResponse response = http.send(request);

      }
  }

Great! Now that we have made the call and saved the response, we need to navigate the JSON. This process is called JSON Deserialization where we get values from the JSON and store it in variables.

For this, we make a new variable of type JSONResponse, and type cast the response to JSONResponse type (if you forgot, take a look back on Day 10).

JSONResponse result = (JSONResponse) JSON.deserialize(response.getBody(), JSONResponse.class);

Now we get to our value by using result variable that contains our deserialized JSON, followed by the JSONResponse variable bird, followed by the key we are trying to access:

return result.bird.name;

Our end code should look something like this:

public class responseClass {

      public class JSONResponse {
          public Bird bird;
      }

      public class Bird {
          public Integer id;
          public String name, food, product;
      }

      public static String methodName() {


          Http http = new Http();
          HttpRequest request = new HttpRequest();
          request.setEndpoint('https://admin2dev.com/rest/response.json');
          request.setMethod('GET');
          HttpResponse response = http.send(request);

          JSONResponse result = (JSONResponse) JSON.deserialize(response.getBody(), JSONResponse.class);
          return result.bird.name;

      }
  }

So here's what we did:

  • Made a JSONResponse class that holds the JSON Object
  • Made a class named after the JSON Object (Bird) that holds the values
  • Made a method to:
    • First make the HTTP Call
    • Built a HTTP Request with what and where we are making the call
    • Stored the HTTP Response
    • Made a variable that holds the response when it's deserialized
    • Navigated the result and returned it

While this is a lot to digest, let's turn it into a snippet, a template of sorts that can be reused like fill in the blanks.

Part 2

It is possible to pretty much avoid writing so much code. This is why every efficient developer creates their set of snippets they use. Over the years, I personally have built snippets for my iOS / macOS apps (Swift), AI (Python) and Apex / Visualforce components. Let's see how to turn this specific code into a snippet:

public class responseClass {

      public class JSONResponse { //create JSON structure class
      	//Define values as is with data types
      	//Ensure name of the variables matches the JSON keys
      }

  	public static String methodName() {

          //Make the Request and save it

          String requestURL = 'http://url-goes-here.com/';
          String requestType = 'GET'; //GET POST PATCH PUT DELETE

          Http http = new Http();
          HttpRequest request = new HttpRequest();
          request.setEndpoint(requestURL);
          request.setMethod(requestType);
          HttpResponse response = http.send(request);

          // Deserialize based on result type class
          JSONResponse result = (JSONResponse) JSON.deserialize(response.getBody(), JSONResponse.class);
          return result.JSONObject.Key_Name //Replace JSONObject with value from JSONResponse and Key_Name with the key you're accessing in the said JSON

     }
  }

Now this snippet is a simple copy paste away to making a call to simple JSON File. You'll notice how a lot of the code that we wrote was bunch of code that was as is, meaning we don't really need to remember what we're doing here, and can be turned into a template or a snippet to get things done. In this particular example, we only need to update the JSONResponse, requestURL, requestType and the return value at the end, which is much simpler than remembering to define HTTP variables and calling and saving responses over and over again.

Making snippets is really important since it reduces your work load by a chunk, letting you reuse your code through multiple orgs without having to modify much. It is still, however, important to know what each line of code does and properly comment your code so at a later date if there are any changes to the way Apex works, it's easy to update your snippet library.

I have my snippet library stored and organized in my private repo that I usually refer to, which now is open sourced and available with documentation at https://github.com/Admin2Dev/apex-snippets that covers commonly used classes along with tests! Feel free to fork the code which allows you to copy the code in your github repo and make changes to it!

Let's try with a new JSON response! Here's the URL: https://admin2dev.com/rest/response2.json . Use the snippet above to return any value from the response. Incase you get stuck, here's the JSON and the code:

First, we use Postman to get the JSON:

{
  	"animal": {
  		"name": "cow",
  		"food": "grass",
  		"product": "milk"
  	}
  }

Now we copy paste the snippet and change the class name:

public class httpResponseClass {

      public class JSONResponse { //create JSON structure class
      	//Define values as is with data types
      	//Ensure name of the variables matches the JSON keys
      }

  	public static String methodName() {

          //Make the Request and save it

          String requestURL = 'http://url-goes-here.com/';
          String requestType = 'GET'; //GET POST PATCH PUT DELETE

          Http http = new Http();
          HttpRequest request = new HttpRequest();
          request.setEndpoint(requestURL);
          request.setMethod(requestType);
          HttpResponse response = http.send(request);

          // Deserialize based on result type class
          JSONResponse result = (JSONResponse) JSON.deserialize(response.getBody(), JSONResponse.class);
          return result.JSONObject.Key_Name //Replace JSONObject with value from JSONResponse and Key_Name with the key you're accessing in the said JSON

     }
  }

Now we build our JSON structure and store it

public class JSONResponse{
  	public Animal animal;
  }
  public class Animal{
  	String name, food, product;
  }

Now we update the requestURL to https://admin2dev.com/rest/response2.json, JSONObject to animal and KEY_NAME_GOES_HERE to name, food or product. The final code for this would be:

public class httpResponseClass {

      public class JSONResponse{
      	public Animal animal;
  	}
  	public class Animal{
  		String name, food, product;
  	}

  	public static String methodName() {

          //Make the Request and save it

          String requestURL = 'https://admin2dev.com/rest/response2.json';
          String requestType = 'GET'; //GET POST PATCH PUT DELETE

          Http http = new Http();
          HttpRequest request = new HttpRequest();
          request.setEndpoint(requestURL);
          request.setMethod(requestType);
          HttpResponse response = http.send(request);

          // Deserialize based on result type class
          JSONResponse result = (JSONResponse) JSON.deserialize(response.getBody(), JSONResponse.class);
          return result.animal.name; //Replace JSONObjec with value from JSONResponse and Key_Name with the key you're accessing in the said JSON

     }
  }

Summary

  • It's important to have JSON Keys named exactly in vairables.
  • There are multiple ways to deserialize a JSON but we cover it here by creting classes becuase it gives us clarity on JSON Structure.
Day 23: REST API Class, Mock Class and Test Class