Skip to content

Commit 42761ae

Browse files
committed
update documentation with missing piecese documented in v7 release notes
SoftInstigate/restheart#471
1 parent 1cbd5ad commit 42761ae

File tree

4 files changed

+105
-1
lines changed

4 files changed

+105
-1
lines changed

docs/graalvm.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,18 @@ In order to use Java or Kotlin plugins on RESTHeart native you must build them a
151151

152152
Refer to [Deploy Java Plugins On Restheart Native](https://restheart.org/docs/plugins/deploy/#deploy-java-plugins-on-restheart-native) for detailed instructions on how to do it.
153153

154+
### Automatic reflection configuration for plugins
155+
156+
Since RESTHeart v7, plugin reflection configuration for native images is handled automatically. RESTHeart implements a GraalVM feature that automatically generates the necessary reflection configuration for plugins annotated with `@RegisterPlugin`.
157+
158+
This means you no longer need to manually maintain `reflect-config.json` files for your plugins. The reflection configuration is automatically generated at build time, streamlining the development process for plugins that will be bundled in RESTHeart native builds.
159+
160+
The automatic reflection configuration covers:
161+
- Plugin classes annotated with `@RegisterPlugin`
162+
- Plugin initialization methods
163+
- Dependency injection fields and methods
164+
- Provider implementations
165+
154166
## build native image
155167

156168
Build image for local OS

docs/plugins/interceptors.adoc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,13 @@ The special interceptor interface, `WildcardInterceptor`, intercepts requests ha
2121
- `JsonInterceptor`: Intercepts requests handled by services implementing `JsonService`
2222
- `BsonInterceptor`: Intercepts requests handled by services implementing `BsonService`
2323
- `MongoInterceptor`: Intercepts requests handled by the `MongoService`
24-
- `GraphQLInterceptor`: Intercepts GraphQL requests
24+
- `GraphQLInterceptor`: Intercepts GraphQL requests (available since RESTHeart v7)
2525
- `ProxyInterceptor`: Intercepts proxied requests
2626

2727
NOTE: `MongoInterceptor` is particularly useful as it allows intercepting requests to the `MongoService`, adding logic to its data API. For instance, the following response interceptor removes the property `secret` from `GET /coll`.
2828

29+
NOTE: `GraphQLInterceptor` became available in RESTHeart v7 when `GraphQLRequest` was moved to `restheart-commons`, enabling plugin developers to intercept and modify GraphQL requests and responses. This allows implementing custom logic such as query validation, result transformation, or access logging for GraphQL operations.
30+
2931
[source,java]
3032
----
3133
@RegisterPlugin(name = "secretFilter",

docs/plugins/services.adoc

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,12 +83,80 @@ The following table describes the arguments of the annotation for Services:
8383
|`true` to require successful authentication and authorization to be invoked; can be overridden by the service configuration option `secure`
8484
|no
8585
|`false`
86+
|`blocking`
87+
|`true` to execute the service in the worker thread pool (blocking mode), `false` to execute in the IO thread (non-blocking mode)
88+
|no
89+
|`true`
8690
|`dontIntercept`
8791
|list of interceptPoints to be executed on requests handled by the service, e.g. `dontIntercept = { InterceptPoint.ANY, InterceptPoint.RESPONSE }`
8892
|no
8993
|`{}`
9094
|===
9195

96+
=== Blocking vs Non-Blocking Services
97+
98+
RESTHeart allows you to control the execution model of your services using the `blocking` parameter in the `@RegisterPlugin` annotation.
99+
100+
==== Blocking Services (Default)
101+
102+
By default, services are executed in **blocking mode** (`blocking = true`). In this mode, when a request arrives, it is dispatched to a worker thread from the thread pool whose size is configured by the `worker-threads` parameter.
103+
104+
This concurrency model performs well for CPU-bound and blocking operations, such as:
105+
- MongoDB operations executed with the `mongodb-driver-sync`
106+
- Database queries
107+
- File I/O operations
108+
- Network calls to external services
109+
110+
[source,java]
111+
----
112+
@RegisterPlugin(
113+
name = "blocking-service",
114+
description = "A service that performs blocking operations",
115+
blocking = true) // Default value, can be omitted
116+
public class BlockingService implements JsonService {
117+
@Override
118+
public void handle(JsonRequest req, JsonResponse res) {
119+
// Blocking operation - this will be executed in a worker thread
120+
var result = performDatabaseQuery();
121+
res.setContent(result);
122+
}
123+
}
124+
----
125+
126+
==== Non-Blocking Services
127+
128+
For non-blocking operations, you can specify `blocking = false`. In this mode, the service is executed directly by the IO thread, avoiding the overhead of thread dispatching and context switching.
129+
130+
This approach follows the **Event Loop** concurrency model and can perform better for:
131+
- Reactive operations
132+
- Async computations
133+
- Services that don't perform blocking I/O
134+
135+
[source,java]
136+
----
137+
@RegisterPlugin(
138+
name = "non-blocking-service",
139+
description = "A service that performs non-blocking operations",
140+
blocking = false) // Enable non-blocking mode
141+
public class NonBlockingService implements JsonService {
142+
@Override
143+
public void handle(JsonRequest req, JsonResponse res) {
144+
// Non-blocking operation - executed directly by IO thread
145+
var result = performAsyncComputation();
146+
res.setContent(result);
147+
}
148+
}
149+
----
150+
151+
==== Performance Considerations
152+
153+
- **Blocking services**: Better for CPU-intensive tasks and operations that involve waiting for I/O
154+
- **Non-blocking services**: Better for lightweight operations and reactive programming patterns
155+
156+
WARNING: Be careful not to perform blocking operations (like database calls) in non-blocking services, as this will block the IO thread and negatively impact performance.
157+
158+
Since RESTHeart uses Virtual Threads, there are virtually no limits on the number of blocking threads.
159+
92160
=== Service with custom generic types
93161

94162
To implement a `Service` that handles different types of `Request` and `Response`, it must implement the base `Service` interface.

docs/upgrade-to-v8.adoc

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,28 @@ public void init() {
295295
}
296296
```
297297

298+
=== MongoService Driver Update
299+
300+
RESTHeart v8 completes the migration from `mongo-driver-legacy` to `mongo-driver-sync` that was started in v7.
301+
302+
*Impact for Plugin Developers*
303+
304+
This change affects plugins that:
305+
- Use `@Inject("mclient")` to access the MongoDB client
306+
- Interact with MongoDB through the MongoService
307+
- Implement custom MongoDB operations
308+
309+
*Benefits*
310+
311+
- Improved performance and stability
312+
- Better alignment with MongoDB's current driver architecture
313+
- Enhanced support for modern MongoDB features
314+
- Consistent synchronous API patterns
315+
316+
*Migration Notes*
317+
318+
No code changes are required for existing plugins using `@Inject("mclient")`, as the injected `MongoClient` interface remains the same. The underlying implementation has been updated to use the modern MongoDB driver.
319+
298320
=== Lazy-load Request Content
299321

300322
Up to RESTHeart v7, requests processed by the `MongoService` are designed to lazy-load their content. This means that the request body is only read when `MongoRequest.getContent()` is invoked for the first time.

0 commit comments

Comments
 (0)