Connecting to Swagger-backed APIs with Clicks or Code

Integrating external APIs is core business for every developer. That means that you often write many lines of code to consume an API. To make things easier for you, we explore in this blog post how you can leverage Swagger-backed APIs in your Salesforce environment by connecting to them via clicks or code.

Swagger – an introduction

Swagger is an API specification, also known as OpenAPI, that enables developers to describe their REST APIs in a language-agnostic way. The specification contains, for example, options to document the following parts of an API:

  • Operations (get, post, put, etc.)
  • URL paths
  • Parameters (url, query, body)
  • Authentication
  • Request return values

Describing an API in this way has many advantages. First, it is human and machine readable because the descriptions are provided in JSON or YAML. You can then give the documentation to other people and they can understand how your API works, even without knowing the code. In addition, you can use tools like the Swagger code-generator (in short: codegen) to automatically create server and/or client libraries for the API, based on the JSON/YAML files.

To get an initial understanding, I recommend that you check out the Petstore definitions, which are kind of the Swagger equivalent of Hello World (Old Java devs like me will remember the petstore too):

I highly recommend that you dig into the specification on the official GitHub repository and also the OpenAPIs Initiative website for getting a good understanding on how it works and how to apply it.

Now let’s start with the first implementation approach by using clicks.

Swagger and External Services

At Dreamforce, we showed the features of External Services in beta. If you’ve signed up for a Summer ’18 pre-release org, you’ll notice that the beta tag is gone. The feature provides a declarative UI for importing Swagger definitions into your Salesforce org. The imported API operations are available in Flow, as invocable methods. See it here in action:

You can handle authentication to your external API via Named Credentials. These features allow you to communicate with external APIs quickly, even as a part of complex workflows.

Though you can do a lot without writing code, there may be times where you need to add to this functionality. Here are some reasons to move to more code:

  • Your API has inputs and outputs that need to be described with complex embedded objects.
  • You need to use custom HTTP headers when calling the API.
  • You want to use the API in existing Apex code.

Let’s look at how to solve these use cases.

Swagger and Apex

As mentioned before, the Swagger project provides a Java-based client code generator (codegen) for several programming languages. By using the codegen for Apex (Yes, that’s a thing!) you can generate the needed code automatically, including Apex tests.

To get hands-on, you can download the codegen from the official website. However, the most up-to-date implementation for Apex is in the master branch on GitHub, which is what I prefer to use as the official download is always some releases behind. Check out the instructions here to set up your environment for building from the GitHub branch.

Once the Java files are built, you execute the codegen-cli from the root of the git repository with this command:

java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jar generate -i http://petstore.swagger.io/v2/swagger.json -l apex -o ../swagger-test/

Parameter explanation:

  • -i: The location of the Swagger definition file (here: the swagger petstore example).
  • -l: The language for which the client libraries should be built.
  • -o: The output directory for the generated code, swagger-test.

After you execute the codegen, it creates all needed files within the specified output directory:

These files are:

  • Salesforce DX configuration files (project and scratch org definition)
  • Apex classes
  • Apex test classes
  • Apex class documentation in Markdown format
  • Named Credential configuration

While most Swagger client generators for other languages have built-in code to handle authentication, this has been removed from the Apex generator. This is because delegating authentication tasks to Named Credentials gives you the ability to change basic settings without affecting your code. It also lets you still handle more complex settings, like custom HTTP headers, within Apex.

However, not everyone will want to build from Java-based resources. To make it easier for more Salesforce developers to use the Apex codegen, I’ve bundled it into a new Salesforce CLI plugin.

Adding Salesforce DX to the mix

By embedding the generator into a Salesforce CLI plugin, you can leverage the functionality without building things every time from scratch. You’re also freed from waiting for a new official Swagger codegen version, as the plugin will always be updated with the most current build.

The full documentation for the plugin is available on npmjs. To install it, you issue the following Salesforce CLI command:

sfdx plugins:install muenzpraeger-sfdx-plugin

This command will fetch the plugin from npmjs and add it to your local installation. Pro tip: don’t forget to check frequently for updates for any of your installed plugins using sfdx plugins:update, so that you always have the latest version installed. 😉

Once you’ve installed the plugin you can run a Swagger import using this command:

sfdx muenzpraeger:swagger:import -p http://petstore.swagger.io/v2/swagger.json -d /Users/rwinkelmeyer/Development/testApex

The parameters are very similar to the ones that you’re (hopefully) used to from other Salesforce CLI commands. With -p you’re pointing to the Swagger definition file, which could be a local file as well as a remote URL. The -d flag specifies the target directory for the output. By providing the -h flag to the command, you are provided with a full list of available options. So you can, for example, specify if existing files should be overridden (which can be useful) or if you want to set a specific API version in the generated metadata.

Now that you know how to generate Apex code from a Swagger definition file — either using the GitHub project or the Salesforce CLI plugin — we’ll now take a look at how to use it.

Writing Swagger Apex code

Let’s walk through an example, in Apex, that works with the GET /pet/{petId} operation of the petstore example:

SwagClient client = new SwagClient();
SwagPetApi api = new SwagPetApi(client);
Map<String, Object> params = new Map<String, Object>();
Long petId = Long.valueOf('100');
params.put('petId', petId);
SwagPet pet = api.getPetById(params);

Code explanation:

  • Line 1: The SwagClient is the main class that owns authentication, using a related Named Credential, HTTP communication and so forth.
  • Line 2: For every URL junction, like /pet, a dedicated xxxApi class is generated. In this case SwagPetApi.
  • Line 3-5: If parameters are sent with the API call, you provide a Map object to the SwagPetApi class. It is important to note that you you don’t have to handle URL, query or body parameters differently — the xxxAPI class handles that.
  • Line 6: The getPetById method executes the above mentioned GET operation and returns in response a SwagPet class.

To get an idea of how the codegen generates Apex classes, see the following excerpt of the SwagPet class:

/*
 * Swagger Petstore
 * This is a sample server Petstore server.  You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/).  For this sample, you can use the api key `special-key` to test the authorization filters.
 *
 * OpenAPI spec version: 1.0.0
 * Contact: apiteam@swagger.io
 *
 * NOTE: This class is auto generated by the swagger code generator program.
 * https://github.com/swagger-api/swagger-codegen.git
 * Do not edit the class manually.
 */
/**
 * SwagPet
 */
public class SwagPet {
    /**
     * Get id
     * @return id
     */
    public Long id { get; set; }
    /**
     * Get category
     * @return category
     */
    public SwagCategory category { get; set; }
    /**
     * Get name
     * @return name
     */
    public String name { get; set; }

In this example, all generated classes are prefixed with “Swag”. This is the default value. You can set a custom prefix using the -c flag, like “Imp” in the following example.

sfdx muenzpraeger:swagger:import -c Imp -p http://petstore.swagger.io/v2/swagger.json -d /Users/rwinkelmeyer/Development/testApex

Next steps

The combination of External Services and Apex codegen give you options for how you can integrate Swagger-backed APIs into your Salesforce org. If you have to or want to use Apex, the codegen will cover many of your use cases. If something is wrong with the generated Apex classes or the Apex tests, which you’ll find out during deployment to a scratch org, you should file an issue on the Swagger GitHub repo. Or even better, create the issue and contribute the solution. I did that – so can you!

Here are also some great Trailhead modules around Apex development to check out:

About the author

René Winkelmeyer works as Principal Developer Evangelist at Salesforce. He focuses on enterprise integrations, mobile, and security with the Lightning Platform. You can follow him on Twitter @muenzpraeger.

Leave your comments...

Connecting to Swagger-backed APIs with Clicks or Code