journeys / journey-xml-5Markdown ↓

Queries, selections and writes

The following complete recipe uses illustrative API fields: greeting, records and save are not platform endpoints. Discover the actual GraphQL fields, input types and permissions on your target instance before adapting it.

<journey id="operations" title="Select and save" estimatedMinutes="3">
  <fetch id="load" title="Load" description="Loading the greeting">
    <document>query { result: greeting }</document>
    <capture key="greeting" path="result"/>
  </fetch>
  <query-pick id="pick" title="Choose" description="Choose a record"
              listPath="result" labelPath="name">
    <document>query { result: records { id name } }</document>
    <capture key="selected" path="id"/>
  </query-pick>
  <execute id="save" title="Save" description="Save your choice" mutating="true">
    <document><![CDATA[
      mutation Save($id: ID!, $input: Settings!) {
        result: save(id: $id, input: $input) { id }
      }
    ]]></document>
    <variables>
      <arg name="id" ref="$.state.selected"/>
      <object name="input">
        <arg name="enabled" type="boolean" value="true"/>
        <array name="counts"><arg type="number" value="2"/><arg type="number" value="3"/></array>
        <arg name="note" type="null"/>
      </object>
    </variables>
    <capture key="saved" path="result.id"/>
    <reveal key="saved" label="Saved identifier" copyable="true" monospaced="true"/>
  </execute>
  <wait-for id="wait" title="Wait" description="Waiting for readiness"
            path="result" intervalSeconds="1" timeoutSeconds="5">
    <document>query { result: ready }</document>
    <equals type="boolean" value="true"/>
  </wait-for>
  <agent id="review" title="Review">
    <goal>Review the saved record.</goal>
    <manual-fallback><body>Review the saved identifier before finishing.</body><check>Record reviewed.</check></manual-fallback>
  </agent>
  <done id="done" title="Saved"><body>{{ $.state.greeting }}: {{ $.state.saved }}</body></done>
  <knowledge-capture>Saved {{ $.state.saved }}</knowledge-capture>
</journey>

Fetch runs a read query on entry, captures values, and advances after success. A capture path is relative to response data, without a data prefix. In this recipe result is a GraphQL alias. Missing required capture paths fail the stage; they are not silently replaced with empty strings.

Query-pick reads a list. listPath is relative to data; labelPath, sublabelPath and capture paths are relative to each selected list item. For a Relay connection, listPath could select connection.edges and the item paths would start with node. A selection captures values and advances. An empty list requires a retry or going back, not a fabricated selection.

Execute runs on explicit activation. A mutation document must set mutating="true", so the CoCoCo app asks the user to confirm before sending; an unmarked mutation is rejected when you save. Confirmation does not grant API permissions. All requests retain the current user's authority. A read query may also use execute when explicit activation is desirable.

Use GraphQL variables, including nested object and array values. Query strings remain static; never concatenate user input into the document. Alias the principal result to result to keep response paths easy to read. Captures happen after successful execution; reveal displays captured state and may offer copy and monospaced presentation.

GraphQL errors, including errors alongside partial data, fail execution. Retry can resend an operation. A network failure after a server write does not prove the write was rolled back: use an idempotent API or check whether the record already exists before retrying a create. Going back does not undo writes or promise to invalidate earlier captures. Journeys are not database transactions.

Published platform manual · revision 91e006badb55