Skip to content

Repository files navigation

Implementation Guide: Salesforce Connect adapter for GraphQL

Introduction and Goals

The purpose of this resource is to guide technical teams administering Salesforce and AWS through the process of configuring and testing the Salesforce Connect adapter for GraphQL against a known, supported configuration. Salesforce recommends customers deploy this simple (yet complete) solution to gain familiarity with all the relevant concepts, then build on that success and extend these patterns to solve for your particular target use case.

The configuration steps detailed below are sequenced so that the each element of the architecture can be validated incrementally, minimizing hassles and troubleshooting. Working step-by-step isolates potential issues, builds the team’s skills in a deliberate manner, and raises overall confidence in the solution. Follow the sequence below to maximize your success.

Overview of Configuration Steps

Since there are many steps involved, it’s helpful to have a sense for how this will progress before you begin. Here’s an overview of the process:

  1. Obtain access to an AWS account suitable for testing and experimentation
  2. Create the initial set of AWS resources by running the CloudFormation template
  3. Make note of the database name and credentials in Secrets Manager
  4. Validate the RDS configuration with a test SQL query
  5. Validate AppSync’s connection to the database with a test GraphQL query
  6. Validate the AppSync API’s authentication settings with a test HTTP call
  7. Obtain access to a Salesforce org suitable for testing and experimentation and load the sample data
  8. Define the connectivity and authentication to the GraphQL API endpoint as a Named Credential in Salesforce
  9. Create Salesforce’s representation of the External Data Source and create the External Objects via metadata sync
  10. Surface the underlying data in the Salesforce UI
  11. Attach your own database table to the GraphQL API and repeat steps 4-10 as needed

These high-level configuration steps are divided into two fundamental groupings: those performed within AWS, and those performed within Salesforce. This allows you to isolate any configuration issues and save time troubleshooting.

Note: do not proceed to the Salesforce configuration (step 7) until the AWS configuration has been validated.

AWS Configuration

1. Obtain an AWS Account

If you don’t already have an AWS account designated for development and testing, use this short guide to obtain one.

2. Create the AWS Resources via CloudFormation

To save time, the AWS resources used in this example can be created via this CloudFormation template hosted in this GitHub repository.

  • Log in to your AWS account, then navigate to CloudFormation.
  • Choose Create Stack
  • Under Prerequisite - Prepare template, choose Template is ready.
  • Under Template source, choose Upload a template file.
  • Upload AppSyncGraphRDS.yaml that you downloaded from the previous step.
  • Choose Next.
  • Provide a name for your stack. For example, GraphQLRDS.
  • You can leave the defaults for Network configuration or provide a different CIDR ranges.
  • Under Choose a deployment option choose Serverless to create a serverless RDS cluster or Standard to create a standard cluster.
  • If you chose Standard provide options under RDS Standard Mode Configuration. You can ignore these settings if you chose Serverless.
    • For RDS Instance Class, leave the default or choose a larger instance size.
    • For EC2 instance type, leave default or choose a larger instance. The EC2 instance (via Cloud9) will allow you to connect to the RDS cluster.
    • For AutoHibernateTimeout, leave the default or use a longer window. This option helps save on cost by hibernating your Cloud9 when inactive.
  • Provide the following values under RDS Serverless Mode Configuration if you chose the Serverless option. You can ignore these settings if you chose Standard option.
    • Set AutoPauseCluster to true if you wish to save cost by scaling down the capacity to 0 when idle.
    • Provide an appropriate value for SecondsUntilAutoPause (if you set AutoPauseCluster to true).
    • Set MinCapacity to desired minimum capacity of your RDS cluster.
    • Set MaxCapacity to desired maximum capacity of your RDS cluster.
  • Provide the following values under AppSync
  • Choose Next, followed by Next.
  • Acknowledge by checking the checkbox next to I acknowledge that AWS CloudFormation might create IAM resources.
  • Choose Submit.

3. Note the Database Information in Secrets Manager

  • From the AWS console, navigate to Secrets Manager, and choose the secret (it would be either /graphqlrdsserverless/dbsecret or /graphqlrds/dbsecret, depending on the configuration.)
  • Copy the ARN under Secret ARN.

4. Test RDS with a SQL Query

  • From the AWS console, navigate to RDS.
  • Choose Query Editor from the left navigation pane.
  • Choose your database cluster under Database instance or cluster
  • Under Database username choose Connect with a Secrets Manager ARN
  • Enter the ARN that you copied from the previous step ("Note the Database Information in Secrets Manager")
  • Under Enter the name of the database, enter graphqlrds
  • Run a simple query to confirm that everything is working properly. Copy/paste the statment below to save time, then click Run and view the results in the lower portion of the screen.
SELECT * FROM graphqlsample.my_order WHERE order_id = 'ORD-100';

