How to generate unique business key

I have gone through other forum posts and could not get the answer I was looking for.

I have an approval workflow with multiple user’s approval required once a request is raised. When the request is created in the client side (React) I am first calling the camunda REST API to create the process instance. This gives me the processId which I then use to create the request in my application DB (one of the fields is the camundaProcessId). If the business key is supposed to be the id of my request, then I cannot get that Id until it has been created on the database.

The other option is that I could create the entry in my app DB first leaving camunda process Id field empty, then I use this entry Id as a business key (something like tenantId:approval:approvalId?) to make the API call to camunda. Then once the process instance is started, I would update the process Id into my app DB.

Yet another option is the first method, but generating some random uuid (something like tenantId:approval:uuid?) on the client (react) and setting that value in both camunda business key, and also my app DB.

I am using a GraphQL endpoint, but that should not matter. Do the above options make sense, or am I missing something?

Hi @johnjacobkenny,

The businessKey will be returned, if it is set in a task or a listener directly after the start of the process.

Have a look at this process: BusniessKeyTest.bpmn (2.8 KB)

The Rest call to start a process instance returned:

{
    "links": [
        {
            "method": "GET",
            "href": "http://localhost:8080/engine-rest/process-instance/aea58379-0ec9-11eb-986b-4865ee124855",
            "rel": "self"
        }
    ],
    "id": "aea58379-0ec9-11eb-986b-4865ee124855",
    "definitionId": "BusinessKeyTest:1:85c55758-0ec9-11eb-986b-4865ee124855",
    "businessKey": "123",
    "caseInstanceId": null,
    "ended": false,
    "suspended": false,
    "tenantId": null
}

Hope this helps, Ingo

Hi @Ingo_Richtsmeier,

Thanks for sharing the example :smiley:

In the model, I can see the inline script being used to set a static value for business key. In my use case that is specifically not helping out much. And I think from the docs they mention that there are no other ways to dynamically set the business key once the process is started?

Here for my requirement I need to have some dynamic key which is set when starting the process instance. So would that mean that I need to have the entry in my app db before kicking off the camunda process instance?

Hi

This post may be of interest… Hence rather than focussing on how to generate a unique busines key, consider what its business purpose is. Once you have identified that, the generation location and form may become evident…

P.s. - this post is dated in that the engine now supports a more mutable business key posture…

regards

Rob

1 Like

Hi @johnjacobkenny,

my process was just an example. You can get more details about changing a businessKey during process execution here: https://docs.camunda.org/manual/7.14/user-guide/process-engine/delegation-code/#set-business-key-from-delegation-code.

And I agree to Rob, that the value of the key is a totally different story. Don’t create them too complicated. From my experience, businessKeys should be as short as possible that human beeings can recognize them.

Hope that helps, Ingo

1 Like

Thanks @Webcyberrob @Ingo_Richtsmeier

Would you recommend that I figure out how to trigger process instance creation on a table insert event? Also, would you recommend not adding the process instance id as a field in my table?

So in my case I am tracking the status of the process by changing a status variable in the process instance. I have so far stored the process instance ID with my database entry, and I am using it through the REST API to fetch the status variable and display status on the UI.

Should I set the business key, and then use the business key to fetch the same data instead?

Hi,

From your description, it looks like your architecture comprises the UI, a business object representing a Request and a business process to transition the Request from initiated to approved…

I get the impression you are wrestling with the order of creating the business object and the business process and how to connect all the parts…

So lets start with creating the Request object first. The identifier of this business object is a good candidate for a business key. I would suggest this business object needs a status attribute with values something like [Pending, Approved, Referred, Declined]. Hence your business object domain could expose a get API to retrieve the status of the request… eg /api/requests/[businessKey/

Now that you have a businessKey, your client could start a new process instance and pass in this business key. The process could use this business key to access the business object. Thus as the process proceeds, the process could retrieve the request when a task requires the content and update the status at appropriate stages in the process.

So do you need to store the process instance Id in your request object? Not in this case as you can always query the process engine based on business key.

In this architecture, I have chosen to treat the business object state (approved/declined) separate to the process flow state (the bpmn engine). Thus request state is always retrieved from the business object, not the process engine. Hence there is no need to maintain the process instance Id in the request object…

I hope this helps you articulate your design decisions a little more

regards

Rob

1 Like

Hi @Webcyberrob

This is very useful and helped me clear up a lot of details. :smiley:

So I can generate the business object, and get the Id to pass through as the business key. I was initially assuming that the business key needs to be unique across all process instances in camunda, but now from what you suggest, I think that there can be multiple processes with the same business key. So in order to get details about that process instance, I would use the camunda REST API and filter by process name and business key, is that right?

Also, there are multiple approvals in this request flow. Right now I have a tasks table in my application db and I am using a nodejs service to create a task business object (this has to identify the right user for the task somehow, and assign to them). This happens for the corresponding approver when the process instance reaches that step (see fig). Here I am also including the task Id so that I can mark it as completed from the UI. Does that make sense or is there a better way?

I think that there can be multiple processes with the same business key. So in order to get details about that process instance, I would use the camunda REST API and filter by process name and business key, is that right?

Yes - its a design choice to enforce unique business key or not…

Also, there are multiple approvals in this request flow. Right now I have a tasks table in my application db and I am using a nodejs service to create a task business object (this has to identify the right user for the task somehow, and assign to them)

Not sure why you need to do this as task management should be the domain of the process engine and thus you dont manage this yourself…

To expose task status to the UI, you have two choices. You could obtain it direct from the process engine, or the process could update your business object and you UI always obtains it from the business object. This is an architectural choice…

My guiding principles would be - if you want to expose granularity of status at the granularity of the process model and a direct mapping of the process model status, then get it from the process engine. If you anticipate the read load for status requests to be extremely high, then obtain it from a read replica of the process engine. If the granularity of business object state is much more coarse grained than the process model, then encapsulate this an expose it from the business object domain…

regards

Rob

1 Like

Yes this makes sense. So the way you are suggesting to keep the task in camunda - so I would assign the user id for that user as the assigned user in camunda for that task. Then from UI I should fetch all tasks for that user, and when the user opens this task, I can fetch the details by using the business key. And I can use that task id to complete it too, right?

Hi,

Heres an interaction diagram which shows one architectural approach along the lines I discussed…

regards

Rob

2 Likes

Hi Rob,

This diagram is very exhaustive, thank you so much for thinking through it and creating it. I will get back to you after giving it a try :smiley:

Best,
Kenny

1 Like

Hi John,

No prob - this is one approach, others are possible. The intent is to show how three components of this architectural approach interact…

regards

Rob

2 Likes