From 68fce152f681853bdc4ba608638643be690ae48b Mon Sep 17 00:00:00 2001 From: "Tj (bougyman) Vanderpoel" Date: Sun, 3 Aug 2025 20:30:25 -0500 Subject: [PATCH 01/19] removes ractor references --- doc/service-api-vs-rest.adoc | 85 ++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 doc/service-api-vs-rest.adoc diff --git a/doc/service-api-vs-rest.adoc b/doc/service-api-vs-rest.adoc new file mode 100644 index 0000000..6d9c960 --- /dev/null +++ b/doc/service-api-vs-rest.adoc @@ -0,0 +1,85 @@ += Leopard Service-API Whitepaper +:revdate: 2025-08-03 +:doctype: whitepaper + +== Abstract +Leopard’s NATS Service-API brings full-featured service-to-service communication—complete with discovery, health checks, per-endpoint scaling, and observability—while preserving the simplicity and resilience of asynchronous messaging. This paper contrasts Leopard’s model with traditional REST, outlines its key benefits and trade-offs, and illustrates how Leopard can streamline microservice architectures. + +== 1. Introduction +Microservices communicate most often via HTTP/REST today, but REST comes with overhead: service registries, load-balancers, schema/version endpoints, and brittle synchronous request patterns. Leopard leverages NATS’s Service-API layer to deliver: +* **Automatic discovery** via `$SRV.PING/INFO/​STATS` subjects +* **Dynamic load-balanced routing** with queue groups +* **Built-in telemetry** (per-endpoint request counts, latencies, errors) +* **Scalable workers** (Concurrent::FixedThreadPool currently) +* **Asynchronous decoupling** for resilient flows + +== 2. Architecture Overview +Leopard embeds a “mini web-framework” in Ruby, registering each endpoint on a NATS subject and grouping instances for load-sharing: + +[mermaid,flowchart] +---- +flowchart LR + subgraph ServiceInstance + A[NatsApiServer.start] --> B(Registers endpoints) + end + subgraph NATS_Cluster + B --> C[$SRV.INFO.calc] + B --> D[calc.add queue group] + end + E[Client] -->|request("calc.add")| D + D --> F[Worker Thread pool] + F --> G[Handler & Dry::Monads] + G -->|respond()/respond_with_error()| E +---- + +== 3. Key Benefits + +=== 3.1 Automatic Discovery & Monitoring +Leopard services auto-advertise on well-known NATS subjects. Clients can query: +* `$SRV.PING.` – discover live instances & measure RTT +* `$SRV.INFO.` – retrieve endpoint schemas & metadata +* `$SRV.STATS.` – fetch per-endpoint metrics + +No external service-registry (Consul, etcd) or custom HTTP health paths required. + +=== 3.2 Scaling-Per-Endpoint-Group +Each endpoint—registered with an optional queue group—enjoys native NATS queue-group load balancing. You can: +* Scale thread-pooled workers independently per service +* Horizontally add new service instances without redeploying clients +* Isolate hot-paths (e.g. “reports.generate”) onto dedicated worker farms + +=== 3.3 Observability & Telemetry +Leopard exposes stats out-of-the-box: +* Request counts, error counts, processing time +* Custom `on_stats` hooks for business metrics +* Integration with Prometheus or any NATS-capable dashboard + +=== 3.4 Asynchronous, Resilient Communication +Unlike blocking HTTP calls, Leopard’s NATS requests can: +* Employ timeouts, retries, and dead-letter queues +* Fit into event-driven pipelines, decoupling producers and consumers +* Maintain throughput under partial outages + +== 4. Comparison with REST +[cols="1,1", options="header"] +|=== +| Feature | REST (HTTP) | Leopard (NATS Service-API) + +| Discovery | External registry | Built-in `$SRV.*` subjects +| Load-balancing| HTTP LB or DNS | Native queue groups +| Telemetry | Custom endpoints | Auto-collected stats +| Latency | Higher overhead | Low-latency messaging +| Coupling | Synchronous | Async, decoupled +| Schema | Swagger/OpenAPI | Optional metadata on endpoints +|=== + +== 5. Trade-Offs & Considerations +. **Dependency on NATS** + Leopard requires a healthy NATS cluster; network partition or broker outage impacts all services. +. **Learning Curve** + Teams must understand NATS subjects, queue groups, and Service-API conventions. +. **Language Support** + While Leopard is Ruby-centric, NATS Service-API is cross-language—other teams must adopt compatible clients. + +== 6. Conclusion +Leopard’s NATS Service-API framework offers a powerful alternative to REST: zero-config discovery, per-endpoint scaling, rich observability, and asynchronous resilience. For high-throughput, low-latency microservice ecosystems, Leopard can simplify infrastructure, reduce boilerplate, and improve operational visibility—while retaining the expressiveness and composability of idiomatic Ruby. From 3caf21b1bb13580df1e1e7303776da4ececa35b4 Mon Sep 17 00:00:00 2001 From: "Tj (bougyman) Vanderpoel" Date: Sun, 3 Aug 2025 20:31:43 -0500 Subject: [PATCH 02/19] fix: corrects mermaid declaration --- doc/service-api-vs-rest.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/service-api-vs-rest.adoc b/doc/service-api-vs-rest.adoc index 6d9c960..17e6816 100644 --- a/doc/service-api-vs-rest.adoc +++ b/doc/service-api-vs-rest.adoc @@ -16,7 +16,7 @@ Microservices communicate most often via HTTP/REST today, but REST comes with ov == 2. Architecture Overview Leopard embeds a “mini web-framework” in Ruby, registering each endpoint on a NATS subject and grouping instances for load-sharing: -[mermaid,flowchart] +[source,mermaid] ---- flowchart LR subgraph ServiceInstance From 544f998ea14ba500ba313535a326ff31ffd4111d Mon Sep 17 00:00:00 2001 From: "Tj (bougyman) Vanderpoel" Date: Sun, 3 Aug 2025 20:33:21 -0500 Subject: [PATCH 03/19] fix: corrects mermaid declaration --- doc/service-api-vs-rest.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/service-api-vs-rest.adoc b/doc/service-api-vs-rest.adoc index 17e6816..1dffd89 100644 --- a/doc/service-api-vs-rest.adoc +++ b/doc/service-api-vs-rest.adoc @@ -27,7 +27,7 @@ flowchart LR B --> D[calc.add queue group] end E[Client] -->|request("calc.add")| D - D --> F[Worker Thread pool] + D --> F[Worker Ractor pool] F --> G[Handler & Dry::Monads] G -->|respond()/respond_with_error()| E ---- From 004990ff7bddd111d8dcbfae63420b705ebf9d54 Mon Sep 17 00:00:00 2001 From: "Tj (bougyman) Vanderpoel" Date: Sun, 3 Aug 2025 20:35:22 -0500 Subject: [PATCH 04/19] fix: corrects mermaid declaration --- doc/service-api-vs-rest.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/service-api-vs-rest.adoc b/doc/service-api-vs-rest.adoc index 1dffd89..2d14736 100644 --- a/doc/service-api-vs-rest.adoc +++ b/doc/service-api-vs-rest.adoc @@ -26,7 +26,7 @@ flowchart LR B --> C[$SRV.INFO.calc] B --> D[calc.add queue group] end - E[Client] -->|request("calc.add")| D + E[Client] -->|request(calc.add)| D D --> F[Worker Ractor pool] F --> G[Handler & Dry::Monads] G -->|respond()/respond_with_error()| E From 52c2fa6bb8feeb5abd7ef6bf08965b53be0f5765 Mon Sep 17 00:00:00 2001 From: "Tj (bougyman) Vanderpoel" Date: Sun, 3 Aug 2025 20:36:46 -0500 Subject: [PATCH 05/19] fix: corrects mermaid declaration --- doc/service-api-vs-rest.adoc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/service-api-vs-rest.adoc b/doc/service-api-vs-rest.adoc index 2d14736..801c1d5 100644 --- a/doc/service-api-vs-rest.adoc +++ b/doc/service-api-vs-rest.adoc @@ -18,15 +18,15 @@ Leopard embeds a “mini web-framework” in Ruby, registering each endpoint on [source,mermaid] ---- -flowchart LR +graph LR subgraph ServiceInstance - A[NatsApiServer.start] --> B(Registers endpoints) + A[NatsApiServer.start] --> B[Registers endpoints] end subgraph NATS_Cluster - B --> C[$SRV.INFO.calc] - B --> D[calc.add queue group] + B --> C["$SRV.INFO.calc"] + B --> D["calc.add queue group"] end - E[Client] -->|request(calc.add)| D + E[Client] -->|request("calc.add")| D D --> F[Worker Ractor pool] F --> G[Handler & Dry::Monads] G -->|respond()/respond_with_error()| E From 6f5825b96e805b2f6a7b6296d3906277990fff17 Mon Sep 17 00:00:00 2001 From: "Tj (bougyman) Vanderpoel" Date: Sun, 3 Aug 2025 20:39:24 -0500 Subject: [PATCH 06/19] fix: corrects mermaid declaration --- doc/service-api-vs-rest.adoc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/service-api-vs-rest.adoc b/doc/service-api-vs-rest.adoc index 801c1d5..74dcab6 100644 --- a/doc/service-api-vs-rest.adoc +++ b/doc/service-api-vs-rest.adoc @@ -26,10 +26,10 @@ graph LR B --> C["$SRV.INFO.calc"] B --> D["calc.add queue group"] end - E[Client] -->|request("calc.add")| D + E[Client] -->|request calc.add| D D --> F[Worker Ractor pool] - F --> G[Handler & Dry::Monads] - G -->|respond()/respond_with_error()| E + F --> G[Handler & Dry Monads] + G -->|respond or error| E ---- == 3. Key Benefits From 33380ce685293f8b598d0d1ee77d00dfeb42f7fc Mon Sep 17 00:00:00 2001 From: "Tj (bougyman) Vanderpoel" Date: Sun, 3 Aug 2025 20:40:16 -0500 Subject: [PATCH 07/19] doc: remove reference to Ractor --- doc/service-api-vs-rest.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/service-api-vs-rest.adoc b/doc/service-api-vs-rest.adoc index 74dcab6..8ec6b84 100644 --- a/doc/service-api-vs-rest.adoc +++ b/doc/service-api-vs-rest.adoc @@ -27,7 +27,7 @@ graph LR B --> D["calc.add queue group"] end E[Client] -->|request calc.add| D - D --> F[Worker Ractor pool] + D --> F[Worker Thread pool] F --> G[Handler & Dry Monads] G -->|respond or error| E ---- From 4dd0f0897c1d661125b10586c20ecf7643ec5c9a Mon Sep 17 00:00:00 2001 From: "Tj (bougyman) Vanderpoel" Date: Sun, 3 Aug 2025 20:40:46 -0500 Subject: [PATCH 08/19] doc: remove reference to Ractor --- doc/service-api-vs-rest.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/service-api-vs-rest.adoc b/doc/service-api-vs-rest.adoc index 8ec6b84..8bf21f1 100644 --- a/doc/service-api-vs-rest.adoc +++ b/doc/service-api-vs-rest.adoc @@ -20,7 +20,7 @@ Leopard embeds a “mini web-framework” in Ruby, registering each endpoint on ---- graph LR subgraph ServiceInstance - A[NatsApiServer.start] --> B[Registers endpoints] + A[NatsApiServer.run] --> B[Registers endpoints] end subgraph NATS_Cluster B --> C["$SRV.INFO.calc"] From ad54e5a06af12f8e5600bc352b161fdcee6c0ed6 Mon Sep 17 00:00:00 2001 From: "Tj (bougyman) Vanderpoel" Date: Sun, 3 Aug 2025 20:47:40 -0500 Subject: [PATCH 09/19] doc: remove reference to Ractor --- doc/service-api-vs-rest.adoc | 47 +++++++++++++++++++++++++++++------- 1 file changed, 38 insertions(+), 9 deletions(-) diff --git a/doc/service-api-vs-rest.adoc b/doc/service-api-vs-rest.adoc index 8bf21f1..5673dd5 100644 --- a/doc/service-api-vs-rest.adoc +++ b/doc/service-api-vs-rest.adoc @@ -61,16 +61,45 @@ Unlike blocking HTTP calls, Leopard’s NATS requests can: * Maintain throughput under partial outages == 4. Comparison with REST -[cols="1,1", options="header"] +[cols="1,1,1", options="header"] |=== -| Feature | REST (HTTP) | Leopard (NATS Service-API) - -| Discovery | External registry | Built-in `$SRV.*` subjects -| Load-balancing| HTTP LB or DNS | Native queue groups -| Telemetry | Custom endpoints | Auto-collected stats -| Latency | Higher overhead | Low-latency messaging -| Coupling | Synchronous | Async, decoupled -| Schema | Swagger/OpenAPI | Optional metadata on endpoints +| Feature | REST (HTTP) | NATS Service-API + +| Discovery +| Requires external service registry or API gateway +| Built-in via `$SRV.PING`, `$SRV.INFO`, `$SRV.STATS`—works uniformly across all languages + +| Load Balancing +| HTTP load balancer or DNS round-robin +| Native queue-group load balancing per subject + +| Telemetry +| Custom instrumentation (e.g., `/metrics` endpoint) +| Auto-collected stats (`service.stats`) and `on_stats` hooks + +| Latency & Overhead +| Higher (HTTP/TCP handshake, headers, JSON) +| Low-latency binary protocol with optional JSON payloads + +| Communication Model +| Synchronous, blocking request/response +| Asynchronous request/reply, decoupled via subjects + +| Schema & Validation +| OpenAPI/Swagger externally managed +| Optional metadata on endpoints + pluggable middleware + +| Error Handling +| HTTP status codes and response bodies +| Standardized error headers (`Nats-Service-Error`, `Nats-Service-Error-Code`) + +| Multi-Language Support +| Varies by framework; patterns differ per language +| Uniform Service-API semantics with native clients in all major languages + +| Scalability +| Scale replicas behind LB +| Scale Ractor/thread pools + horizontal instances independently |=== == 5. Trade-Offs & Considerations From 5c9a1ffcfe3e2b627961fb41d08e20494dc081d3 Mon Sep 17 00:00:00 2001 From: "Tj (bougyman) Vanderpoel" Date: Sun, 3 Aug 2025 20:57:16 -0500 Subject: [PATCH 10/19] doc: remove reference to Ractor --- doc/service-api-vs-rest.adoc | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/doc/service-api-vs-rest.adoc b/doc/service-api-vs-rest.adoc index 5673dd5..126bbc9 100644 --- a/doc/service-api-vs-rest.adoc +++ b/doc/service-api-vs-rest.adoc @@ -66,8 +66,8 @@ Unlike blocking HTTP calls, Leopard’s NATS requests can: | Feature | REST (HTTP) | NATS Service-API | Discovery -| Requires external service registry or API gateway -| Built-in via `$SRV.PING`, `$SRV.INFO`, `$SRV.STATS`—works uniformly across all languages +| Requires external service registry or API gateway, A.K.A. "it's always DNS" +| Built-in via `$SRV.PING`, `$SRV.INFO`, `$SRV.STATS` Works uniformly across all languages | Load Balancing | HTTP load balancer or DNS round-robin @@ -79,7 +79,7 @@ Unlike blocking HTTP calls, Leopard’s NATS requests can: | Latency & Overhead | Higher (HTTP/TCP handshake, headers, JSON) -| Low-latency binary protocol with optional JSON payloads +| Low-latency binary protocol with optional JSON payloads (other formats supported with plugins) | Communication Model | Synchronous, blocking request/response @@ -99,16 +99,32 @@ Unlike blocking HTTP calls, Leopard’s NATS requests can: | Scalability | Scale replicas behind LB -| Scale Ractor/thread pools + horizontal instances independently +| Scale thread pools vertically + horizontal instances independently, by endpoint groups (or even a single endpoint) |=== == 5. Trade-Offs & Considerations . **Dependency on NATS** - Leopard requires a healthy NATS cluster; network partition or broker outage impacts all services. + Leopard requires a healthy NATS cluster; network partition or broker outage impacts all services. (This is not unlike Redis or Postgres dependencies) . **Learning Curve** - Teams must understand NATS subjects, queue groups, and Service-API conventions. + Teams must understand NATS subjects, queue groups, and Service-API conventions. (Easier with helpers like Leopard’s `NatsApiServer`.) . **Language Support** - While Leopard is Ruby-centric, NATS Service-API is cross-language—other teams must adopt compatible clients. - -== 6. Conclusion -Leopard’s NATS Service-API framework offers a powerful alternative to REST: zero-config discovery, per-endpoint scaling, rich observability, and asynchronous resilience. For high-throughput, low-latency microservice ecosystems, Leopard can simplify infrastructure, reduce boilerplate, and improve operational visibility—while retaining the expressiveness and composability of idiomatic Ruby. + While Leopard is Ruby-centric, NATS Service-API is cross-language—other teams must adopt compatible clients. (And handle concurrency and error handling in their own way.) +. **Subject Naming** + Adopting a consistent naming convention for subjects is crucial. This can be a challenge in large teams. + NATS can support a massive number of subjects. But to avoid confusion, subjects should have + clear, descriptive names that reflect the service and endpoint purpose. + There could (should?) be a central authoritative + document that defines the subject structure and naming conventions. + There should also be a "registry" of subjects, + that can be queried by developers to discover available subjects. + This can avoid confusion and ensure that all developers are on the same page and not conflicting with one another. + +== 6. What, then? +Leopard’s NATS Service-API framework offers a powerful alternative to REST: +zero-config discovery, per-endpoint scaling, rich observability, and asynchronous resilience. + +For high-throughput, low-latency microservice (nano-service?) ecosystems, Leopard can simplify infrastructure, +reduce boilerplate, and improve operational visibility. + +Leopard's aim is to retain the expressiveness and composability of idiomatic Ruby, while leveraging +NATS's ServiceApi performance and flexibility. From dadc08eabf7e10a9d3ac85b20ee3cd381e6fcccb Mon Sep 17 00:00:00 2001 From: "Tj (bougyman) Vanderpoel" Date: Sun, 3 Aug 2025 21:00:56 -0500 Subject: [PATCH 11/19] doc: remove reference to Ractor --- doc/service-api-vs-rest.adoc | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/doc/service-api-vs-rest.adoc b/doc/service-api-vs-rest.adoc index 126bbc9..1dc7e86 100644 --- a/doc/service-api-vs-rest.adoc +++ b/doc/service-api-vs-rest.adoc @@ -3,10 +3,17 @@ :doctype: whitepaper == Abstract -Leopard’s NATS Service-API brings full-featured service-to-service communication—complete with discovery, health checks, per-endpoint scaling, and observability—while preserving the simplicity and resilience of asynchronous messaging. This paper contrasts Leopard’s model with traditional REST, outlines its key benefits and trade-offs, and illustrates how Leopard can streamline microservice architectures. +Leopard’s NATS Service-API brings full-featured service-to-service communication, comparable with REST/GRPC. +Complete with discovery, health checks, per-endpoint scaling, and observability. +Preserving the simplicity and resilience of asynchronous messaging, under the hood. +This paper contrasts the NATS ServiceApi model with traditional REST, +outlines its key benefits and trade-offs, +and illustrates how Leopard can streamline microservice (and nanoservice) architectures. == 1. Introduction -Microservices communicate most often via HTTP/REST today, but REST comes with overhead: service registries, load-balancers, schema/version endpoints, and brittle synchronous request patterns. Leopard leverages NATS’s Service-API layer to deliver: +Microservices communicate most often via HTTP/REST today, but REST comes with overhead: service registries, +load-balancers, schema/version endpoints, and brittle synchronous request patterns. +Leopard leverages NATS’s Service-API layer to deliver: * **Automatic discovery** via `$SRV.PING/INFO/​STATS` subjects * **Dynamic load-balanced routing** with queue groups * **Built-in telemetry** (per-endpoint request counts, latencies, errors) From 465bfae6e38251be66154fae6ab03f541e25a3fb Mon Sep 17 00:00:00 2001 From: "Tj (bougyman) Vanderpoel" Date: Sun, 3 Aug 2025 21:03:46 -0500 Subject: [PATCH 12/19] doc: remove reference to Ractor --- doc/service-api-vs-rest.adoc | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/service-api-vs-rest.adoc b/doc/service-api-vs-rest.adoc index 1dc7e86..b702d71 100644 --- a/doc/service-api-vs-rest.adoc +++ b/doc/service-api-vs-rest.adoc @@ -14,6 +14,7 @@ and illustrates how Leopard can streamline microservice (and nanoservice) archit Microservices communicate most often via HTTP/REST today, but REST comes with overhead: service registries, load-balancers, schema/version endpoints, and brittle synchronous request patterns. Leopard leverages NATS’s Service-API layer to deliver: + * **Automatic discovery** via `$SRV.PING/INFO/​STATS` subjects * **Dynamic load-balanced routing** with queue groups * **Built-in telemetry** (per-endpoint request counts, latencies, errors) From 4df21b631d07b76fcb8202d7a5c83dd403cabeb3 Mon Sep 17 00:00:00 2001 From: "Tj (bougyman) Vanderpoel" Date: Sun, 3 Aug 2025 21:08:20 -0500 Subject: [PATCH 13/19] doc: remove reference to Ractor --- doc/service-api-vs-rest.adoc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/service-api-vs-rest.adoc b/doc/service-api-vs-rest.adoc index b702d71..e0b4b57 100644 --- a/doc/service-api-vs-rest.adoc +++ b/doc/service-api-vs-rest.adoc @@ -44,6 +44,7 @@ graph LR === 3.1 Automatic Discovery & Monitoring Leopard services auto-advertise on well-known NATS subjects. Clients can query: + * `$SRV.PING.` – discover live instances & measure RTT * `$SRV.INFO.` – retrieve endpoint schemas & metadata * `$SRV.STATS.` – fetch per-endpoint metrics @@ -52,18 +53,21 @@ No external service-registry (Consul, etcd) or custom HTTP health paths required === 3.2 Scaling-Per-Endpoint-Group Each endpoint—registered with an optional queue group—enjoys native NATS queue-group load balancing. You can: + * Scale thread-pooled workers independently per service * Horizontally add new service instances without redeploying clients * Isolate hot-paths (e.g. “reports.generate”) onto dedicated worker farms === 3.3 Observability & Telemetry Leopard exposes stats out-of-the-box: + * Request counts, error counts, processing time * Custom `on_stats` hooks for business metrics * Integration with Prometheus or any NATS-capable dashboard === 3.4 Asynchronous, Resilient Communication Unlike blocking HTTP calls, Leopard’s NATS requests can: + * Employ timeouts, retries, and dead-letter queues * Fit into event-driven pipelines, decoupling producers and consumers * Maintain throughput under partial outages From 2dd772c703a85505258074780361ace320e9e3fb Mon Sep 17 00:00:00 2001 From: "Tj (bougyman) Vanderpoel" Date: Sun, 3 Aug 2025 21:12:13 -0500 Subject: [PATCH 14/19] doc: remove reference to Ractor --- doc/service-api-vs-rest.adoc | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/service-api-vs-rest.adoc b/doc/service-api-vs-rest.adoc index e0b4b57..136ea81 100644 --- a/doc/service-api-vs-rest.adoc +++ b/doc/service-api-vs-rest.adoc @@ -20,6 +20,7 @@ Leopard leverages NATS’s Service-API layer to deliver: * **Built-in telemetry** (per-endpoint request counts, latencies, errors) * **Scalable workers** (Concurrent::FixedThreadPool currently) * **Asynchronous decoupling** for resilient flows +* **Versioned endpoints** multiple versions can be registered concurrently, no need for /v1, /v2, etc. == 2. Architecture Overview Leopard embeds a “mini web-framework” in Ruby, registering each endpoint on a NATS subject and grouping instances for load-sharing: From 37e6016c74ebfae9700f4d1f23ee1e5857b4bcb9 Mon Sep 17 00:00:00 2001 From: "Tj (bougyman) Vanderpoel" Date: Sun, 3 Aug 2025 21:19:17 -0500 Subject: [PATCH 15/19] doc: remove reference to Ractor --- doc/service-api-vs-rest.adoc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/service-api-vs-rest.adoc b/doc/service-api-vs-rest.adoc index 136ea81..f9ffeca 100644 --- a/doc/service-api-vs-rest.adoc +++ b/doc/service-api-vs-rest.adoc @@ -53,7 +53,8 @@ Leopard services auto-advertise on well-known NATS subjects. Clients can query: No external service-registry (Consul, etcd) or custom HTTP health paths required. === 3.2 Scaling-Per-Endpoint-Group -Each endpoint—registered with an optional queue group—enjoys native NATS queue-group load balancing. You can: +Each endpoint (mapped to a NATS subject) is registered with an optional queue group. +This allows it to enjoy native NATS queue-group load balancing. You can: * Scale thread-pooled workers independently per service * Horizontally add new service instances without redeploying clients From f4809b2994d14715f2a45afe655a089112b8ce80 Mon Sep 17 00:00:00 2001 From: "Tj (bougyman) Vanderpoel" Date: Sun, 3 Aug 2025 21:56:51 -0500 Subject: [PATCH 16/19] docs: Removed fluff language --- doc/service-api-vs-rest.adoc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/doc/service-api-vs-rest.adoc b/doc/service-api-vs-rest.adoc index f9ffeca..6c2f6e6 100644 --- a/doc/service-api-vs-rest.adoc +++ b/doc/service-api-vs-rest.adoc @@ -18,8 +18,7 @@ Leopard leverages NATS’s Service-API layer to deliver: * **Automatic discovery** via `$SRV.PING/INFO/​STATS` subjects * **Dynamic load-balanced routing** with queue groups * **Built-in telemetry** (per-endpoint request counts, latencies, errors) -* **Scalable workers** (Concurrent::FixedThreadPool currently) -* **Asynchronous decoupling** for resilient flows +* **Scalable workers** (Concurrent::FixedThreadPool with Leopard, currently) * **Versioned endpoints** multiple versions can be registered concurrently, no need for /v1, /v2, etc. == 2. Architecture Overview From 5c16a55a5b0ab3e7fc008575105982a4c0b9e2e3 Mon Sep 17 00:00:00 2001 From: "Tj (bougyman) Vanderpoel" Date: Sun, 3 Aug 2025 22:01:53 -0500 Subject: [PATCH 17/19] doc: adds clarity to intro --- doc/service-api-vs-rest.adoc | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/doc/service-api-vs-rest.adoc b/doc/service-api-vs-rest.adoc index 6c2f6e6..58239ac 100644 --- a/doc/service-api-vs-rest.adoc +++ b/doc/service-api-vs-rest.adoc @@ -3,12 +3,13 @@ :doctype: whitepaper == Abstract -Leopard’s NATS Service-API brings full-featured service-to-service communication, comparable with REST/GRPC. -Complete with discovery, health checks, per-endpoint scaling, and observability. -Preserving the simplicity and resilience of asynchronous messaging, under the hood. -This paper contrasts the NATS ServiceApi model with traditional REST, -outlines its key benefits and trade-offs, -and illustrates how Leopard can streamline microservice (and nanoservice) architectures. +Leopard’s NATS ServiceApi wrapper delivers full-featured service-to-service communication, comparable with REST/GRPC. +With NATS, you get complete with discovery, health checks, per-endpoint scaling, and observability. +This abstraction preserves the simplicity of REST request with the resilience of asynchronous messaging +under the hood. + +This paper contrasts the NATS ServiceApi model with traditional REST, outlines its key benefits and trade-offs, +and illustrates how Leopard can specifically streamline microservice (and nanoservice) architectures. == 1. Introduction Microservices communicate most often via HTTP/REST today, but REST comes with overhead: service registries, From 1adf87c1b167bc0e8e2bb88baa6f9ec0b38a943a Mon Sep 17 00:00:00 2001 From: "Tj (bougyman) Vanderpoel" Date: Sun, 3 Aug 2025 22:03:03 -0500 Subject: [PATCH 18/19] doc: adds clarity to intro --- doc/service-api-vs-rest.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/service-api-vs-rest.adoc b/doc/service-api-vs-rest.adoc index 58239ac..2f8c3fd 100644 --- a/doc/service-api-vs-rest.adoc +++ b/doc/service-api-vs-rest.adoc @@ -1,4 +1,4 @@ -= Leopard Service-API Whitepaper += NATS ServiceApi (via Leopard) vs REST :revdate: 2025-08-03 :doctype: whitepaper From d36ce4b3931076ab0e263fe602f57ff2bb9de370 Mon Sep 17 00:00:00 2001 From: "Tj (bougyman) Vanderpoel" Date: Sun, 3 Aug 2025 22:05:05 -0500 Subject: [PATCH 19/19] doc: consistency with ServiceApi --- doc/service-api-vs-rest.adoc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/service-api-vs-rest.adoc b/doc/service-api-vs-rest.adoc index 2f8c3fd..71c7d05 100644 --- a/doc/service-api-vs-rest.adoc +++ b/doc/service-api-vs-rest.adoc @@ -14,7 +14,7 @@ and illustrates how Leopard can specifically streamline microservice (and nanose == 1. Introduction Microservices communicate most often via HTTP/REST today, but REST comes with overhead: service registries, load-balancers, schema/version endpoints, and brittle synchronous request patterns. -Leopard leverages NATS’s Service-API layer to deliver: +Leopard leverages NATS’s ServiceApi layer to deliver: * **Automatic discovery** via `$SRV.PING/INFO/​STATS` subjects * **Dynamic load-balanced routing** with queue groups @@ -77,7 +77,7 @@ Unlike blocking HTTP calls, Leopard’s NATS requests can: == 4. Comparison with REST [cols="1,1,1", options="header"] |=== -| Feature | REST (HTTP) | NATS Service-API +| Feature | REST (HTTP) | NATS ServiceApi | Discovery | Requires external service registry or API gateway, A.K.A. "it's always DNS" @@ -109,7 +109,7 @@ Unlike blocking HTTP calls, Leopard’s NATS requests can: | Multi-Language Support | Varies by framework; patterns differ per language -| Uniform Service-API semantics with native clients in all major languages +| Uniform ServiceApi semantics with native clients in all major languages | Scalability | Scale replicas behind LB @@ -120,9 +120,9 @@ Unlike blocking HTTP calls, Leopard’s NATS requests can: . **Dependency on NATS** Leopard requires a healthy NATS cluster; network partition or broker outage impacts all services. (This is not unlike Redis or Postgres dependencies) . **Learning Curve** - Teams must understand NATS subjects, queue groups, and Service-API conventions. (Easier with helpers like Leopard’s `NatsApiServer`.) + Teams must understand NATS subjects, queue groups, and ServiceApi conventions. (Easier with helpers like Leopard’s `NatsApiServer`.) . **Language Support** - While Leopard is Ruby-centric, NATS Service-API is cross-language—other teams must adopt compatible clients. (And handle concurrency and error handling in their own way.) + While Leopard is Ruby-centric, NATS ServiceApi is cross-language—other teams must adopt compatible clients. (And handle concurrency and error handling in their own way.) . **Subject Naming** Adopting a consistent naming convention for subjects is crucial. This can be a challenge in large teams. NATS can support a massive number of subjects. But to avoid confusion, subjects should have @@ -134,7 +134,7 @@ Unlike blocking HTTP calls, Leopard’s NATS requests can: This can avoid confusion and ensure that all developers are on the same page and not conflicting with one another. == 6. What, then? -Leopard’s NATS Service-API framework offers a powerful alternative to REST: +Leopard’s NATS ServiceApi framework offers a powerful alternative to REST: zero-config discovery, per-endpoint scaling, rich observability, and asynchronous resilience. For high-throughput, low-latency microservice (nano-service?) ecosystems, Leopard can simplify infrastructure,