What is the best practice for headless (UI outside Appian) implementation in Appian

Hi,

We have the following requirement and would appreciate the community's support to suggest the best practice for achieving the same.

Business Requirement :

A process for loan is triggered in a branch (CRM system) where all the customer and loan related details are collected and then submitted to another department(Credit department) in the bank.

All the UI and process related to branch is implemented in CRM, whereas credit department UI is implemented in Appian(review of submitted application happens in credit department).

if any discrepancies are found in the application, credit department can send the application back to branch(CRM) and once corrected flow will continue in Appian.

This return to branch/ different roles within the branch can happen multiple times at various points during credit department review

Suggestion required on below approaches:

Approach 1:

In traditional BPM systems, we create a Dummy task in BPM to indicate the external system task(CRM), once this task is created, we capture the task ID and notify the external system about the impending task that needs to be actioned. --> Once external system completes the task , an API call is made along with the same task ID and using the CompleteTask function/ smart service we complete the dummy external task in BPM and flow moves forward

Approach 2:

As soon as the credit department selects to return the application to CRM, we capture the state of the process in DB via records and the terminate the process, and inform CRM about the impending external activity to be done. --> Once external activity is completed in CRM, a new instance of the same process is created via StartProcess API--> we check the state of the application in DB for the same application number and redirect the flow to that particular step post external activity

Now, which one of the above mentioned approaches is best suitable for my requirement (Consider that fact that entire process is not a long running process and there might be a maximum of 2000 instances created in a day in Appian for all process of bank combined together), please suggest the same with pros and cons?

Also, If there is any other better approach, please suggest the same

Thanks in Advance

Suhas

  Discussion posts and replies are publicly visible

Parents
  • Certified Lead Developer

    Some of my thoughts:

    - It is clear that a "User Input Task" is meant to directly interact with the user. So using them headless makes no sense. 

    - Short living processes are good.

    - Lingering receive message events in high volumes are a problem. 2000 is not.

    Both options are very comparable, but being a process person, I would probably go with the reasoning I got from Google Gemini.

    Everything below is AI generated:

    Okay, let's break down these two approaches for integrating your CRM and Appian processes, considering the back-and-forth nature of the loan application review.

    Analysis of Approaches

    Approach 1: Dummy Task / Wait State

    • Mechanism: The Appian process reaches a point where it needs CRM input. It creates a placeholder (dummy) task or enters a wait state (e.g., using a "Receive Message Event" node). Appian notifies CRM, passing a unique identifier (like the process instance ID or a specific correlation ID, potentially the Appian Task ID if using an actual task node). The Appian process instance remains active but paused. When CRM completes its work, it calls an Appian API (e.g., Complete Task if using a task node, or a custom API triggering the message event), passing back the identifier. Appian then resumes the flow from where it paused.
    • Pros:
      • Maintains Process Context: The entire state of the Appian process (all process variables, history) is preserved within the single, active instance. This simplifies debugging and understanding the flow.
      • Simpler Flow Logic: The process model directly reflects the business flow, including the waiting period. Resumption is straightforward – the flow continues from the node that was waiting.
      • Standard BPM Pattern: This is a very common integration pattern in BPM suites. Appian is designed to handle paused instances waiting for external events or callbacks efficiently.
      • Easier Reporting: Tracking the end-to-end lifecycle of a single loan application within Appian's process reporting tools is simpler as it's typically tied to a single process instance ID.
    • Cons:
      • Resource Consumption: Active (even if paused) process instances consume some memory and potentially other system resources on the Appian server. While you state it's not "long-running" in the sense of months/years, if the CRM turnaround takes days and you have many instances waiting, this could add up. However, 2000 total instances daily across all processes is generally not considered excessively high for Appian, suggesting this might be manageable.
      • Requires Identifier Management: CRM needs to reliably store and return the correct Appian identifier (Task ID, Process ID, or Correlation ID) for the callback to work.

    Approach 2: Terminate and Restart

    • Mechanism: When sending work to CRM, Appian saves all necessary data (current state, relevant variables, application ID) to an external datastore (like an Appian Record Type backed by a database table). The current Appian process instance is then terminated. CRM is notified. When CRM finishes, it calls a different Appian API (like Start Process or a Web API that starts a process). This creates a newprocess instance. The new instance's first steps involve querying the datastore using the application ID, retrieving the saved state, and using gateways/rules to navigate the process flow to the correct resumption point.
    • Pros:
      • Lower Resource Usage (During Wait): No active Appian process instance is consuming resources while waiting for CRM. This is the primary advantage, especially if wait times could be unexpectedly long or if instance volume was extremely high.
      • Decoupling: Creates a harder boundary between the systems during the wait period.
    • Cons:
      • Increased Complexity: This is significantly more complex to design, implement, and maintain.
        • State Management: You must meticulously ensure all required data is saved before termination and correctly restored upon restart. This logic can become complex and prone to errors, especially if the process model changes.
        • Process Model Complexity: The process model needs logic at the beginning to handle these different "entry points" based on the restored state, making it harder to read and follow the standard flow.
        • Error Handling: What happens if the restart fails? You need robust error handling and potentially manual intervention processes to deal with orphaned state data in the database.
      • Loss of In-Flight Context: The direct link and history within a single Appian process instance are broken. Reporting on the end-to-end journey of one application requires stitching together data from potentially multiple process instances and the external state datastore.
      • Restart Overhead: Starting a new process instance incurs some overhead each time, although usually minor.
      • Potential for Orphaned Data: If CRM fails to call back or the restart process fails critically, the saved state data might remain in the database indefinitely without a corresponding active process.

    Recommendation

    Approach 1 (Dummy Task / Wait State) is generally the recommended best practice for this scenario, especially given your context.

    • Why: It aligns best with how BPM platforms like Appian are designed to work. Managing state within an active (even if paused) instance is simpler and less error-prone than externalizing, terminating, and rebuilding state. The complexity of Approach 2 introduces significant risks and maintenance overhead that likely outweigh the resource benefits, especially since your stated volume (2000 instances/day total) is not typically problematic for Appian's ability to handle paused instances. The fact that returns can happen multiple times strongly favors Approach 1, as looping back to a wait state is much cleaner than repeated terminate/save/restart cycles.

    Refinement for Approach 1 in Appian:

    Instead of literally creating a "dummy task" that requires CompleteTask, consider using Appian's Receive Message Event node.

    1. When the process needs to hand off to CRM, it reaches a "Receive Message Event" node configured to wait for a specific message (correlated by, say, the loan application ID).
    2. Appian sends the loan application ID and any other necessary data to CRM.
    3. The Appian process instance pauses at the event node.
    4. When CRM finishes, it calls an Appian Web API.
    5. This Web API uses the Send Event or Send Message function/smart service, targeting the paused process instance using the loan application ID as the correlation key.
    6. The "Receive Message Event" node receives the message, and the process instance resumes.

    This achieves the same goal as the "dummy task" but is often considered a more modern and slightly cleaner way to handle external asynchronous callbacks in Appian.

    Conclusion

    Unless you have specific, measured evidence that paused instances under Approach 1 are causing critical resource constraints on your Appian environment (which seems unlikely given the described volume), Approach 1 (ideally using a Receive Message Event) offers a simpler, more robust, and more maintainable solution that leverages the strengths of the Appian platform for managing process state. The complexity and potential pitfalls of Approach 2 generally make it less desirable for this type of requirement.

  • I got similar response from ChatGPT, Grok and MS Copilot

Reply Children
No Data