Stuck on what to include/exclude in workflow

Hello all,

I’m currently stuck on what to include / exclude from my BPMN workflow. My use case at the moment is to process requests as user submits them. A user would submit a request via my application’s API endpoint and once user submits a request, I’d like to validate and save to DB if it passes validation. Once saved to DB, I’d like to sent an email to specific group of users to have them approve / reject the request.

I’m stuck at the moment trying to figure out if I should have my API endpoint first validate and save the request to the DB first before starting my workflow to send the email or should I just include validation and DB transaction tasks within my workflow as well?

The reason why I don’t want to include the validation and DB transaction in the workflow is because I would like to throw 400 error to the user letting them know that their request isn’t valid and I don’t believe I can throw the error if I’ve entered my workflow.

How should I go about modeling my process in this scenario?

Also if I were to validate the request, I would have to pass in most of my request business data into the process engine as well.

Thanks!

I would recommend to move the validation part outside BPMN.

If you use Spring boot, first you can validate and save the data to DB and then start the workflow using API. In modeling, start event, add the input form fields which you would like to use, pass the data from inside api to start the work flow.

Thanks @cpbpm, that’s what I was thinking too. I was just worried that this could cause some sort of invalid scenarios because the data wasn’t validated properly in the workflow. I guess if I ensure data is always validated before the workflow starts, then I don’t have to worry about invalid data in my workflow.

Thanks!

Personally I would like to start a workflow, and perform everything inside of it. This gives me insight into what is happening with my application.

In your scenario, if 10 different users tried to submit some data, and all of them have errored out, there will be zero process initiated and it may appear like today no users have logged on.

In my example, I will clearly know that 10 instances have been started, and all of them have failed and requires attention from administrators.

  • I can have the user resubmit the task
  • In case user did nothing wrong, but systems were down, I can have the admin fix the backend APIs and resubmit all the instances (end users don’t have to do anything)

Doing everything inside the workflow gives us 1) better visibility 2) better error handling capability

This also makes sense to me. However, I would like to return a HTTP error code back to the client if their request is invalid. I don’t think there’s a way for my Java Spring REST API to wait for the workflow to validate the request before sending a response back to the client. If I were to put everything in the workflow, I’d have to let the client know that their request has been started (not created) and if the validation fails in the workflow I can send them an email letting them know failed validation.]

For my use case, I don’t think adding the validation in the workflow brings about the best experience for the client.

Actually, you can do this quite easily -
Because the tread that starts an instance only returns successfully after it reaches the first wait state. You could add an execution listener on the start event which can do some validation and throw an error if the input is invalid. If you do that the error will be thrown back the user and the process instance will not be created.

That said - i strongly agree with what @vikkee is suggesting, in terms of system administration and general knowledge of whats happening across your system, keeping things inside the workflow can be a big benefit.

1 Like

Oh nice! I didn’t know about execution listeners can work at the start event of a workflow. According to this page Delegation Code | docs.camunda.org,

BpmnError in the delegation code behaves like modelling an error end event.

Would I need to catch the error thrown on my start event within my workflow? Or I can just catch the BPMN error within my API logic?

I wouldn’t use BPMN errors in this case. BPMN errors should be thought more as events that can be thrown and caught within a process and are used for violations in business logic rather than low-level validation.
I’ll create a quick example of how an execution listener might work and i’ll post it up

Appreciate your help, Niall.

So I made a pretty quick example - in this case it’s a process that needs to have the variable nameto exist.

There’s a listener in the process model’s start event written in JavaScript that just check if the variable is set.

If you start the process with a name variable the process will successfully start if you don’t add name the response send back to the requester is:

{
    "type": "RestException",
    "message": "Cannot instantiate process definition ValidationCheck:6:41d8baea-8c8a-11eb-91ad-8cb0865f5659: Unable to evaluate script while executing activity 'StartEvent_1' in the process definition with id 'ValidationCheck:6:41d8baea-8c8a-11eb-91ad-8cb0865f5659':You need to add a Name! in <eval> at line number 4 at column number 2"
}

Hope that helps.

validationListener.bpmn (2.4 KB)

My validation logic is more complex as I need to perform a few DB queries to check if a similar request hasn’t been created already. Can I just have the execution listener call my JavaDelegate class?

If so, what error should I be throwing in the execute() method to ensure the error gets propagated back to the requester (like how you threw the above error).

Screen Shot 2021-03-24 at 3.33.19 AM

Yes, thats a good idea :slight_smile:

Any error you like - whatever error you throw will be send back to the user.

Cool! I tried using the event listener myself and it seems the JavaDelegate class is throwing this error:
couldn't execute event listener : Error found, request is invalid

My error message that I want to return to the client is the “Error found, request is invalid” part, is there a way I can prevent my workflow from returning “couldn’t execute event listener”? Or should I just remove everything before the :?

@Niall - can I implement an event listener on the start of a service task with an external implementation? Whenever I call the externalTaskService.complete() method I’d like the event listener to perform additional validation and throw an error if validation fails. If validation passes, I’d like to complete the task.