Overview of How to Expose Apex Classes and Methods as Rest Web Services
Published: 2022-04-14 08:35:16

In this article, you will get an overview of how to expose Apex classes and methods as REST web services. This article also helps you to know about classes & method annotations.

- Introduction to Apex Web Services
- Apex Web Services
- Exposing Web Services
- Callouts

## **Introduction to Apex Web Services**

Apex classes with business logic are exposed to web services. External apps invoke these web services and execute the business process workflows. 

External web services also can be invoked from your apex code. This invoking is performed using SOAP and WSDL services (RESTful web services). This invoking process is called Callouts.

## **Apex Web Services**

By Exposing your Apex classes & methods, you allow external applications to access your code and applications by using REST or SOAP web service operations. This can be done by adding an annotation to your Apex class with @RestResource to expose as a REST resource. 

Similarly, you can add annotations to your methods to expose them through REST. For example, @HttpGet exposes your method as a REST resource and can be called by HTTP GET request. External applications and [Salesforce integration](https://www.bolt.today/salesforce-integration-services.html) can be possible by making your methods callable through the web to perform operations like Add, Update, Delete, etc. to and from Salesforce.

## **Syntax**

To allow an external application to access your class, define it as global. Just add 'global' keyword before the class definition. Global is an access identifier that makes the class visible and it's accessible to outside of the organization.

```
@RestResource(urlMapping='/Account/*')
global class YourApexClass {
}
```

Here, in the above example, @RestResource annotation used to expose your class as a REST resource. And to form your web service endpoint URL Mapping is used.

After creating the Apex class, we will create Apex methods in the next step. These Apex methods should be annotated with @HttpGet, @HttpPost, or @HttpDelete, etc. to ensure the type of request and expose as REST resources. 

The methods defined in Apex class with identifier global must be defined as global and static. In the code snippet below we are exposing the Apex method as GET request.

```
@RestResource(urlMapping='/Account/*')
global with sharing class MyRestResource {
@HttpGet
global static Account getRecord() {
// Add your code
}
}
```

For more examples and to know more about Apex Web Services check out below URL: [Apex Web Services](https://trailhead.salesforce.com/en/content/learn/modules/apex_integration_services/apex_integration_webservices)

## **Exposing Web Services**

As mentioned earlier, Apex Web services enable an external application to access Apex classes and methods.

## **Apex REST Code Sample**

This Apex REST Code sample shows you how to implement a simple REST API in Apex with 3 HTTP request methods to delete a record, get a record, and update a record. For authentication, [Click here](https://developer.salesforce.com/docs/atlas.en-us.226.0.api_rest.meta/api_rest/quickstart.htm).

In the below code snippets, the class MyRestResource is annotated with @RestResource. And the endpoint of your web service is created using the urlMapping parameter. https://yourInstance.salesforce.com/services/apexrest/ - is the base endpoint for apex REST. 

The URL mapping is appended to the base endpoint to form the endpoint of your REST service. The URL mapping is case sensitive and it can contain the wild character which is used to match any character e.g. AccountID etc.

```
@RestResource(urlMapping='/Account/*')
global with sharing class MyRestResource {
@HttpDelete
global static void doDelete() {
RestRequest req = RestContext.request;
RestResponse res = RestContext.response;
String accountId = req.requestURI.substring(req.requestURI.lastIndexOf('/')+1);
Account account = [SELECT Id FROM Account WHERE Id = :accountId];
delete account;
}
@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;
}
@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;
}
}
```

@HttpDelete: The @HttpDelete annotation is used at the method level and enables you to expose an Apex method as a REST resource. This method is called when an HTTP DELETE request is sent, and deletes the specified resource.

To use this annotation, your Apex method must be defined as global static.

@HttpGet: The @HttpGet annotation is used at the method level and enables you to expose an Apex method as a REST resource. This method is called when an HTTP GET request is sent, and returns the specified resource.

These are some considerations when using this annotation:

- To use this annotation, your Apex method must be defined as global static.

- Methods annotated with @HttpGet are also called if the HTTP request uses the HEAD request method.

@HttpPost: The @HttpPost annotation is used at the method level and enables you to expose an Apex method as a REST resource. This method is called when an HTTP POST request is sent, and creates a new resource.

To use this annotation, your Apex method must be defined as global static.

There are two more annotations @HttpPut and @HttpPatch. Below is their description:

@HttpPut: The @HttpPut annotation is used at the method level and enables you to expose an Apex method as a REST resource. This method is called when an HTTP PUT request is sent, and creates or updates the specified resource.

To use this annotation, your Apex method must be defined as global static.

@HttpPatch: The @HttpPatch annotation is used at the method level and enables you to expose an Apex method as a REST resource. This method is called when an HTTP PATCH request is sent, and updates the specified resource.

To use this annotation, your Apex method must be defined as global static.

You can check more information about how to call REST Methods in the following link. [Click here](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_rest_code_sample_basic.htm)

## **Callouts**

Each REST callout should follow the protocol. Primarily, these callouts are based on HTTP and valid endpoint URL.

Below mentioned HTTP methods are common and can be used for REST callouts:

- GET
- POST
- DELETE
- PUT

When the server receives the request, it processes as per the logic written in the methods and returns the requested information to the recipient. This can be done using callouts. The result is returned in the response object.

## **Example**

Get the data from a service.

```
Http http = new Http();
HttpRequest request = new HttpRequest();
request.setEndpoint('https://th-apex-http-callout.herokuapp.com/animals');
request.setMethod('GET');
HttpResponse response = http.send(request);
// If the request is successful, parse the JSON response.
if (response.getStatusCode() == 200) {
// Deserialize the JSON string into collections of primitive data types.
Map<String, Object> results = (Map<String, Object>) JSON.deserializeUntyped(response.getBody());
// Cast the values in the 'animals' key as a list
List<Object> animals = (List<Object>) results.get('animals');
System.debug('Received the following animals:');
for (Object animal: animals) {
System.debug(animal);
}
}
```

Send the data to a Service

```
Http http = new Http();
HttpRequest request = new HttpRequest();
request.setEndpoint('https://th-apex-http-callout.herokuapp.com/animals');
request.setMethod('POST');
request.setHeader('Content-Type', 'application/json;charset=UTF-8');
// Set the body as a JSON object
request.setBody('{"name":"mighty moose"}');
HttpResponse response = http.send(request);
// Parse the JSON response
if (response.getStatusCode() != 201) {
System.debug('The status code returned was not expected: ' +
response.getStatusCode() + ' ' + response.getStatus());
} else {
System.debug(response.getBody());
}
```

Each REST method gets the response or accepts requests in either XML or JSON form. In short, REST web services are using JSON or XML for communicating with external apps.