As my kids have grown (I have a 12 year old, a 10 year old, and a 7 year old), it is easy to watch as they become more mature and more independent. They are growing towards maturity and independence. Perhaps it is inevitable that I, as an architect, find myself comparing this growth to that of application design.
When my kids were small, I had to tell them everything that was happening, and what they should do. “It’s raining, Max. Put on your coat,” or “We need to get ready to leave, or we will be late to see the movie.” Every step was reminded, every consequence laid out. They were responsible primarily for listening and doing what we told them to do.
As they’ve grown, my wife and I have worked hard to teach them to look for the consequences themselves. “If it is bedtime, you don’t need us to remind you to brush your teeth. You should do it on your own.” The goal is to have a household that runs pretty much on its own. They get up when the alarm goes off. They contribute to the household chores without the need for step-by-step oversight. They are rewarded for being good household “citizens.”
The other day, I was describing autonomous services to a developer and my mind wandered to thinking about my kids. It hit me: an autonomous service is like a child that is growing up. For the service to be truly autonomous, you don’t have to tell it what to do with information. You just provide the information that it is interested in. It is responsible for handling it. If it needs help, it should speak up.
Look at the “normal” design between the application layer and the business object layer as an example. The app layer creates the business object, tells it to fetch data, updates each field independently, adds any detailed objects into it, and indicates that the data should be saved to the database. “Collect your homework. Put on your shoes. Put on your coat. Grab your backpack. Get in the car. Buckle up.”
Now look at an automous service. I am the user interface. I ask for data about an “invoice” and the service hands me a complete document (Data Transfer Object) filled with the data. It then goes away. I know what to do. I display the data and modify the document with updates. I then call the service and say “Here’s the document.” I don’t say “save it in a database, or check for duplicates.” I don’t sit waiting for error messages. I’ve checked the data and it is right.
If there is a problem on the service’s side, it doesn’t tell the me (the user interface). It copes. If the database is unavailable, the data is queued. If the “invoice” doesn’t already exist, the service creates one.
Errors still happen, of course. If the user doesn’t have the right to create an invoice, it responds with a “Negative Acknowledgement” and logs the event. If the invoice is for an unknown product, the invoice may be entered as “partial” and the document could enter a workflow for later resolution.
The point is that a service doesn’t know, can’t know, that its consumer is a user interface. It simply has rules, and follows them, without being told every little step.
The point is that the service acts more like an adult. The document that I give to the service is a statement of fact (“It is raining.”) and not a command (“Put on your coat”). The document simply provides information. The service may already know the information, but that’s OK. The service will be polite and say “thanks.”
That’s how adults behave.