diff --git a/404.html b/404.html index 47f6ec2..0724981 100644 --- a/404.html +++ b/404.html @@ -17,7 +17,7 @@
- + \ No newline at end of file diff --git a/assets/flash_advanced_handler-default-implementations.md.CRxyEpV6.js b/assets/flash_advanced_handler-default-implementations.md.CRxyEpV6.js new file mode 100644 index 0000000..47887c4 --- /dev/null +++ b/assets/flash_advanced_handler-default-implementations.md.CRxyEpV6.js @@ -0,0 +1,102 @@ +import{_ as i,c as a,a0 as n,o as t}from"./chunks/framework.p2VkXzrt.js";const e="/assets/hdi.CNuX0-qb.png",h="/assets/hdichain.FX-X2Mhu.png",c=JSON.parse('{"title":"⚡ Handler Default Implementations (HDI)","description":"","frontmatter":{"banner_title":"Flash - Handler Default Implementations","banner_description":"Leverage HDIs for cleaner and more maintainable route logic.","head":[["meta",{"name":"twitter:image","content":"/assets/banner-cards/flash-advanced-handler-default-implementations.png"}],["meta",{"name":"twitter:image:src","content":"https://docs.pixel-services.com/assets/banner-cards/flash-advanced-handler-default-implementations.png"}],["meta",{"name":"twitter:card","content":"summary_large_image"}],["meta",{"name":"twitter:image:height","content":"1280"}],["meta",{"name":"twitter:image:width","content":"669"}],["meta",{"name":"twitter:description","content":""}]]},"headers":[],"relativePath":"flash/advanced/handler-default-implementations.md","filePath":"flash/advanced/handler-default-implementations.md"}'),l={name:"flash/advanced/handler-default-implementations.md"};function p(k,s,r,d,E,o){return t(),a("div",null,s[0]||(s[0]=[n('

⚡ Handler Default Implementations (HDI)

Handler Default Implementations (HDIs) offer a streamlined approach to standardize common behaviors across request handlers in Flash. By extending a base RequestHandler (or chaining multiple base handlers), you can centralize tasks like authentication, user data retrieval, and rate limiting while keeping your code modular and maintainable.

HDIs use the Chain of Responsibility pattern to layer reusable logic, ensuring that shared functionality is defined once and inherited by all handlers.

HDI

🔗 How HDIs Work

Rather than repeating common logic across different handlers, HDIs allow you to create abstract base handlers that encapsulate shared behaviors. When your individual request handlers extend these bases, they automatically inherit predefined functionality, and you only need to implement request-specific logic.

Key Benefits

🛡️ HDI Design Guidelines

1. Base HDI Class

Define an abstract base class that extends RequestHandler to encapsulate common logic:

2. Concrete Handler Implementation

Extend the base HDI class in your handler:

🛠️ Example: API Key Authentication

This example demonstrates how to build an HDI that validates an API key before processing a request.

Abstract API Key Protected Handler

java
public abstract class APIKeyProtectedHandler extends RequestHandler {
+    protected String apiKey;
+
+    public APIKeyProtectedHandler(Request req, Response res) {
+        super(req, res);
+    }
+
+    @Override
+    public Object handle() {
+        apiKey = req.header("X-API-Key");
+        if (apiKey == null || !isValidApiKey(apiKey)) {
+            res.status(403);
+            res.type("application/json");
+            return "{\\"error\\":\\"Invalid API Key\\"}";
+        }
+        return handleAuthorized();
+    }
+
+    protected abstract Object handleAuthorized();
+
+    private boolean isValidApiKey(String key) {
+        // Implement your API key validation logic here
+        return true;
+    }
+}

Concrete API Handler

Extend the abstract handler to process the request only if the API key is valid:

java
@RouteInfo(endpoint = "/data", method = HttpMethod.GET)
+public class GetDataHandler extends APIKeyProtectedHandler {
+    public GetDataHandler(Request req, Response res) {
+        super(req, res);
+    }
+
+    @Override
+    protected Object handleAuthorized() {
+        res.type("application/json");
+        return "{\\"data\\":\\"Your API response here\\"}";
+    }
+}

🏗️ Chaining HDIs for Modular Logic

HDIs can be layered to build complex flows. For instance, you might first authenticate a request, then fetch user data.

Protected Handler (Authentication)

java
public abstract class ProtectedHandler extends RequestHandler {
+    protected String authToken;
+
+    public ProtectedHandler(Request req, Response res) {
+        super(req, res);
+    }
+
+    @Override
+    public Object handle() {
+        authToken = req.header("Authorization");
+        if (authToken == null || !isValidToken(authToken)) {
+            res.status(401);
+            res.type("application/json");
+            return "{\\"error\\":\\"Unauthorized\\"}";
+        }
+        return handleAuthenticated();
+    }
+
+    protected abstract Object handleAuthenticated();
+
+    private boolean isValidToken(String token) {
+        // Validate the token here
+        return true;
+    }
+}

Authenticated Handler (User Data Retrieval)

Extend the ProtectedHandler to fetch user details:

java
public abstract class AuthenticatedHandler extends ProtectedHandler {
+    protected User user;
+
+    public AuthenticatedHandler(Request req, Response res) {
+        super(req, res);
+    }
+
+    @Override
+    protected Object handleAuthenticated() {
+        user = getUserFromDatabase(authToken);
+        if (user == null) {
+            res.status(403);
+            res.type("application/json");
+            return "{\\"error\\":\\"User not found\\"}";
+        }
+        return handleWithUser();
+    }
+
+    protected abstract Object handleWithUser();
+}

Final Handler Implementation

Implement the final handler that uses the authenticated user data:

java
@RouteInfo(endpoint = "/profile", method = HttpMethod.GET)
+public class UserProfileHandler extends AuthenticatedHandler {
+    public UserProfileHandler(Request req, Response res) {
+        super(req, res);
+    }
+
+    @Override
+    protected Object handleWithUser() {
+        res.type("application/json");
+        return "{\\"username\\":\\"" + user.getUsername() + "\\"}";
+    }
+}

For reference, here's a visual representation of how an HDI chain operates:

HDI Chain

',35)]))}const y=i(l,[["render",p]]);export{c as __pageData,y as default}; diff --git a/assets/flash_advanced_handler-default-implementations.md.CRxyEpV6.lean.js b/assets/flash_advanced_handler-default-implementations.md.CRxyEpV6.lean.js new file mode 100644 index 0000000..47887c4 --- /dev/null +++ b/assets/flash_advanced_handler-default-implementations.md.CRxyEpV6.lean.js @@ -0,0 +1,102 @@ +import{_ as i,c as a,a0 as n,o as t}from"./chunks/framework.p2VkXzrt.js";const e="/assets/hdi.CNuX0-qb.png",h="/assets/hdichain.FX-X2Mhu.png",c=JSON.parse('{"title":"⚡ Handler Default Implementations (HDI)","description":"","frontmatter":{"banner_title":"Flash - Handler Default Implementations","banner_description":"Leverage HDIs for cleaner and more maintainable route logic.","head":[["meta",{"name":"twitter:image","content":"/assets/banner-cards/flash-advanced-handler-default-implementations.png"}],["meta",{"name":"twitter:image:src","content":"https://docs.pixel-services.com/assets/banner-cards/flash-advanced-handler-default-implementations.png"}],["meta",{"name":"twitter:card","content":"summary_large_image"}],["meta",{"name":"twitter:image:height","content":"1280"}],["meta",{"name":"twitter:image:width","content":"669"}],["meta",{"name":"twitter:description","content":""}]]},"headers":[],"relativePath":"flash/advanced/handler-default-implementations.md","filePath":"flash/advanced/handler-default-implementations.md"}'),l={name:"flash/advanced/handler-default-implementations.md"};function p(k,s,r,d,E,o){return t(),a("div",null,s[0]||(s[0]=[n('

⚡ Handler Default Implementations (HDI)

Handler Default Implementations (HDIs) offer a streamlined approach to standardize common behaviors across request handlers in Flash. By extending a base RequestHandler (or chaining multiple base handlers), you can centralize tasks like authentication, user data retrieval, and rate limiting while keeping your code modular and maintainable.

HDIs use the Chain of Responsibility pattern to layer reusable logic, ensuring that shared functionality is defined once and inherited by all handlers.

HDI

🔗 How HDIs Work

Rather than repeating common logic across different handlers, HDIs allow you to create abstract base handlers that encapsulate shared behaviors. When your individual request handlers extend these bases, they automatically inherit predefined functionality, and you only need to implement request-specific logic.

Key Benefits

🛡️ HDI Design Guidelines

1. Base HDI Class

Define an abstract base class that extends RequestHandler to encapsulate common logic:

2. Concrete Handler Implementation

Extend the base HDI class in your handler:

🛠️ Example: API Key Authentication

This example demonstrates how to build an HDI that validates an API key before processing a request.

Abstract API Key Protected Handler

java
public abstract class APIKeyProtectedHandler extends RequestHandler {
+    protected String apiKey;
+
+    public APIKeyProtectedHandler(Request req, Response res) {
+        super(req, res);
+    }
+
+    @Override
+    public Object handle() {
+        apiKey = req.header("X-API-Key");
+        if (apiKey == null || !isValidApiKey(apiKey)) {
+            res.status(403);
+            res.type("application/json");
+            return "{\\"error\\":\\"Invalid API Key\\"}";
+        }
+        return handleAuthorized();
+    }
+
+    protected abstract Object handleAuthorized();
+
+    private boolean isValidApiKey(String key) {
+        // Implement your API key validation logic here
+        return true;
+    }
+}

Concrete API Handler

Extend the abstract handler to process the request only if the API key is valid:

java
@RouteInfo(endpoint = "/data", method = HttpMethod.GET)
+public class GetDataHandler extends APIKeyProtectedHandler {
+    public GetDataHandler(Request req, Response res) {
+        super(req, res);
+    }
+
+    @Override
+    protected Object handleAuthorized() {
+        res.type("application/json");
+        return "{\\"data\\":\\"Your API response here\\"}";
+    }
+}

🏗️ Chaining HDIs for Modular Logic

HDIs can be layered to build complex flows. For instance, you might first authenticate a request, then fetch user data.

Protected Handler (Authentication)

java
public abstract class ProtectedHandler extends RequestHandler {
+    protected String authToken;
+
+    public ProtectedHandler(Request req, Response res) {
+        super(req, res);
+    }
+
+    @Override
+    public Object handle() {
+        authToken = req.header("Authorization");
+        if (authToken == null || !isValidToken(authToken)) {
+            res.status(401);
+            res.type("application/json");
+            return "{\\"error\\":\\"Unauthorized\\"}";
+        }
+        return handleAuthenticated();
+    }
+
+    protected abstract Object handleAuthenticated();
+
+    private boolean isValidToken(String token) {
+        // Validate the token here
+        return true;
+    }
+}

Authenticated Handler (User Data Retrieval)

Extend the ProtectedHandler to fetch user details:

java
public abstract class AuthenticatedHandler extends ProtectedHandler {
+    protected User user;
+
+    public AuthenticatedHandler(Request req, Response res) {
+        super(req, res);
+    }
+
+    @Override
+    protected Object handleAuthenticated() {
+        user = getUserFromDatabase(authToken);
+        if (user == null) {
+            res.status(403);
+            res.type("application/json");
+            return "{\\"error\\":\\"User not found\\"}";
+        }
+        return handleWithUser();
+    }
+
+    protected abstract Object handleWithUser();
+}

Final Handler Implementation

Implement the final handler that uses the authenticated user data:

java
@RouteInfo(endpoint = "/profile", method = HttpMethod.GET)
+public class UserProfileHandler extends AuthenticatedHandler {
+    public UserProfileHandler(Request req, Response res) {
+        super(req, res);
+    }
+
+    @Override
+    protected Object handleWithUser() {
+        res.type("application/json");
+        return "{\\"username\\":\\"" + user.getUsername() + "\\"}";
+    }
+}

For reference, here's a visual representation of how an HDI chain operates:

HDI Chain

',35)]))}const y=i(l,[["render",p]]);export{c as __pageData,y as default}; diff --git a/assets/hdi.CNuX0-qb.png b/assets/hdi.CNuX0-qb.png new file mode 100644 index 0000000..e6d1b81 Binary files /dev/null and b/assets/hdi.CNuX0-qb.png differ diff --git a/flash/advanced/fullstack-development.html b/flash/advanced/fullstack-development.html index dea5b6d..b55578b 100644 --- a/flash/advanced/fullstack-development.html +++ b/flash/advanced/fullstack-development.html @@ -54,7 +54,7 @@ server.start(); } }

🚀 Package and Deploy your app!

With the frontend and backend code in place, you can now build the JAR file and deploy it to your server. The JAR file will contain both the frontend and backend code, making it easy to deploy and run your fullstack application.

All you've left to do is run the jarfile on any machine that has Java installed, and your fullstack application will be up and running!

- + \ No newline at end of file diff --git a/flash/advanced/handler-default-implementations.html b/flash/advanced/handler-default-implementations.html index 638b8ac..ef462f8 100644 --- a/flash/advanced/handler-default-implementations.html +++ b/flash/advanced/handler-default-implementations.html @@ -13,7 +13,7 @@ - + @@ -25,36 +25,19 @@ -
Skip to content

⚡ Handler Default Implementations (HDI)

Handler Default Implementations (HDIs) provide an elegant way to standardize common behaviors across multiple request handlers. By defining base handlers that extend RequestHandler (or chaining multiple base handlers together), you can modularize logic for common tasks like authentication, user data retrieval, and rate limiting.

HDIs are designed using the Chain of Responsibility pattern, making it easy to handle requests with layered logic.

🔗 How It Works

Instead of repeating the same logic in each handler, create abstract handler classes that define common functionality. Your handler implementations then extend these base classes, inheriting the shared behavior while implementing the request-specific logic.

Semantics of an HDI

Creating an HDI is simple, but it's useful to follow some guidelines for clarity and maintainability:

  1. Base HDI Class:

    • Extends: The base HDI class should extend RequestHandler.
    • Constructor: The constructor must call the super constructor with Request and Response objects.
    • Override: Override the handle method to include common behavior. The handle method should return the response to the client and should call the Abstract Handler Method, which is implemented by the handler or next HDI in the chain.
      java
      @Override
      +    
      Skip to content

      ⚡ Handler Default Implementations (HDI)

      Handler Default Implementations (HDIs) offer a streamlined approach to standardize common behaviors across request handlers in Flash. By extending a base RequestHandler (or chaining multiple base handlers), you can centralize tasks like authentication, user data retrieval, and rate limiting while keeping your code modular and maintainable.

      HDIs use the Chain of Responsibility pattern to layer reusable logic, ensuring that shared functionality is defined once and inherited by all handlers.

      HDI

      🔗 How HDIs Work

      Rather than repeating common logic across different handlers, HDIs allow you to create abstract base handlers that encapsulate shared behaviors. When your individual request handlers extend these bases, they automatically inherit predefined functionality, and you only need to implement request-specific logic.

      Key Benefits

      • Build-Time Optimization:
        When your project is compiled, Flash’s router merges the entire HDI chain into a single handler instance. This eliminates extra function calls and runtime lookups, resulting in a leaner execution path compared to traditional middleware stacks.

      • Reduced Complexity:
        Unlike frameworks that rely on reflection (e.g., Spring Boot) or a deep middleware stack (e.g., Express.js), HDIs embed inherited behavior directly in the compiled class, minimizing runtime overhead.

      • Type Safety & Clean State Management:
        Protected fields in HDIs allow seamless data sharing between handlers without using global variables, callbacks, or type casting. Note: Always declare these fields as instance (non-static) variables to ensure each handler maintains its own state.

      🛡️ HDI Design Guidelines

      1. Base HDI Class

      Define an abstract base class that extends RequestHandler to encapsulate common logic:

      • Constructor:
        Initialize by passing Request and Response objects to the superclass.

      • Overridden handle Method:
        Implement common logic and delegate to an abstract method for custom behavior.

        java
        @Override
         public Object handle() {
        -    // Common logic here, then call the abstract method
        +    // Insert common logic here (e.g., logging, header processing)
             return handleCustom();
        -}
      • Abstract Handler Method: Define an abstract method that must be implemented by the handler to provide custom logic. It should look like this:
        java
        protected abstract Object handleCustom();
      • Protected Fields: If needed, declare protected fields in the base class to pass data between handlers in the chain.

        INFO

        Protected fields are accessible to the handler implementation inside the Abstract Handler Method. Example HDI :

        java
        public abstract class MyHDI extends RequestHandler {
        -    protected String data; 
        -    public BaseHandler(Request req, Response res) {
        -        super(req, res);
        -    }
        -    @Override
        -    public Object handle() {
        -        data = "Some data"; // Set the data
        -        return handleCustom();
        -    }
        -    protected abstract Object handleCustom();
        -}

        Example Handler Implementation :

        java
        public class MyHandler extends MyHDI {
        -    public MyHandler(Request req, Response res) {
        -        super(req, res);
        -    }
        -    @Override
        -    protected Object handleCustom() {
        -        // The data is accessible here
        -        System.out.println(data);
        -        return "Response";
        -    }
        -}
    • Handler Implementation:

      • Extends: The handler should extend the HDI class (or be the final handler in the chain).
      • Constructor: The constructor should call the super constructor with Request and Response objects.
      • Implement: Implement the Abstract Handler Method from the HDI.
      • Response Logic: The response logic should be in the abstract method, and its return value is sent to the client.
        java
        @Override
        +}
      • Abstract Method:
        Declare an abstract method that must be implemented by subclasses.

        java
        protected abstract Object handleCustom();
      • Protected Fields:
        Use protected instance fields to share data between HDI layers.

        Warning: Do not declare these fields as static. Each handler should manage its own state.

        java
        // Incorrect: static field
        +protected static String data;
        +
        +// Correct: instance field
        +protected String data;

      2. Concrete Handler Implementation

      Extend the base HDI class in your handler:

      • Constructor:
        Call the super constructor with the necessary Request and Response objects.

      • Implement handleCustom():
        Write the request-specific logic here. Protected fields from the base class are available within this method.

        java
        @Override
         protected Object handleCustom() {
        -      // Custom logic here
        -      return "Response";
        -}
      • Protected Fields: The handler implementation can access data from the HDI using the protected fields, inside the Abstract Handler Method.

🛠 Example: API Key Authentication

Now let's go over a simple example to demonstrate how HDIs work. Imagine you need to authenticate API requests by checking an API key. You can create an abstract APIKeyProtectedHandler that extends RequestHandler and handles the API key authentication:

java
public abstract class APIKeyProtectedHandler extends RequestHandler {
+    // Custom logic using inherited data
+    return "Response";
+}

🛠️ Example: API Key Authentication

This example demonstrates how to build an HDI that validates an API key before processing a request.

Abstract API Key Protected Handler

java
public abstract class APIKeyProtectedHandler extends RequestHandler {
     protected String apiKey;
 
     public APIKeyProtectedHandler(Request req, Response res) {
@@ -64,23 +47,21 @@
     @Override
     public Object handle() {
         apiKey = req.header("X-API-Key");
-
         if (apiKey == null || !isValidApiKey(apiKey)) {
             res.status(403);
             res.type("application/json");
             return "{\"error\":\"Invalid API Key\"}";
         }
-
         return handleAuthorized();
     }
 
     protected abstract Object handleAuthorized();
 
     private boolean isValidApiKey(String key) {
-        // Implement key validation logic, e.g., checking against a database
+        // Implement your API key validation logic here
         return true;
     }
-}

Now, your API handler implementation only need to extend APIKeyProtectedHandler, ensuring every request has a valid API key before executing its logic:

java
@RouteInfo(endpoint = "/data", method = HttpMethod.GET)
+}

Concrete API Handler

Extend the abstract handler to process the request only if the API key is valid:

java
@RouteInfo(endpoint = "/data", method = HttpMethod.GET)
 public class GetDataHandler extends APIKeyProtectedHandler {
     public GetDataHandler(Request req, Response res) {
         super(req, res);
@@ -91,7 +72,7 @@
         res.type("application/json");
         return "{\"data\":\"Your API response here\"}";
     }
-}

🏗️ Chaining HDIs for Modular Logic

HDI Chain

HDIs can be chained together to create multiple layers of logic. For example, if you need to authenticate a user and fetch their data from a database, you can create two HDIs:

  • ProtectedHandler ensures authentication.
java
public abstract class ProtectedHandler extends RequestHandler {
+}

🏗️ Chaining HDIs for Modular Logic

HDIs can be layered to build complex flows. For instance, you might first authenticate a request, then fetch user data.

Protected Handler (Authentication)

java
public abstract class ProtectedHandler extends RequestHandler {
     protected String authToken;
 
     public ProtectedHandler(Request req, Response res) {
@@ -110,9 +91,13 @@
     }
 
     protected abstract Object handleAuthenticated();
-}
  • AuthenticatedHandler extends ProtectedHandler to fetch user data from the database, and overrides handleAuthenticated to ensure the user is authenticated before proceeding.
java
public abstract class AuthenticatedHandler extends ProtectedHandler {
+
+    private boolean isValidToken(String token) {
+        // Validate the token here
+        return true;
+    }
+}

Authenticated Handler (User Data Retrieval)

Extend the ProtectedHandler to fetch user details:

java
public abstract class AuthenticatedHandler extends ProtectedHandler {
     protected User user;
-    private String authToken; // inherited from ProtectedHandler
 
     public AuthenticatedHandler(Request req, Response res) {
         super(req, res);
@@ -130,7 +115,7 @@
     }
 
     protected abstract Object handleWithUser();
-}
  • Your handler implementation UserProfileHandler extends AuthenticatedHandler and implements handleWithUser to ensure the user is authenticated and their profile data has been fetched before proceeding.
java
@RouteInfo(endpoint = "/profile", method = HttpMethod.GET)
+}

Final Handler Implementation

Implement the final handler that uses the authenticated user data:

java
@RouteInfo(endpoint = "/profile", method = HttpMethod.GET)
 public class UserProfileHandler extends AuthenticatedHandler {
     public UserProfileHandler(Request req, Response res) {
         super(req, res);
@@ -141,8 +126,8 @@
         res.type("application/json");
         return "{\"username\":\"" + user.getUsername() + "\"}";
     }
-}
- +}

For reference, here's a visual representation of how an HDI chain operates:

HDI Chain

+ \ No newline at end of file diff --git a/flash/core-concepts/handlers.html b/flash/core-concepts/handlers.html index 29c8b0c..0978434 100644 --- a/flash/core-concepts/handlers.html +++ b/flash/core-concepts/handlers.html @@ -28,7 +28,7 @@
Skip to content

📚 Handlers

In Flash, handlers are the building blocks of your application logic. They are responsible for processing incoming requests, executing the necessary logic, and generating the appropriate response.

There are several types of handlers in Flash, each serving a specific purpose and providing a different level of control over the request lifecycle. Understanding the different handler types will help you structure your application logic more effectively and make the most out of Flash's powerful routing system.

📦 Routing Behavior

Before diving into the different handler types, it's essential to understand how routing works in Flash. When a request is received by the server, Flash matches the request path and method against the registered routes to find the appropriate handler. The handler is then executed, and its response is sent back to the client.

Flash supports 3 main types of routing behaviors:

  • Literal Routing: Matches the exact path specified in the route definition.
  • Parametrized Routing: Matches paths with dynamic segments that are extracted as route parameters.
  • Dynamic Routing: Matches any path that starts with the specified prefix and is flagged with a wildcard "*" character.

📌 Handler Types

1. RequestHandler

The RequestHandler is the "standard" type of handler in Flash, it provides the most control over the request lifecycle and allows you to define custom logic for handling requests. You can extend the RequestHandler class to create custom handlers that process incoming requests and generate responses.

Because RequestHandler is an abstract class, you need to implement both the handle() method and the super constructor in your custom handler to define the logic that should be executed when a request is received.

Since RequestHandler is an abstract class, you can leverage and chain HDI's to create cleaner and more maintainable route logic (more on that in the Handler Default Implementations guide).

2. SimpleHandler

The SimpleHandler is a lightweight handler that allows you to define request handling logic in a single method using lambda notation. It is useful for simple request processing tasks that don't require the full lifecycle control provided by RequestHandler.

To create a SimpleHandler, you can use the server.get(), server.post(), server.put(), server.delete() etc. in general, you can use the server.<METHOD>() methods to register the handler with the server.

The arguments for these methods are the route path and a lambda expression that provides the request and response objects and defines the request handling logic.

java
server.get("/hello", (req, res) -> {
     return "Hello, World!";
 });

Both RequestHandler and SimpleHandler can specify the router behavior by the naming convention of the endpoint used to register the handler.

  • Literal Routing: /hello
    Will match exactly /hello

  • Parametrized Routing: /hello/:name
    Will match /hello/John, /hello/Alice, etc.

  • Dynamic Routing: /hello/*
    Will match /hello/../..

- + \ No newline at end of file diff --git a/flash/core-concepts/request-handler.html b/flash/core-concepts/request-handler.html index c63a416..3e532c5 100644 --- a/flash/core-concepts/request-handler.html +++ b/flash/core-concepts/request-handler.html @@ -37,7 +37,7 @@ return response; } }

WARNING

Any logic that needs to be executed before the request handler is registered must be done within the constructor.

Request Handler methods

The RequestHandler class provides several methods that can be used to interact with the request and response objects easily and safely. Following are listed the methods available in the RequestHandler class, with a brief description of their purpose:

MethodParamsDescription
getRequestBody()noneReturns a JSONObject representation of the request body.
getSpecification()noneReturns an instance of HandlerSpecification containing all sorts of information about the handler.
expectedRequestParameter()String name, descriptionReturns an instance of ExpectedRequestParameter for the specified parameter name.
expectedBodyField()String name, descriptionReturns an instance of ExpectedBodyField for the specified field name.
expectedBodyFile()String name, descriptionReturns an instance of ExpectedBodyFile for the specified file name.

(More on the ExpectedRequestParameter, ExpectedBodyField, and ExpectedBodyFile classes in the next section).

- + \ No newline at end of file diff --git a/flash/core-concepts/request-response.html b/flash/core-concepts/request-response.html index 4cb8341..3c8d65a 100644 --- a/flash/core-concepts/request-response.html +++ b/flash/core-concepts/request-response.html @@ -92,7 +92,7 @@ return "File saved at: " + myFile.getAbsolutePath(); } }

This time, you will need to use a tool like Postman to send a POST request to /helloFile with a multipart form data body containing a file named myFile. You should receive a response like File saved at: <path> where <path> is the location where the server saved the file.

- + \ No newline at end of file diff --git a/flash/core-concepts/server-router.html b/flash/core-concepts/server-router.html index 93f238e..9d2afe0 100644 --- a/flash/core-concepts/server-router.html +++ b/flash/core-concepts/server-router.html @@ -49,7 +49,7 @@ return response; } }

In the example above, we create an /api router and register the MyHandler class to handle requests on the /api/hello endpoint.

This is because the path property of the RouteInfo annotation is relative to the base path of the router, which in this case is /api.

Visiting /api/hello from your browser will result in the response Hello, world!.

- + \ No newline at end of file diff --git a/flash/core-concepts/websockets.html b/flash/core-concepts/websockets.html index 5038e03..095b041 100644 --- a/flash/core-concepts/websockets.html +++ b/flash/core-concepts/websockets.html @@ -58,7 +58,7 @@ 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.

MethodParamsDescription
getChannel()noneReturns an instance of AsynchronousSocketChannel useful for retrieving info about the client .
getRequestInfo()noneReturns an instance of RequestInfo containing all sorts of information about the request (headers, method, path etc.) .
getPath()noneReturns the path to the websocket endpoint as a String.
getId()noneReturns the id of the websocket session as a String, useful if you want to keep track of the connected clients in a custom manager.
getBuffer()noneReturns the ByteBuffer for that session.
sendMessage()String messageSends the message to the client as a String. it's up to the developer to stringify and de-stringify any data you want to send back and forth
close()noneCloses the websocket session.

NOTE

WebsocketHandler includes a setId(String id) method for overriding the default session ID. Unless you have a specific reason to change it, it's best to leave it as is.

Similarly, the setBuffer(ByteBuffer buffer) method allows you to override the default buffer. If you're unsure about this, it's recommended to keep the default setting.

- + \ No newline at end of file diff --git a/flash/file-serving/dynamic-file-server.html b/flash/file-serving/dynamic-file-server.html index edc2fe7..0cc10c9 100644 --- a/flash/file-serving/dynamic-file-server.html +++ b/flash/file-serving/dynamic-file-server.html @@ -53,7 +53,7 @@ )); } } - + \ No newline at end of file diff --git a/flash/file-serving/static-file-server.html b/flash/file-serving/static-file-server.html index 9c8b809..9763cb6 100644 --- a/flash/file-serving/static-file-server.html +++ b/flash/file-serving/static-file-server.html @@ -53,7 +53,7 @@ )); } } - + \ No newline at end of file diff --git a/flash/index.html b/flash/index.html index c4927e4..2426794 100644 --- a/flash/index.html +++ b/flash/index.html @@ -26,7 +26,7 @@
Skip to content

⚡ Flash

Flash is a simple, modern and fast expressive web framework written in Java. The project is maintained by Pixel Services and the open-source community.

- + \ No newline at end of file diff --git a/flash/introduction/installation.html b/flash/introduction/installation.html index 81caaf8..c5ff8b6 100644 --- a/flash/introduction/installation.html +++ b/flash/introduction/installation.html @@ -44,7 +44,7 @@ }
  • And the dependency :

    groovy
    dependencies {
         implementation 'com.pixelservices:flash:{{ latestVersion }}'
     }
  • ⚡ Latest version:
    - + \ No newline at end of file diff --git a/hashmap.json b/hashmap.json index 2b90f06..c82016d 100644 --- a/hashmap.json +++ b/hashmap.json @@ -1 +1 @@ -{"flash_advanced_fullstack-development.md":"DFJ2Nfm_","flash_advanced_handler-default-implementations.md":"ki9D2CCK","flash_core-concepts_handlers.md":"BZuBmBSX","flash_core-concepts_request-handler.md":"fjZWLpOw","flash_core-concepts_request-response.md":"BuTSfkDO","flash_core-concepts_server-router.md":"DIWo49Yl","flash_core-concepts_websockets.md":"ByGVX96c","flash_file-serving_dynamic-file-server.md":"DY_r4ecH","flash_file-serving_static-file-server.md":"BvN0FZB2","flash_index.md":"CAxgiNVz","flash_introduction_installation.md":"BEOKwAAp","index.md":"sDYgKdFh","mobot_index.md":"Be0Zoetq","serverlibraries_index.md":"CeIqSPIs"} +{"flash_advanced_fullstack-development.md":"DFJ2Nfm_","flash_advanced_handler-default-implementations.md":"CRxyEpV6","flash_core-concepts_handlers.md":"BZuBmBSX","flash_core-concepts_request-handler.md":"fjZWLpOw","flash_core-concepts_request-response.md":"BuTSfkDO","flash_core-concepts_server-router.md":"DIWo49Yl","flash_core-concepts_websockets.md":"ByGVX96c","flash_file-serving_dynamic-file-server.md":"DY_r4ecH","flash_file-serving_static-file-server.md":"BvN0FZB2","flash_index.md":"CAxgiNVz","flash_introduction_installation.md":"BEOKwAAp","index.md":"sDYgKdFh","mobot_index.md":"Be0Zoetq","serverlibraries_index.md":"CeIqSPIs"} diff --git a/index.html b/index.html index c2d93b1..ac8359e 100644 --- a/index.html +++ b/index.html @@ -26,7 +26,7 @@
    Skip to content

    Pixel Services Documentation

    Explore the documentation for all public Pixel Services projects




    Our Team

    Say hello to the Pixel Services team !

    Relism

    Relism

    Backend Developer

    Sieadev

    Sieadev

    Developer

    - + \ No newline at end of file diff --git a/mobot/index.html b/mobot/index.html index fc16109..3d21e59 100644 --- a/mobot/index.html +++ b/mobot/index.html @@ -26,7 +26,7 @@
    Skip to content
    - + \ No newline at end of file diff --git a/serverlibraries/index.html b/serverlibraries/index.html index c26d13f..99bef75 100644 --- a/serverlibraries/index.html +++ b/serverlibraries/index.html @@ -26,7 +26,7 @@
    Skip to content
    - + \ No newline at end of file