GraphQL is another format to use when making requests to FlexDeploy servers. To get started you will need to download a way to make GraphQL Requests to your FlexDeploy server. Throughout this example we will be using Postman in order to send out GraphQL requests. a different type of REST request you can use on FlexDeploy servers. It’s main advantage over traditional REST Endpoints is its ability for a user to define exactly the data they want in a request. The request will only retrieve the data selected in a request. This can lead to better response times and more customizable data retrieval from an server. To get started, a tool is needed in in order to send requests to your FlexDeploy server. Several options exist like curl or other REST clients, but we will be using a Postman in order to send out GraphQL requests in this example.
Table of Contents | ||||
---|---|---|---|---|
|
Making a Request
First, there are some steps in postman that need to be done before writing a request.
Create an HTTP Request
Make sure the Request is a POST request
Set the URL to the format below, replacing the FLEXDEPLOY_SERVER_HOSTNAME and FLEXDEPLOY_SERVER_PORT with your FlexDeploy server’s hostname and port respectively
http(s)://{{FLEXDEPLOY_SERVER_HOSTNAME}}:{{FLEXDEPLOY_SERVER_PORT}}/flexdeploy/rest/v2/graphql
Set up security information under the “Authorization” tab. Either Basic Auth (username and password) or a token can be used here
Under the “Body” tab of the request, switch the body format to GraphQL by clicking on the dot next to “GraphQL”
...
After that is done we can now start to create our request. An example request is provided below.
...
language | graphql |
---|
...
Fetching Schema and Introspection
A GraphQL schema is a complete outline of what data is available when sending a query to the server. In order to learn what data is available when making a request, the schema can be fetched from the server. Postman will automatically fetch the schema from the server and use it in autocomplete help when writing queries. Otherwise, an Introspection Query can provide a list of queries accessible in our schema if this Auto-fetch feature is unavailable .
...
To have Postman give suggestions for your query, press Ctrl + Space to bring up the autocomplete box.
...
Query
After you have created a request and loaded the schema, we can start to write our query. There are a few key parts to a query which we’ll dive into with the example below.
Code Block | ||
---|---|---|
| ||
query envState($where: [WhereInput], $sort: [SortInput], $page: PageInput) { reportEnvironmentState(where: $where, sort: $sort, page: $page) { items { endTime environmentName executionStatus externalTicket instanceName objectPath packageName partialDeployments projectName projectVersionName projectWorkflowType relName relSnapshot scmRevision startTime streamName workflowExecutionId workflowRequestId } } } |
Variables
There are three main variables to use with FlexDeploy GraphQL queries: We can see that we are getting information about the reportEnvironmentState (Environment State Report) in this query. This query has three variables (where, sort, and page) and is selecting quite a few fields in the “items” section to return when it executes.
...
...
Description
...
Object Definition
...
where: [WhereInput]
...
This allows you to filter the data like a where clause in an SQL query. Where is an array so multiple individual WhereInput objects can be linked together to filter the query.
field: GraphQL field being filtered
type: The comparison being preformed. For example, ‘eq’ represents equals and ‘eqi’ represents equals ignoring case.
innerWhere: Similar to a subselect in SQL where prefiltering of a query could be done
value: The value you are filtering by
...
Code Block | ||
---|---|---|
| ||
input WhereInput {
field: String!
type: WhereTypeEnum!
innerWhere: [WhereInput!]
value: String
}
enum WhereTypeEnum {
eq
ne
eqi
gt
lt
inc
inci
ninc
btwn
rel
empty
nempty
} |
...
sort: [SortInput]
...
This allows you to sort the data like a order by clause in an SQL query. Sort is an array so multiple individual SortInput objects can be linked together to sort the query.
field: GraphQL field being sorted
direction: the direction of sort being preformed with asc meaing ascending order and desc meaning descending order.
Code Block | ||
---|---|---|
| ||
input SortInput {
field: String!
direction: SortEnum
}
enum SortEnum {
asc
desc
} |
...
page: PageInput
...
Page input contains extra options for the block of data that is returned by the query.
limit: The number of items in the block being returned. By default, a limit of 50 items are returned by the query. This can be overridden by the page limit to return a different amount of items.
offset: Offsets the block of data being returned by the set value. For example, a limit of 20 and an offset of 4 would return items 4 through 23.
Code Block | ||
---|---|---|
| ||
input PageInput {
limit: Int
offset: Int
} |
All of the above variables object above are then bundled together in on variable object. It is not required to always include all three variables in the object. For example, if you wanted to only filter and not sort, you would only need to include the where variable. Below is an example of the combined variable object with all three variables used.
...
Selection Set
The biggest difference between GraphQL and other, more traditional, REST requests are the optional selection of elements to be returned in a query. This can make queries return faster if only the information that is needed by the query is returned. This is called a subselection set. In our example we can see we have this block of text:
Code Block |
---|
items {
endTime
environmentName
executionStatus
externalTicket
instanceName
objectPath
packageName
partialDeployments
projectName
projectVersionName
projectWorkflowType
relName
relSnapshot
scmRevision
startTime
streamName
workflowExecutionId
workflowRequestId
} |
Here is where we can control what is being returned in the query. GraphQL will only return fields present in the subselection. For example, If I only wanted Package Name, Project Name, and Project Version Name to be returned, I could alter our previous example to something like this:
Code Block |
---|
query envState($where: [WhereInput], $sort: [SortInput], $page: PageInput) {
reportEnvironmentState(where: $where, sort: $sort, page: $page) {
items {
packageName
projectName
projectVersionName
}
}
} |
Response
Code Block |
---|
{
"data": {
"reportEnvironmentState": {
"items": [
{
"packageName": null,
"projectName": "RESTDeployProject1",
"projectVersionName": "1.0.30566"
},
{
"packageName": null,
"projectName": "RESTDeployProject1",
"projectVersionName": "1.0.30577"
},
]
}
}
} |
Variables
There are three main variables to use with FlexDeploy GraphQL queries: where, sort, and page.
Variable Name | Description | Object Definition | |||||
---|---|---|---|---|---|---|---|
where: [WhereInput] | This allows you to filter the data like a where clause in an SQL query. Where is an array so multiple individual WhereInput objects can be linked together to filter the query. field: GraphQL field being filtered type: The comparison being preformed. eq - equal ne - not equal eqi - equal (Ignores Case) gt - greater than lt - less than inc - includes inci - includes (Ignores Case) ninc - does not include empty - empty nempty - not empty innerWhere: Similar to a subselect in SQL where prefiltering of a query could be done value: The value you are filtering by |
| |||||
sort: [SortInput] | This allows you to sort the data like a order by clause in an SQL query. Sort is an array so multiple individual SortInput objects can be linked together to sort the query. field: GraphQL field being sorted direction: the direction of sort being preformed with asc meaing ascending order and desc meaning descending order. |
| |||||
page: PageInput | Page input contains extra options for the block of data that is returned by the query. limit: The number of items in the block being returned. By default, a limit of 50 items are returned by the query. This can be overridden by the page limit to return a different amount of items. offset: Offsets the block of data being returned by the set value. For example, a limit of 20 and an offset of 4 would return items 4 through 23. |
|
All of the above variables object above are then bundled together in on variable object. It is not required to always include all three variables in the object. For example, if you wanted to only filter and not sort, you would only need to include the where variable. Below is an example of the combined variable object with all three variables used.
Code Block |
---|
{
"sort": [
{
"field": "projectName",
"direction": "asc"
}
],
"where": [
{
"field": "environmentName",
"type": "eqi",
"value": "QA"
},
{
"field": "projectWorkflowType",
"type": "eq",
"value": "DEPLOY"
}
],
"page": {
"limit": 20
}
} |
Executing A Query
Combing everything we talked about this far (creating a HTTP Request, queries, and variables), we are now able to execute a query.
...
Once a query is configured inside your software of choice to make HTTP requests, just press the “Send” or “Execute” button to send out your HTTP Request.
Example Queries:
Here are are few more examples of queries that you can use with FlexDeploy. See “Fetching Schema and Introspection” above for information on how to get our full schema.
Environment History Report With File Details
This is querying the history of an environment called “Build” with file details being returned. We have a where variable below being used to only filter for the Build environment.
Code Block |
---|
query reportHistoryFiles($where: [WhereInput], $sort: [SortInput], $page: PageInput) {
reportEnvironmentHistoryFileDetails(where: $where, sort: $sort, page: $page) {
items {
allFilesRequested
cmsTicketIds
endTime
environmentId
environmentName
executionStatus
folderId
instanceId
instanceName
workItemIds
objectPath
packageName
partialDeployments
pkgStatus
poScmRevision
projectId
projectName
projectVersionName
relDefinitionId
relName
relSnapshot
relSnapshotId
requestedBy
requestedOn
scmRevision
sequenceNumber
stageExecId
startTime
streamName
workflowExecutionId
workflowId
workflowRequestId
workflowType
workflowVersion
}
}
}
|
Variables
Code Block |
---|
{
"where": [
{
"field": "environmentName",
"type": "eqi",
"value": "build"
}
],
"page": {
"limit": 2
}
} |
Response
Code Block |
---|
{
"data": {
"reportEnvironmentHistoryFileDetails": {
"items": [
{
"projectName": "RESTDeployProject1",
"environmentName": "Build",
"instanceName": "Project Rest Test Instance 1",
"workflowExecutionId": 6114897,
"executionStatus": "Success",
"workflowType": "DEPLOY",
"streamName": "trunk",
"projectVersionName": "1.0.30577",
"packageName": "",
"objectPath": null,
"objectType": null,
"poScmRevision": null,
"projectId": 759143,
"subComponentName": null,
"subComponentType": null,
"requestedOn": 1683228165127,
"pkgStatus": null,
"partialDeployments": "N",
"sequenceNumber": null,
"stageExecId": null,
"relName": null,
"relSnapshot": null,
"relStatus": null,
"environmentId": 10050,
"instanceId": 45664,
"scmRevision": null,
"workItemIds": null,
"cmsTicketIds": null,
"startTime": 1683228167140,
"endTime": 1683228167234,
"duration": 94,
"folderId": 759142,
"folderName": "SoapUI Testing",
"workflowName": "Deploy No Action",
"relDefinitionId": null,
"relSnapshotId": null,
"pipelineName": null,
"workflowId": 83363,
"workflowRequestId": 1190158,
"workflowVersion": "1.2"
},
{
"projectName": "RESTDeployProject1",
"environmentName": "Build",
"instanceName": "Project Rest Test Instance 1",
"workflowExecutionId": 6114898,
"executionStatus": "Success",
"workflowType": "DEPLOY",
"streamName": "trunk",
"projectVersionName": "1.0.30577",
"packageName": "",
"objectPath": null,
"objectType": null,
"poScmRevision": null,
"projectId": 759143,
"subComponentName": null,
"subComponentType": null,
"requestedOn": 1683228163189,
"pkgStatus": null,
"partialDeployments": "N",
"sequenceNumber": null,
"stageExecId": null,
"relName": null,
"relSnapshot": null,
"relStatus": null,
"environmentId": 10050,
"instanceId": 45664,
"scmRevision": null,
"workItemIds": null,
"cmsTicketIds": null,
"startTime": 1683228167138,
"endTime": 1683228167218,
"duration": 80,
"folderId": 759142,
"folderName": "SoapUI Testing",
"workflowName": "Deploy No Action",
"relDefinitionId": null,
"relSnapshotId": null,
"pipelineName": null,
"workflowId": 83363,
"workflowRequestId": 1190157,
"workflowVersion": "1.0"
}
]
}
}
} |
Environment History Report Without File Details
This is querying the history of an environment called “Development” with file details not being returned.
Code Block |
---|
query reportHistoryNoFiles($where: [WhereInput], $sort: [SortInput], $page: PageInput) { reportEnvironmentHistoryNoFileDetails(where: $where, sort: $sort, page: $page) { items { allFilesRequested cmsTicketIds endTime environmentId environmentName executionStatus folderId instanceId instanceName "field": "environmentName",workItemIds objectPath "type": "eqi", packageName "value": "QA" }, partialDeployments { pkgStatus "field": "projectWorkflowType", poScmRevision "type": "eq", projectId "value": "DEPLOY" projectName } ],projectVersionName "page": { relDefinitionId limit: 20 } } |
Selection Set
The biggest difference between GraphQL and REST is the option selection of elements to be returned in a query. This can make queries return faster if only the information that is needed by the query is returned. This is called a subselection set. In our above example we can see we have this block of text:
Code Block |
---|
items { relName relSnapshot endTime relSnapshotId environmentName requestedBy executionStatus requestedOn externalTicket scmRevision instanceName sequenceNumber objectPath stageExecId packageName startTime partialDeployments streamName projectName workflowExecutionId projectVersionName workflowId projectWorkflowType workflowRequestId relName workflowType relSnapshot workflowVersion } scmRevision } } |
Variables
Code Block |
---|
{ "where": [ startTime { streamName "field": "environmentName", workflowExecutionId "type": "eqi", workflowRequestId } |
Here is where we can control what is being returned in the query. GraphQL will only return fields present in the subselection. For example, If i only wanted Package Name, Project Name and Project Version Name to be returned, I could alter our previous example to something like this:
Code Block |
---|
query envState($where: [WhereInput], $sort: [SortInput], $page: PageInput) { reportEnvironmentState(where: $where, sort: $sort, page: $page) {"value": "development" } ], "page": { "limit": next2 } } |
Response
Code Block |
---|
{ hasMore "data": { items { "reportEnvironmentHistoryNoFileDetails": { packageName "items": [ projectName { projectVersionName } } } |
Example Queries:
Here are are few more examples of queries that you can use with FlexDeploy. To get a full list of queries, some software used to execute queries like postman can give auto correct advice by fetching out GraphQL schema automatically. Otherwise, an Introspection Query can provide a list of queries accessible in our schema.
Environment History Report With File Details
Code Block |
---|
query envState($where: [WhereInput], $sort: [SortInput], $page: PageInput) { reportEnvironmentHistoryFileDetails(where: $where, sort: $sort, page: $page) { "allFilesRequested": "N", "cmsTicketIds": null, "endTime": 1683228177100, "environmentId": 10051, next hasMore items { "environmentName": "Development", allFilesRequested "executionStatus": "Success", buildFlexField1 buildFlexField10 "folderId": 759142, buildFlexField2 buildFlexField3 "instanceId": 21888, buildFlexField4 "instanceName": "RESTServer", buildFlexField5 buildFlexField6 "workItemIds": null, buildFlexField7 buildFlexField8 "objectPath": null, buildFlexField9 "packageName": "", cmsTicketIds endTime "partialDeployments": "N", environmentId environmentName "pkgStatus": null, executionStatus flexField1"poScmRevision": null, flexField10 "projectId": 759143, flexField2 flexField3 "projectName": "RESTDeployProject1", flexField4 flexField5 "projectVersionName": "1.0.30577", flexField6 "relDefinitionId": 27201, flexField7 flexField8 "relName": "REST Release 1", flexField9 folderId "relSnapshot": "05-04-2023 14:22:47", instanceId instanceName "relSnapshotId": 939685, workItemIds "requestedBy": "stepworker", objectPath packageName "requestedOn": 1683228173402, partialDeployments pkgStatus "scmRevision": null, poScmRevision "sequenceNumber": null, projectId projectName "stageExecId": 939691, projectVersionName relDefinitionId "startTime": 1683228177087, relName relSnapshot"streamName": "trunk", relSnapshotId "workflowExecutionId": 6115046, requestedBy requestedOn "workflowId": 83363, scmRevision sequenceNumber "workflowRequestId": 1190160, stageExecId "workflowType": "DEPLOY", startTime streamName "workflowVersion": "1.2" workflowExecutionId }, workflowId workflowRequestId { workflowType "allFilesRequested": "N", workflowVersion } } } |
Environment History Report Without File Details
Code Block |
---|
query envState($where: [WhereInput], $sort "cmsTicketIds": [SortInput]null, $page: PageInput) { reportEnvironmentHistoryNoFileDetails(where: $where, sort: $sort, page: $page) { "endTime": 1683228177233, next hasMore items { "environmentId": 10051, allFilesRequested "environmentName": "Development", buildFlexField1 buildFlexField10 "executionStatus": "Success", buildFlexField2 buildFlexField3 "folderId": 759142, buildFlexField4 "instanceId": 45664, buildFlexField5 buildFlexField6 "instanceName": "Project Rest Test Instance 1", buildFlexField7 buildFlexField8 "workItemIds": null, buildFlexField9 cmsTicketIds "objectPath": null, endTime "packageName": "", environmentId environmentName "partialDeployments": "N", executionStatus flexField1 "pkgStatus": null, flexField10 "poScmRevision": null, flexField2 flexField3 "projectId": 759143, flexField4 flexField5 "projectName": "RESTDeployProject1", flexField6 flexField7"projectVersionName": "1.0.30577", flexField8 "relDefinitionId": 27201, flexField9 folderId "relName": "REST Release 1", instanceId instanceName "relSnapshot": "05-04-2023 14:22:47", workItemIds objectPath"relSnapshotId": 939685, packageName "requestedBy": "stepworker", partialDeployments pkgStatus "requestedOn": 1683228173402, poScmRevision projectId "scmRevision": null, projectName "sequenceNumber": null, projectVersionName relDefinitionId "stageExecId": 939691, relName relSnapshot "startTime": 1683228177188, relSnapshotId requestedBy"streamName": "trunk", requestedOn "workflowExecutionId": 6115047, scmRevision sequenceNumber "workflowId": 83363, stageExecId startTime "workflowRequestId": 1190160, streamName "workflowType": "DEPLOY", workflowExecutionId workflowId "workflowVersion": "1.2" workflowRequestId } workflowType workflowVersion] } } } |
Executing Queries
Combing everything we talked about this far, we are now able to execute queries.
...