\ No newline at end of file
diff --git a/flash/request-handler.md b/flash/request-handler.md
index 6562c0a..ff88096 100644
--- a/flash/request-handler.md
+++ b/flash/request-handler.md
@@ -11,19 +11,14 @@ In this section, we illustrate the powerful concept of `RequestHandler` in Flash
To create a custom request handler, you need to extend the `RequestHandler` class and annotate the class with the `RouteInfo` annotation,
specifying the HTTP method that the handler will respond to and the relative path that the handler will be registered to.
-The `enforceNonNullBody` attribute is used to specify whether the handler expects a non-null request body: by default, it is set to `false`.
After that, you must override the `handle` method;
The `handle` method is where you define the logic for processing the request and generating the response.
The `req` (request) and `res` (response) objects are available in the handler to access the request data and send the response back to the client.
You must call the super constructor with the `req` and `res` objects to initialize the handler.
-```java{5,8}
-import flash.Request;
-import flash.Response;
-import flash.RequestHandler;
-
-@RouteInfo(method = HttpMethod.GET, path = "/hello", enforceNonNullBody = false)
+```java{1,4}
+@RouteInfo(method = HttpMethod.GET, path = "/hello")
public class MyHandler extends RequestHandler {
public MyHandler(Request req, Response res) {
super(req, res);
diff --git a/flash/request-response.md b/flash/request-response.md
index 6c2a3f4..0d2f34f 100644
--- a/flash/request-response.md
+++ b/flash/request-response.md
@@ -50,13 +50,8 @@ The `ExpectedRequestParameter`, `ExpectedBodyField`, and `ExpectedBodyFile` inst
The `ExpectedRequestParameter` object is used to get the expected parameters of the request.
You can use the getter methods to safely get the parameter value, such as `getString`, `getInt`, `getDouble`, and `getBoolean` methods to safely cast the parameter to the expected type.
-```java{8,11,16}
-import flash.Request;
-import flash.Response;
-import flash.models.RequestHandler;
-import flash.models.ExpectedRequestParameter;
-
-@RouteInfo(method = HttpMethod.GET, path = "/hello", enforceNonNullBody = false)
+```java{4,8,18,21}
+@RouteInfo(method = HttpMethod.GET, path = "/hello")
public class MyHandler extends RequestHandler {
// Store the expected parameter in a private field
private final ExpectedRequestParameter myExpectedReqParam;
@@ -89,14 +84,8 @@ Visiting `/hello?myParam=John` from your browser, will return `Hello, John!`.
The `ExpectedBodyField` object is used to get the expected fields of the request body.
You can use the getter methods to safely get the field value, such as `getString`, `getInt`, `getDouble`, and `getBoolean` methods to safely cast the field to the expected type.
-```java{8,11,16}
-import flash.Request;
-import flash.Response;
-import flash.models.RequestHandler;
-import flash.models.ExpectedBodyField;
-
-// Make sure to set enforceNonNullBody to true
-@RouteInfo(method = HttpMethod.GET, path = "/helloBody", enforceNonNullBody = true)
+```java{4,8,18,21}
+@RouteInfo(method = HttpMethod.GET, path = "/helloBody")
public class MyHandler extends RequestHandler {
// Store the expected field in a private field
private final ExpectedBodyField myExpectedBodyField;
@@ -134,14 +123,8 @@ The methods provided by this object are slightly different from the other two, b
- `getFileName()` simply returns the name of the file specified by the client.
- `getInputStream()` returns an `InputStream` object containing the file's contents.
-```java{8,11,16}
-import flash.Request;
-import flash.Response;
-import flash.models.RequestHandler;
-import flash.models.ExpectedBodyFile;
-
-// Make sure to set enforceNonNullBody to true
-@RouteInfo(method = HttpMethod.POST, path = "/helloFile", enforceNonNullBody = true)
+```java{4,8,18,21}
+@RouteInfo(method = HttpMethod.POST, path = "/helloFile")
public class MyHandler extends RequestHandler {
// Store the expected file in a private field
private final ExpectedBodyFile myExpectedBodyFile;
diff --git a/flash/server-router.md b/flash/server-router.md
index 3f6cb11..7ec1988 100644
--- a/flash/server-router.md
+++ b/flash/server-router.md
@@ -9,27 +9,23 @@ In this section, we discuss how to use the `FlashServer` router to manage our `R
The router is used to define route endpoints and their corresponding handler, which are executed when a request is made to the server.
The `FlashServer` router is an instance of the `RouteController` class, each server instance has its own router instance.
-To access the router instance, you can call the `route()` method on either the internal server or your `FlashServer` instance.
+To access the router instance, you can call the `route()` method on the `FlashServer` instance.
## Creating a Route
To create a route, you need to call the `route()` method on your server's instance (in this case for simplicity, on the InternalFlashServer)
-and specify the base path of the route, followed by your handler class and optionally a `RouteInterceptor` instance.
+and specify the base path of the route, followed by your handler class,
-(More on the concept of `RouteInterceptor` in the following sections).
-
-```java{8,9}
+```java{9}
// Example.java
-import static flash.InternalFlashServer.*;
-
public class Example {
public static void main(String[] args) {
- port(8080);
+ FlashServer server = new FlashServer(8080);
- route("/api")
+ server.route("/api")
.register(MyHandler.class);
- start();
+ server.start();
}
}
```
@@ -40,7 +36,7 @@ import flash.Request;
import flash.Response;
import flash.models.RequestHandler;
-@RouteInfo(method = HttpMethod.GET, path = "/hello", enforceNonNullBody = false)
+@RouteInfo(method = HttpMethod.GET, path = "/hello")
public class MyHandler extends RequestHandler {
public MyHandler(Request req, Response res) {
super(req, res);
diff --git a/flash/server-types.md b/flash/server-types.md
deleted file mode 100644
index d769e7d..0000000
--- a/flash/server-types.md
+++ /dev/null
@@ -1,99 +0,0 @@
----
-banner_title: "Flash - Server Types"
-banner_description: "Illustrating the main differences between the internal server instance and the FlashServer instance."
----
-
-# Server Types
-
-In this section, we discuss the differences between the internal server instance `InternalFlashServer` and the `FlashServer` instance, and whether you should use one or the other. We will also provide examples of how to use each type of server.
-
-## Internal Server
-
-The internal server is a singleton instance that can be accessed by statically importing
-methods from `InternalFlashServer`. This means that for each application, only one `InternalFlashServer` instance is created.
-This allows you to use the server's functionality without creating and managing an instance of the server.
-
-### Usage
-
-To use the internal server, you can statically import the methods from `InternalFlashServer`:
-
-```java{1}
-import static flash.InternalFlashServer.*;
-
-public class Example {
- public static void main(String[] args) {
- port(8080);
-
- get("/hello", (req, res) -> {
- res.status(200);
- return "Hello, world!";
- });
-
- post("/submit", (req, res) -> {
- // Handle POST request
- });
-
- // Other routes and configurations
- }
-}
-```
-
-## Server Instance
-
-The `FlashServer` class is used to create an instance of the server.
-Unlike the internal server, you can create multiple instances of the `FlashServer` class with different configurations.
-
-### Usage
-
-To create a server instance, you can simply call `new FlashServer()` and configure the server using the instance methods:
-
-```java{5}
-import flash.FlashServer;
-
-public class Example {
- public static void main(String[] args) {
- FlashServer server = new FlashServer("My Server Instance");
-
- server.port(8080);
-
- server.get("/hello", (req, res) -> {
- res.status(200);
- return "Hello, world!";
- });
-
- server.post("/submit", (req, res) -> {
- // Handle POST request
- });
-
- // Other routes and configurations
- }
-}
-```
-
-The `InternalFlashServer` is a **pre-configured instance** of `FlashServer` that is managed internally by the library. Under the hood, it is instantiated as:
-
-```java
-new FlashServer("Internal");
-```
-
-This means:
-- Its **name** is set to `"Internal"` for logging and internal management purposes.
-- It serves as the default server used by the library, which is automatically initialized when the library is loaded.
-
-Both the `InternalFlashServer` and any user-created `FlashServer` instances are of the same type (`FlashServer`). However, if you want to create and manage your own server instance, you must provide a **name** during initialization, e.g.:
-
-```java
-FlashServer server = new FlashServer("My Server Instance");
-```
-
-## Which Server Type Should You Use?
-
-It all depends on your use case.
-If you only need one server instance and want to keep your code concise, you can use the internal server.
-However, if your application needs to handle multiple server instances each with different ports and configurations,
-you should use `FlashServer` instances.
-
-::: warning
-From now on, and unless otherwise specified, every example in the documentation will use the `InternalFlashServer` to illustrate the usage of the library.
-However, for your specific implementation, you can call the same methods on your `FlashServer` instance to achieve the same results.
-:::
diff --git a/flash/websockets.md b/flash/websockets.md
new file mode 100644
index 0000000..36b19a6
--- /dev/null
+++ b/flash/websockets.md
@@ -0,0 +1,64 @@
+---
+banner_title: "Flash - Websockets"
+banner_description: "Learn how to create and manage server-side Websockets in Flash."
+---
+
+# 🌐 Websockets
+
+In this section, we illustrate how to create and manage Websockets in Flash, which are used to establish a bidirectional communication channel between the client and the server.
+
+## Understanding Websockets
+
+Websockets are a communication protocol that provides full-duplex communication channels over a single TCP connection.
+Unlike HTTP, which is a request-response protocol, Websockets allow for real-time, low-latency communication between the client and the server.
+
+Imagine a scenario where you need to send real-time updates to the client, such as a chat application or a live feed: if you were to use HTTP,
+you would need to poll the server at regular intervals to check for updates, which is inefficient and resource-intensive.
+
+## Creating a Websocket
+
+To create a Websocket in Flash, you need to extend the `WebsocketHandler` class and override the `onOpen`, `onMessage`, `onClose`, and `onError` methods.
+
+```java
+public class MyWebsocketHandler extends WebsocketHandler {
+ @Override
+ public void onOpen(WebSocketSession session) {
+ System.out.println("WebSocket connection opened");
+ }
+
+ @Override
+ public void onClose(WebSocketSession session, int statusCode, String reason) {
+ System.out.println("WebSocket connection closed");
+ }
+
+ @Override
+ public void onMessage(WebSocketSession session, String message) {
+ System.out.println("Received message: " + message);
+ session.sendMessage("I received your message!");
+ }
+
+ @Override
+ public void onError(WebSocketSession session, Throwable error) {
+ System.out.println("WebSocket error: " + error.getMessage());
+ }
+}
+```
+
+To register your Websocket handler with the server, you can use the `server.ws()` method:
+
+```java
+public class Example {
+ public static void main(String[] args) {
+ FlashServer server = new FlashServer(8080);
+
+ server.ws("/ws")
+ .register(MyWebsocketHandler.class);
+
+ server.start();
+ }
+}
+```
+
+## Interacting with Websockets sessions
+
+The `WebSocketSession` object provides methods to interact with the Websocket session, such as sending messages, closing the connection, and getting the remote address and session ID.