The Salesforce Connect adapter for GraphQL requires that the GraphQL schema adhere to a specific format.
Required Editions
| Available in: both Salesforce Classic and Lightning Experience (not for high-data-volume external objects) |
|
Available in: Developer Edition Available for an extra cost in: Enterprise, Performance, and Unlimited Editions |
This is a representative schema to understand how to construct a schema that works with Salesforce Connect. Notations to understand the representative schema:
- ObjName: Denotes the name of a GraphQL object.
- Bold text: Represents the pattern to follow for each object.
- Non-bold text: Represents common code, not specific to the objects.
type Query {
objName(
limit: Int,
offset: Int,
orderBy: [ObjName_OrderByInput],
where: ObjName_FilterInput,
first: Int,
after: String
): ObjName_Connection
<additional object queries...>
node(id: ID!): Node
}
type Mutation {
create_ObjName(input: ObjName_CreateInput!): ObjName
<additional create mutations>
...
delete_ObjName(id: ID!): ObjName
<additional delete mutations>
...
update_ObjName(input: ObjName_UpdateInput!): ObjName
<additional update mutations>
...
}
type ObjName implements Node {
id: ID!
<fieldName: fieldType>
...
}
type ObjName_Connection {
edges: [ObjName_Edge]
pageInfo: PageInfo!
}
input ObjName_CreateInput {
<fieldName: fieldType>
...
}
input ObjName_UpdateInput {
id: ID!
<fieldName: fieldType>
...
}
type ObjName_Edge {
cursor: String!
node: ObjName
}
input ObjName_FilterInput {
and: [ObjName_FilterInput]
not: ObjName_FilterInput
or: [ObjName_FilterInput]
id: IDOperator
<fieldName: fieldTypeOperator>
...
}
input ObjName_OrderByInput {
id: OrderByClause
<fieldName >: OrderByClause
...
}
interface Node {
id: ID!
}
enum NullsOrder {
NULLS_FIRST
NULLS_LAST
}
input OrderByClause {
direction: Direction
nulls: NullsOrder
}
type PageInfo {
endCursor: String
hasNextPage: Boolean!
hasPreviousPage: Boolean!
startCursor: String
}
input StringOperator {
eq: String
gt: String
ge: String
in: [String]
like: String
lt: String
le: String
ne: String
nin: [String]
}
input AWSDateOperator {
eq: AWSDate
gt: AWSDate
ge: AWSDate
in: [AWSDate]
like: AWSDate
lt: AWSDate
le: AWSDate
ne: AWSDate
nin: [AWSDate]
}
input AWSDateTimeOperator {
eq: AWSDateTime
gt: AWSDateTime
ge: AWSDateTime
in: [AWSDateTime]
like: AWSDateTime
lt: AWSDateTime
le: AWSDateTime
ne: AWSDateTime
nin: [AWSDateTime]
}
input AWSJSONOperator {
eq: AWSJSON
gt: AWSJSON
ge: AWSJSON
in: [AWSJSON]
like: AWSJSON
lt: AWSJSON
le: AWSJSON
ne: AWSJSON
nin: [AWSJSON]
}
input AWSTimeOperator {
eq: AWSTime
gt: AWSTime
ge: AWSTime
in: [AWSTime]
like: AWSTime
lt: AWSTime
le: AWSTime
ne: AWSTime
nin: [AWSTime]
}
input BooleanOperator {
eq: Boolean
gt: Boolean
gebolded: Boolean
in: [Boolean]
like: Boolean
lt: Boolean
le: Boolean
ne: Boolean
nin: [Boolean]
}
enum Direction {
ASC
DESC
}
input FloatOperator {
eq: Float
gt: Float
ge: Float
in: [Float]
like: Float
lt: Float
le: Float
ne: Float
nin: [Float]
}
input IDOperator {
eq: ID
gt: ID
ge: ID
in: [ID]
like: ID
lt: ID
le: ID
ne: ID
nin: [ID]
}
input IntOperator {
eq: Int
gt: Int
ge: Int
in: [Int]
like: Int
lt: Int
le: Int
ne: Int
nin: [Int]
}
Each object must have an ID! field that’s globally
unique and this global ID must be same across all the objects. If you have multiple
fields of type ID! and there isn’t field with
id as the field name, use keyColumns qualifier to specify the global ID. See Qualifier
Options.
When an external lookup relationship represents the same lookup relationship that exists between GraphQL objects, keep in mind these considerations. The external ID field on the parent external object must match the format of the external lookup field of the child external object. In case they don’t match, use qualifiers to manage one of the following:
- Manipulate the parent external object’s external ID to match the child external lookup.
- Create a virtual column in the child external object to match the parent external ID.
It’s important that the GraphQL global ID and Salesforce external ID can be computed from one another. A possible way to structure a global ID is to use a prefix to namespace the ID and keep it unique. If the primary key of the object is composed of multiple key fields, use a delimiter to separate the prefix and the ID. If any of the key fields’ value contains the delimiter, make sure to escape the delimiter.
In this example, ObjName| is the prefix and - is the delimiter. Using | after the ObjName helps to parse
the prefix from the key composition.
id: ObjName|KEY1\-123-KEY2\-456
key1: KEY1-123
key2: KEY2-456