5. Test the AppSync API with a GraphQL Query

  • From the AWS console, navigate to AWS AppSync.
  • Choose the GraphQL API that was created by CloudFormation.
  • Choose Queries from the left navigation pane.
  • Run a simple GraphQL query in the Queries console to see that the API is returning the values as expected. This example runs a query via GraphQL which is functionally the same as the SQL query in the prior step. Paste the following into the center pane and click the Execute Query button (with the arrow icon).
    • When you get more familiar with these concepts, you can use the Explorer to drill in and build up a similar query.
query MyQuery {
  graphqlsample_MyOrder(where: {OrderId: {eq: "ORD-100"}}) {
    edges {
      node {
        OrderDate
        SourceIpAddress
        CustomerId
        Status
        TotalCost
      }
    }
  }
}

After you click the Execute Query button, it may take a minute or so to see the first set of results due to Lambda's cold start. When it returns, you should see the following in the right-hand pane:

{
  "data": {
    "graphqlsample_MyOrder": {
      "edges": [
        {
          "node": {
            "OrderDate": "2022-09-13T10:10:01Z",
            "SourceIpAddress": "169.114.197.175",
            "CustomerId": "CUST-3675",
            "Status": "Placed",
            "TotalCost": 500.55
          }
        }
      ]
    }
  }
}

6. Test the API Key

Use curl (sample below) or Postman to ping the endpoint with the API key and see that auth is functioning correctly. Here, we will run the same query as the prior step, but from outside the AWS console. Again, the purpose is to validate the connectivity and authentication, since Salesforce will make a similar HTTP call to AppSync.

curl -XPOST -H "Content-Type:application/graphql" -H "x-api-key:YOUR-API-key" -d '{ "query": "query MyQuery {graphqlsample_MyOrder(where: {OrderId: {eq: \"ORD-100\"}}) {edges {node {OrderDate SourceIpAddress CustomerId Status TotalCost}}}}" }' https://YOUR-APPSYNC-ENDPOINT/graphql

You should see the following data returned (formatted here for readability):

{
  "data": {
    "graphqlsample_MyOrder": {
      "edges": [
        {
          "node": {
            "OrderDate": "2022-09-13T10:10:01Z",
            "SourceIpAddress": "169.114.197.175",
            "CustomerId": "CUST-3675",
            "Status": "Placed",
            "TotalCost": 500.55
          }
        }
      ]
    }
  }
}

Salesforce Configuration

7. Obtain a Salesforce Org and Load Sample Data

Work with your account rep to get Salesforce Connect enabled in a sandbox of your choice. Alternatively, you can sign up for a Developer Edition org or get a Salesforce org via our Trailhead learning platform.

Once the org is created and you can log in, take advantage of the sample data here to see how customer data in Salesforce can be augmented with data from external systems:

  • Create a Text field on the Account object called customerID, making sure it is marked as both an External ID and Unique.
  • Import the data the sample-customers.csv as Accounts and Contacts using the Data Import Wizard, being careful to import the first column into the new customerID field.

The sample data here is meant to represent a realistic scenario in which customer data is stored in Salesforce, but Order and Product data is in Amazon RDS. Even though there are disparate data sources, the Order table has a foreign key identifying the customer who placed the order. If this natural key can also be found in Salesforce, it can be used to create an Indirect Lookup that links Orders to Accounts.

After the AppSync is connected to Salesforce—read on to get to this step—you’ll see that the data in RDS references data imported in this step. The result is that Order data stored in AWS can be seen as a Related List on the Account page.

8. Configure the Named Credential

The AWS server resources created in the steps above need to be accessed by Salesforce acting as a client application calling out via HTTPS. This is managed by Salesforce’s Named Credentials capability, which combines the definition of a remote endpoint along with the authentication needed to call that API successfully.

To be more specific, the External Credential captures the authentication details, and the Named Credential specifies the target endpoint itself. The Named Credential holds a reference to the External Credential so that the callout subsystem knows what authentication to use for the endpoint in question.

Access Control via Permission Set

Since Salesforce is secure by default, any User that will use this credential to make a callout needs permission to do so. This is managed via Permission Sets, and for convenience, we’ll handle this first:

  • Navigate to Setup → Permission Sets.
  • Identify a Permission Set all the calling Users already have, or click New to create a new one specifically for this purpose.
    • This example will use a new Permission Set called Access External Systems. Use that as the Label, and press Tab to generate an API Name.
  • Click Save.
  • Click Manage Assignments, then Add Assignment to assign this Permission Set to your User.
  • Follow the rest of the wizard to complete the assignment.

Authentication: External Credential

You may recall that the AppSync endpoint is protected by an API key. External Credentials capture the authentication configuration, so follow these steps to set up the API key:

  • Navigate to Setup → Named Credentials and click the External Credentials subtab.
  • Click New and select Custom for the Authentication Protocol.
  • Provide a Label (API Key Auth for AppSync) and developer Name (APIKeyAuthForAppSync), making note of the developer Name you assign for a later step.
  • Click Save.

External Credential

