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};