/ Development  

Nightmare unleashed; Choose wisely between subtyping and 'toOne' relations

Hi there AppWorks fans,

Welcome to a new installment of AppWorks tips.

This time a post that will discuss several scenarios for implementation on architectural level (WHAT?); So, no low-coding? Yes, you can do some low-coding to try the different architectural topics; Only, this post will give an overview of some interesting “talking” plates to discuss within you own project team. All of them are valid, there is no such thing as “the best” or “the holy grail”…It all depends, and we’ll just talk about the benefits and the disadvantages per scenario. We discuss four of these plates, but a combination is always possible for your project; I just want to open your mind on the possibilities as during my own AppWorks journey this slightly moves to an unexpected direction!


Let get right into it…

The whole discussion started at my current project where we (as low-code developers) would like to implement a NEW case management system with all the best practices, latest platform features, and learned lessons from the past! Well, that’s already a great approach to start with. If your customer agrees to talk about this change, you know you’re on the right track. This asks for a plan with two hard lessons learned from the past:

👉 Subtyping with database disadvantages

Subtyping an entity makes sure that building blocks inherit from the parent entity. You can (optionally) make the parent abstract, so you can’t create an instance out of it. It’s a splendid feature when it comes to reusability, but it also has a dark side. All entity instances (parent and children) get a save in the same database table and with a large project with lots of repeatedly subtyping, you’ll eventually will hit the database limitations and your table will have lots of rows that require proper indexing. Take with this that the lowest subtype entity will inherit everything from all the top entities (also when functionality isn’t used at all) and you can understand how complex a solution can be once you’re a couple of years further down the drain.

👉 Centralized location for dictionaries/taxonomy lists and exposing it over APIs

This has a history of endless discussions with architects how techniques require an implementation. These days “loosely coupled” is the buzzword for each architect and “microservices” seem to be the new default to implement everything. I get it, but it’s not only mountains with green grass on the other side of the hill. Communication is mostly “lost in space” on this mindset. Ending up with islands of developers sending information from one service to the next not knowing the common sense of the complete flow. Data interpretation happens with its own validation on fields and other services should magically fit in. The solution for this messy data flow is a centralized location to store “reusable data” for all the services, but this also comes with a dark side. How to get the data when the API is down, unavailable, or responses with an error on an invalid input call. This is also solvable but has some after-taste with caching mechanisms that must be in sync.

The two lessons from above are direct learnings from what I see going wrong is lots of projects; This is also not only from an AppWorks perspective! In this post I’ll give guidance on how to solve these situations and what benefits and disadvantages they will have. What I said before, it’s not concrete…Pick the fruits and see where it can help in your project! AND…Please comment me on your choices; I love to hear from your experiences.


Inheritance with direct config relation

arch_001

This is a small Entity Relation Diagram that covers a typical case management solution I often see passing by. It uses a main ‘Case’ entity which used as a generic type of case implementation following the rules applied. To implement a specific type of ‘Case’, you create a subtype out of it, inherit all the building blocks and add additional features from the ‘Special Case’ entity (or any others). Great for small solutions, but terrible on a larger scale with more inheritances. Use it wisely!
In this scenario we make use of an external data source (can be a database) that exposed centralized data over an API layer (ReST/SOAP). In this dataset we have a list of types we can use on our cases. In this example we simply introduce a regular ‘Type’ entity, and we make sure they instance/start (in runtime) via a (scheduled) BPM synchronization process. For this we can use the HTTP/UDDI connector to keep it in sync. A regular entity has the advantage of the availability of all the regular BBs (continue your read to see this is different for other types of entities).
Now, we can make a direct relation from ‘Case’ to ‘Type’ which works more smoothly from a low-code implementation perspective. Why not directly calling the central DB from the ‘Case’? Well, that’s for performance reasons as the data is now directly available from an AppWorks perspective; When services are down/unreachable, we can keep on running.
You don’t want to know how many times I see failing service calls with the weirdest reasons, data out of sync, data changes which impact all your relative direct calls! Trust me, you don’t want to have such situation on your name…Pull it into a location where you have control over it.

🗒 Can we do better?


Relations with loosely config over dynamic Enum property

arch_002

In this situation we see two changes:

  1. We don’t use subtyping, but we relate to its parent. This makes sure the ‘Special case’ entity starts from nothing without the ballast from above; This also makes sure some features require a repeating implementation. From a AppWorks database perspective these two entities have their own tables which (with lots over inheritance) will save your future already. Trust me, the issues are nothing compared to implementing a feature twice!
  2. No relation to the ‘Type’ entity but using dynamic enumerated properties to read the data (via a short-lived BPM). Works great but increases complexity as well. Also, the data saves twice (also in a ‘type’ property on the case itself). It does follow the loosely coupled mindset from your architect, and you can easily create a separate ‘Config’ project without the harm of introducing a so-called circular dependency between projects.

🗒 Great to please your architect, but saving data twice? Really?


Relations with linked config relation over WS-AppServer

arch_003

Here we introduce the relation again! Only, this time based on an interesting type of entity called ‘Linked entity’. You can extract these types of entities if you have a direct database connection available. Sounds like the holy grail to me, but your architect will not allow such direct connection (as it’s not “loosely coupled”). Well, to solve this we simply introduce our own database on the AppWorks side that keeps it in sync with the external source. This will be a read-only kind of “cache DB” where we extract our linked entities from which we can then relate to our case again. This way you have the benefits of relations back. What I say…The holy grail where you are fully in self-control to the external data within AppWorks.
You only need to make sure the database is in sync, but that could be a simple tool (a scheduled BPM calling webservices over the HTTP connector!?) when the external source is only accessible over a services API layer (which is common these days!)

🗒 The above thought solves a lot of problems…Is it the holy grail? I don’t know, but I DO know it opened my eyes and mindset on new solution implementations for the future!


Relations with external config relation over EIS-connector

arch_004

Finally, we have the Enterprise Information System (EIS) connector. This one improves in the latest versions of the platform, but I still experience a lot of required effort before it works smoothly as documented. I don’t know what it is with EIS; It sounds great, and it is because it directly embeds external data (over ‘External’ entities) into your solution over a service API layer. I don’t know about caching when the external service is down as I haven’t tried that specific situation. EIS is still a valid solution, but there is just too many buts…

🗒 The EIS was my favorite way of consuming external resources until someone (you know who you are) noted me on the previous path with linked entities and keeping a DB in sync with a small tool!

Another extra note: In the past also the EIS connector didn’t have all the building blocks available on the external entity…Check this before following this path!


An architectural DONE with great thoughts to discuss within your own team. It’s not solid in concrete but pick whatever you can use for your own benefits; Re-discuss them within your own team and act on it. Once chosen wisely it’s hard to turn back; Especially once you’re in production! That’s at least what we experienced already twice in two large projects after excepting the project challenge, but who are we to turn our backs against it; Just embrace it and start moving into a more solid direction by steering the captain to his destination! What a nonsense-talk 🤣 …Enjoy your weekend; See you next week.

Don’t forget to subscribe to get updates on the activities happening on this site. Have you noticed the quiz where you find out if you are also “The AppWorks guy”?