At this point, the External Credential is created, though we need to store the API key—securely!—and link its use to the Permission Set we defined above. Here’s how that’s accomplished:

  • Under Permission Set Mappings, click New.
  • Select the Permission Set we created in the prior step (Access External Systems).
  • Under Authentication Parameters, click New.
  • Use APIKey as the Name, and paste in the API key from AppSync into the Value field.
  • Click Save.

Permission Set Mapping

This stores the API key in an encrypted manner, and links its access to the appropriate permissions. The last step for the External Credential is to configure the HTTP header AppSync expects to contain the API key. Here’s the steps:

  • Under Custom Headers, click New.
  • Enter the Name of the header required by AppSync: x-api-key.
    • This becomes the name of the header in the actual HTTP callout.
  • Enter the following formula as the Value: {!$Credential.APIKeyAuthForAppSync.APIKey}
    • This merge field syntax allows you to reference the API key without reducing security by hard-coding the secret value in clear text.
  • Click Save.

Endpoint: Named Credential

With the permissions and authentication defined, capturing the endpoint as a Named Credential is comparatively simple:

  • Navigate to Setup → Named Credentials and click the Named Credentials subtab.
  • Click New
  • Enter a descriptive Label (AppSync API) and developer Name (AppSyncAPI), then paste in the URL of the API endpoint from AppSync.
  • Select the External Credential we created in the prior step (API Key Auth for AppSync)
  • Check the checkbox to Allow Formulas in HTTP Header.
    • This ensures the formula referencing the API key will be resolved correctly, and not interpreted as literal text.
  • Click Save.

Named Credential

Credential Parameter Storage: User External Credentials

For technical reasons, credential parameters are stored in a standard object called User External Credentials. Users that make callouts with Named Credentials need Read, Create, Edit, and Delete access to this object. Make sure to grant that access via Profiles (shown below) or Permission Sets, even if the User is a System Administrator.

Granting access to User External Credentials

9. Configure the External Data Source

The AppSync API acts as an External Data Source in Salesforce, which yields one or more External Objects. Those need to be configured, though the metadata exposed via AppSync allows you to skip many tedious steps.

First, create the External Data Source:

  • Navigate to Setup → External Data Sources and click New External Data Source.
  • Enter a descriptive Label for the External Data Source (Order Mgmt API) and press Tab to generate a developer Name.
  • Choose GraphQL as the Type.
  • Select the Named Credential we created in the prior step (AppSync API).
  • Check the checkbox to allow Writable External Objects so that this data can be edited from Salesforce.
  • Click Save.

Next, we’ll use the exposed metadata to help create the External Objects:

  • Click Validate and Sync.
  • Note the table onscreen with the list of potential objects to add to Salesforce.
    • Tweak the Name and Label fields to match the screenshot below for increased readability.
  • Checkmark all three rows with the leftmost column, then click Sync.
  • Wait for the operation to complete, then note the new External Objects in the list toward the bottom of the screen.

Sync the External Data Source

10. Surface the Data in the Salesforce UI

Salesforce has access to the external data at this point, though you’ll want to take a few more steps to surface it to your end users. For the purposes of this test, edit the Customer ID field on the new Order object and click Change Field Type to make it an Indirect Lookup to the Account field linked via the Customer ID field you added to that standard object.

Once you add the Related List for Orders to the Page Layout for Account, you’ll be able to see the order data from AWS in the context of the customer. This provides a convenient view of a customer's recent orders for support agents and sellers working in Salesforce.

Order data in Salesforce

11. Attach Your Own Database Table

Once you’ve gotten the out-of-box demo working, you can think about how to surface your own RDS tables to AppSync and Salesforce.

If the tables are in the same RDS instance, you only need to do the following:

  • Update the Schema in AppSync by adding the type and input declarations for the additional table
    • Follow the pattern you see in the Graphqlsample_MyOrder type to get the syntax correct.
  • Make sure to click Save Schema to capture your updates.
  • Attach the included resolver to the query and mutations for the new table.
    • In the Resolvers section of the Schema tab in AWS AppSync console, select the query or mutation, and click Attach. In Create new resolver, select the Lambda function from the dropdown list.
    • Repeat the process to attach the resolver for all the queries and mutations defined in the GraphQL schema. For example, if Salesforce Connect can perform create, read, update and delete operations on records, you must attach the resolver four times.
  • Add additional entries in the Parameter Store in Systems Manager to specify the metadata.
    • Follow the example in /appsync/typemetadata/Graphqlsample_MyOrder and create an additional parameter for each table, including the fieldTypes, keyColumns, etc.

If you are using a different RDS instance, you’ll also need to add the RDS credentials to the Secrets Manager and set up the port forwarding so that the resolver can have a persistent connection to RDS. If you are unsure about this element of the infrastructure, contact AWS support.

After the new GraphQL type is successfully added to the API endpoint (which you should validate with curl as in step 6), you’ll need to go back to your External Data Source definition in Salesforce and Sync the metadata so that Salesforce Connect can pull in the new object(s) and fields. From there, you can decide where exactly to surface this data in the Salesforce UI.

About

Implementation Guide for the Salesforce Connect adapter for GraphQL

Resources

Stars

3 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors