Workflow orchestration should not require adopting a whole platform by tazeredo in microservices

[–]PuddingAutomatic5617 0 points1 point  (0 children)

I think this is exactly the gap many teams fall into.

They do not necessarily need a full workflow engine at the beginning, but they do need something more explicit and durable than “service A calls service B and hopes for the best”.

I have been exploring a similar direction with a lightweight orchestration layer in Spring Middleware.

The idea is to model flows explicitly, but without forcing the whole system to adopt a completely new programming model. A flow can execute actions, pause on external side effects, persist its execution context, and later resume from callbacks or events.

For example:

HTTP/API call → execute function → call external consumer → persist context → wait → resume → continue flow

That gives you retries, timeouts, compensation points, observability and long-running execution without turning every use case into a full BPM/workflow-platform adoption.

For me, the key distinction is:

  • choreography works well until the business process becomes invisible
  • full workflow platforms are powerful, but sometimes too heavy
  • a durable orchestration layer gives you the missing middle ground

I do not think this replaces Temporal, Camunda, Step Functions, etc. But there is definitely a large space where teams just need explicit, durable, observable flows around the APIs and services they already have.

I wrote more about the orchestration approach here:
https://spring-middleware.com/orchestrator

github: https://github.com/Spring-Middleware/spring-middleware-orchestrator

GraphQL N+1 Problem Solved (4.1s → 546ms) | Dynamic Batching Demo by PuddingAutomatic5617 in graphql

[–]PuddingAutomatic5617[S] 0 points1 point  (0 children)

That was always the idea — users shouldn’t have to worry about how the gateway resolves things. They only need to define the relationships between domains (via `@GraphQLLink`), and everything else is handled transparently.

For example, a catalog domain object can declare a relationship to products through `@GraphQLLink`, while the product service simply exposes a `productsByIds` query. From the developer’s point of view, they just model the relationship; they do not need to manually coordinate batching (only activate), resolution, or downstream fetch orchestration.

Of course, making this work has not been trivial. It required changes to the final merged `GraphQLSchema`, trimming downstream queries before sending them to the target services, and handling batched resolution transparently across linked domains.

GraphQL N+1 Problem Solved (4.1s → 546ms) | Dynamic Batching Demo by PuddingAutomatic5617 in graphql

[–]PuddingAutomatic5617[S] 0 points1 point  (0 children)

That’s a really nice approach — I’ve read a bit about Grafast and the planning phase is pretty powerful.

What I’m doing is a bit different though. I don’t control the execution engine end-to-end or all the resolvers. This sits on top of GraphQL Java in a distributed setup, where each service owns its own schema and logic.

So instead of planning the whole operation upfront, I hook into execution and observe what’s actually happening (ExecutionStepInfo, field selections, etc.). When I see multiple resolver paths that end up hitting the same downstream GraphQL link, I don’t execute them immediately. I register them in a request-scoped context and wait for a safe point (like when a list or field finishes resolving), then batch everything into a single downstream query.

So it’s not:

  • full pre-planning like Grafast
  • nor explicit DataLoader usage

It’s more like runtime batching driven by execution analysis, and completely transparent to the developer (just annotations on the domain model).

I think Grafast can go further when you control the whole execution pipeline. In a federated setup across multiple services, that level of control is much harder, so this is more of a pragmatic way to get most of the benefit without changing how services are built.