GraphQL Operations
Author:
Fluent Commerce
Changed on:
16 Oct 2024
Overview
is a query language for APIs and a runtime for fulfilling those queries with your existing data. It provides a complete and easy-to-understand description of the data in your API. Its ability to return select fields enables it to be used with powerful developer tools and ensures that APIs are easily scalable.
Fluent's API has two operations:
- Queries
- Mutations
Queries include predefined Queries and Custom Queries, both of which will be covered below.
Key points
- Operations
- Queries
- Mutations
- Custom Queries
Operations

Queries
Query operations are used for retrieving data. Fluent's API has two types of query operations:
- Get Operations
- Search Operations
Get Operations
Get operations always return a single result. These operations should be used when a unique identifier for the object to be retrieved is known. This can be an ID, ref (reference), or both in conjunction. In some cases, it can also be defined by something else. Refer to the GraphQL Queries page for more details.
Examples
1{
2 order(ref: "Order-Ref-100") {
3 ref
4 type
5 status
6 items {
7 edges {
8 node {
9 status
10 product {
11 name
12 }
13 paidPrice
14 currency
15 }
16 }
17 }
18 fulfilments {
19 edges {
20 node {
21 status
22 createdOn
23 deliveryType
24 fromAddress {
25 name
26 companyName
27 street
28 state
29 postcode
30 }
31 toAddress {
32 name
33 companyName
34 street
35 state
36 postcode
37 }
38 }
39 }
40 }
41 }
42}
1{
2 "data": {
3 "order": {
4 "ref": "Order-Ref-100",
5 "type": "HD",
6 "status": "BOOKED",
7 "items": {
8 "edges": [
9 {
10 "node": {
11 "status": "NEW",
12 "product": {
13 "name": "simple sku"
14 },
15 "paidPrice": 10,
16 "currency": "AUD"
17 }
18 }
19 ]
20 },
21 "fulfilments": {
22 "edges": [
23 {
24 "node": {
25 "status": "CREATED",
26 "createdOn": "2019-09-19T01:01:42.448Z",
27 "deliveryType": "STANDARD",
28 "fromAddress": {
29 "name": "Darth Vader",
30 "companyName": "Star Wars",
31 "street": "200 Secret",
32 "state": "VIC",
33 "postcode": "3032"
34 },
35 "toAddress": {
36 "name": "Luke Skywalker",
37 "companyName": "",
38 "street": "3 Grandiflora Gr",
39 "state": "VIC",
40 "postcode": "3030"
41 }
42 }
43 }
44 ]
45 }
46 }
47 }
48}
1{
2 orderById(id: 100) {
3 id
4 ref
5 type
6 status
7 fulfilments {
8 edges {
9 node {
10 status
11 createdOn
12 deliveryType
13 fromAddress {
14 name
15 companyName
16 street
17 state
18 postcode
19 }
20 toAddress {
21 name
22 companyName
23 street
24 state
25 postcode
26 }
27 }
28 }
29 }
30 }
31}
1{
2 "data": {
3 "orderById": {
4 "id": "100",
5 "ref": "Order-Ref-100",
6 "type": "HD",
7 "status": "BOOKED",
8 "fulfilments": {
9 "edges": [
10 {
11 "node": {
12 "status": "CREATED",
13 "createdOn": "2019-09-19T01:01:42.448Z",
14 "deliveryType": "STANDARD",
15 "fromAddress": {
16 "name": "Darth Vader",
17 "companyName": "Star Wars",
18 "street": "200 Secret",
19 "state": "VIC",
20 "postcode": "3032"
21 },
22 "toAddress": {
23 "name": "Luke Skywalker",
24 "companyName": "",
25 "street": "3 Grandiflora Gr",
26 "state": "VIC",
27 "postcode": "3030"
28 }
29 }
30 }
31 ]
32 }
33 }
34 }
35}
Search Operations
Search operations filter out objects of a given type. They should be used when searching for objects that meet one or more criteria. An example of such an operation would be to search for and get all Orders of type "HD." Search operations are also great for reporting on particular types.
Example
1{
2 orders(type: "HD") {
3 edges {
4 node {
5 id
6 ref
7 type
8 status
9 }
10 }
11 }
12}
1{
2 "data": {
3 "orders": {
4 "edges": [
5 {
6 "node": {
7 "id": "1488206",
8 "ref": "HD-ORDER-REF-743",
9 "type": "HD",
10 "status": "BOOKED"
11 }
12 },
13 {
14 "node": {
15 "id": "1488205",
16 "ref": "HD-ORDER-REF-1643",
17 "type": "HD",
18 "status": "BOOKED"
19 }
20 },
21 {
22 "node": {
23 "id": "1488203",
24 "ref": "HD-ORDER-REF-5037",
25 "type": "HD",
26 "status": "COMPLETE"
27 }
28 },
29 {
30 "node": {
31 "id": "1488202",
32 "ref": "HD-ORDER-REF-3051",
33 "type": "HD",
34 "status": "BOOKED"
35 }
36 },
37 {
38 "node": {
39 "id": "1488200",
40 "ref": "HD-ORDER-REF-6260",
41 "type": "HD",
42 "status": "COMPLETE"
43 }
44 },
45 {
46 "node": {
47 "id": "1488198",
48 "ref": "HD-ORDER-REF-6099",
49 "type": "HD",
50 "status": "COMPLETE"
51 }
52 },
53 {
54 "node": {
55 "id": "1488196",
56 "ref": "HD-ORDER-REF-7798",
57 "type": "HD",
58 "status": "COMPLETE"
59 }
60 },
61 {
62 "node": {
63 "id": "1488194",
64 "ref": "HD-ORDER-REF-9643",
65 "type": "HD",
66 "status": "COMPLETE"
67 }
68 },
69 {
70 "node": {
71 "id": "1488192",
72 "ref": "HD-ORDER-REF-9181",
73 "type": "HD",
74 "status": "COMPLETE"
75 }
76 },
77 {
78 "node": {
79 "id": "1488190",
80 "ref": "HD-ORDER-REF-8637",
81 "type": "HD",
82 "status": "COMPLETE"
83 }
84 }
85 ]
86 }
87 }
88}
Additional Information
To pass schema complexity validation, all API operation queries must meet the following standards:
- Search queries should be supplied with a first or last argument. The query will only return the first 10 records if these arguments are not provided.
- Values of first and last must be within 1 - 5,000. If the value exceeds 5000, it is replaced by 5000.
- Queries must have a complexity value of under 11,111, as those that exceed it will not be executed.
Mutations
operations used to create or update data are called Mutations. The Fluent API provides three types of mutations: Create, Update, and Remove.
Mutations return an object type. The user can specify which fields they want to be returned.
Examples
1mutation {
2 createRole (input: {
3 name: "ROLE_MANAGER"
4 permissions: [
5 { name: "ROLE_VIEW" },
6 { name: "PERMISSION_VIEW" },
7 { name: "ROLE_CREATE" },
8 { name: "ROLEPERMISSION_UPDATE" }
9 ]
10 }) {
11 id
12 name
13 permissions {name}
14 }
15}
1{
2 "data": {
3 "createRole": {
4 "id": "1000030",
5 "name": "ROLE_MANAGER",
6 "permissions": [
7 {
8 "name": "ROLE_VIEW"
9 },
10 {
11 "name": "PERMISSION_VIEW"
12 },
13 {
14 "name": "ROLE_CREATE"
15 },
16 {
17 "name": "ROLEPERMISSION_UPDATE"
18 },
19 {
20 "name": "PERMISSIONROLE_REMOVE"
21 }
22 ]
23 }
24 }
25}
1mutation {
2 updateRole(input: {name: "ROLE_MANAGER", permissions: {name: "ROLE_UPDATE"}}) {
3 name
4 permissions {
5 name
6 }
7 }
8}
1{
2 "data": {
3 "updateRole": {
4 "name": "ROLE_MANAGER",
5 "permissions": [
6 {
7 "name": "ROLE_VIEW"
8 },
9 {
10 "name": "PERMISSION_VIEW"
11 },
12 {
13 "name": "ROLE_CREATE"
14 },
15 {
16 "name": "ROLE_UPDATE"
17 },
18 {
19 "name": "ROLEPERMISSION_UPDATE"
20 },
21 {
22 "name": "PERMISSIONROLE_REMOVE"
23 }
24 ]
25 }
26 }
27}
1mutation {
2 removePermissionsFromRole(input: {role: {name: "ROLE_MANAGER"}, permissions: {name: "ROLE_UPDATE"}}) {
3 status
4 }
5}
6
7
8
9// Query to check the role now
10query {
11 role (name: "ROLE_MANAGER") {
12 name
13 permissions {
14 name
15 }
16 }
17}
1{
2 "data": {
3 "removePermissionsFromRole": {
4 "status": "SUCCESS"
5 }
6 }
7}
8
9
10{
11 "data": {
12 "role": {
13 "name": "ROLE_MANAGER",
14 "permissions": [
15 {
16 "name": "ROLE_VIEW"
17 },
18 {
19 "name": "PERMISSION_VIEW"
20 },
21 {
22 "name": "ROLE_CREATE"
23 },
24 {
25 "name": "ROLEPERMISSION_UPDATE"
26 },
27 {
28 "name": "PERMISSIONROLE_REMOVE"
29 }
30 ]
31 }
32 }
33}
Custom Queries
Custom queries are special queries available through the Fluent API. With custom queries, the server processes the input and applies some logic to it before returning the output. This logic can be either queries or mutations.
Although it is preferred to keep the Fluent servers simple and let handle any complex logic, there are times when custom queries are necessary to improve performance and reduce overall complexity.
The Fluent API now supports two custom queries- SearchVirtualInventory and ArticlesByLocation.
Example - SearchVirtualInventory
This query up to 10 of the nearest locations that can entirely fulfill a set of items based on available-to-sell stock in a given . Targeted use cases include fulfilling an with no splits (as locations that require a split will not be returned) or showing a list of stocked pickup options to a customer in a product page or checkout scenario.
1query {
2 searchVirtualInventory(
3 virtualCatalogue: { ref: "VCREF" },
4 productQuantities: [{ productRef: "myProductRef" quantity: 0 }]
5 ) {
6 edges {
7 node {
8 virtualPositions {
9 id
10 ref
11 productRef
12 quantity
13 createdOn
14 }
15 location {
16 ref
17 name
18 type
19 id
20 defaultCarrier
21 }
22 }
23 }
24 }
25}
1{
2 "data": {
3 "searchVirtualInventory": {
4 "edges": [
5 {
6 "node": {
7 "virtualPositions": [
8 {
9 "id": "efe808e3-5eb5-45ab-b495-9f8a27ddd10a",
10 "ref": "VPREF",
11 "productRef": "myProductRef",
12 "quantity": 40,
13 "createdOn": "2019-10-04T03:28:18.380Z"
14 }
15 ],
16 "location": {
17 "ref": "DEMO_LOC",
18 "name": "fooName",
19 "type": "STORE",
20 "id": "13",
21 "defaultCarrier": "SHIPPIT"
22 }
23 }
24 }
25 ]
26 }
27 }
28}
Example - ArticlesByLocation
This query the articles currently en route to or awaiting collection from a given or set of locations. Either 'fromLocation' or 'toLocation' should be provided.
1{
2 articlesByLocation(fromLocation:{ref:"5000299_SYD"}, first:2, consignmentStatus:"ACTIVE_LODGED", retailerId:5000299 ){
3 edges{
4 node{
5 name
6 description
7 ref
8 quantity
9 consignmentArticles{
10 edges{
11 node{
12 consignment{
13 status
14 }
15 }
16 }
17 }
18
19 name
20 carrierConsignmentArticles{
21 edges{
22 node{
23 carrierConsignment{
24 carrier{
25 name
26 ref
27 }
28 carrierConsignmentArticles{
29 edges{
30 node{
31 article{
32 id
33 ref
34 }
35 carrierConsignment{
36 status
37 labelUrl
38 ref
39 id
40 }
41 }
42 }
43 }
44 }
45 }
46 }
47 }
48 fulfilments{
49 edges{
50 node{
51 order{
52 ref
53 }
54 }
55 }
56 }
57 ref
58 status
59 createdOn
60 }
61 }
62 }
63}
1{
2 "data": {
3 "articlesByLocation": {
4 "edges": [
5 {
6 "node": {
7 "name": "Custom",
8 "description": "2024SHOE001_A,2024SHOE001_B",
9 "ref": "df47c27f-8a66-4b05-bf33-542c7391441a-5000299_SYD-1",
10 "quantity": 12,
11 "consignmentArticles": {
12 "edges": [
13 {
14 "node": {
15 "consignment": {
16 "status": "ACTIVE_LODGED"
17 }
18 }
19 }
20 ]
21 },
22 "carrierConsignmentArticles": {
23 "edges": [
24 {
25 "node": {
26 "carrierConsignment": {
27 "carrier": {
28 "name": "Demo Carrier for Retailer 5000299",
29 "ref": "DEFAULT_CARRIER:5000299"
30 },
31 "carrierConsignmentArticles": {
32 "edges": [
33 {
34 "node": {
35 "article": {
36 "id": "5002370",
37 "ref": "df47c27f-8a66-4b05-bf33-542c7391441a-5000299_SYD-1"
38 },
39 "carrierConsignment": {
40 "status": "ACTIVE_LODGED",
41 "labelUrl": "DEMO_UK_RoyalMail_Label.pdf",
42 "ref": "96ed826d-bc4a-4e29-af37-dc5ed224011c",
43 "id": "5000869"
44 }
45 }
46 }
47 ]
48 }
49 }
50 }
51 }
52 ]
53 },
54 "fulfilments": {
55 "edges": [
56 {
57 "node": {
58 "order": {
59 "ref": "CC_414376"
60 }
61 }
62 }
63 ]
64 },
65 "status": "PENDING_CONSIGNMENT",
66 "createdOn": "2024-04-11T23:15:12.926Z"
67 }
68 },
69 {
70 "node": {
71 "name": "small",
72 "description": "2024SHOE001_A,2024SHOE001_B",
73 "ref": "3156946f-0d02-4869-9077-416822ea0631-5000299_SYD-1",
74 "quantity": 12,
75 "consignmentArticles": {
76 "edges": [
77 {
78 "node": {
79 "consignment": {
80 "status": "ACTIVE_LODGED"
81 }
82 }
83 }
84 ]
85 },
86 "carrierConsignmentArticles": {
87 "edges": [
88 {
89 "node": {
90 "carrierConsignment": {
91 "carrier": {
92 "name": "Demo Carrier for Retailer 5000299",
93 "ref": "DEFAULT_CARRIER:5000299"
94 },
95 "carrierConsignmentArticles": {
96 "edges": [
97 {
98 "node": {
99 "article": {
100 "id": "5002372",
101 "ref": "3156946f-0d02-4869-9077-416822ea0631-5000299_SYD-1"
102 },
103 "carrierConsignment": {
104 "status": "ACTIVE_LODGED",
105 "labelUrl": "DEMO_UK_RoyalMail_Label.pdf",
106 "ref": "dd139c1c-9e15-4368-b565-f71566e53a94",
107 "id": "5000870"
108 }
109 }
110 }
111 ]
112 }
113 }
114 }
115 }
116 ]
117 },
118 "fulfilments": {
119 "edges": [
120 {
121 "node": {
122 "order": {
123 "ref": "CC_681908"
124 }
125 }
126 }
127 ]
128 },
129 "status": "COLLECTED",
130 "createdOn": "2024-04-12T00:36:03.484Z"
131 }
132 }
133 ]
134 }
135 }
136}