From 06e6bfa13d0e18fe7a1c3dd56eb99cf488cecbd9 Mon Sep 17 00:00:00 2001 From: Relism Date: Thu, 27 Feb 2025 20:36:16 +0100 Subject: [PATCH] Added a few things and fixed some others --- flash/assets/flash-fullstack.png | Bin 0 -> 30646 bytes flash/config/sidebar.json | 4 +- flash/dynamic-file-server.md | 88 +++++++++++++++++++++++ flash/handler-default-implementations.md | 4 ++ flash/handlers.md | 63 ++++++++++++++++ flash/request-handler.md | 3 +- flash/server-router.md | 11 ++- 7 files changed, 164 insertions(+), 9 deletions(-) create mode 100644 flash/assets/flash-fullstack.png create mode 100644 flash/dynamic-file-server.md create mode 100644 flash/handlers.md diff --git a/flash/assets/flash-fullstack.png b/flash/assets/flash-fullstack.png new file mode 100644 index 0000000000000000000000000000000000000000..6257133a2054a4a847d15ac3f1f181658ed2704e GIT binary patch literal 30646 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 Ykdl6mHN?n-@*U>Fc`I1Ox$D3DFRZ^`ng9R* literal 0 HcmV?d00001 diff --git a/flash/config/sidebar.json b/flash/config/sidebar.json index 4daa59f..00bfd67 100644 --- a/flash/config/sidebar.json +++ b/flash/config/sidebar.json @@ -5,12 +5,14 @@ "items": [ { "text": "Getting Started", "link": "/flash" }, { "text": "Installation", "link": "/flash/installation" }, + { "text": "Handlers", "link": "/flash/handlers" }, { "text": "RequestHandler", "link": "/flash/request-handler"}, { "text": "Request and Response", "link": "/flash/request-response"}, { "text": "Server Router", "link": "/flash/server-router" }, { "text": "Handler Default Implementations", "link": "/flash/handler-default-implementations" }, { "text": "Websockets", "link": "/flash/websockets" }, - { "text": "Static Files Server", "link": "/flash/static-file-server" } + { "text": "Static Files Server", "link": "/flash/static-file-server" }, + { "text": "Dynamic Files Server", "link": "/flash/dynamic-file-server" } ] } ] diff --git a/flash/dynamic-file-server.md b/flash/dynamic-file-server.md new file mode 100644 index 0000000..cb2576e --- /dev/null +++ b/flash/dynamic-file-server.md @@ -0,0 +1,88 @@ +--- +banner_title: "Flash - Dynamic File Server" +banner_description: "Learn how to serve files in a dynamic context." +--- + +# 📁 Dynamic File Server + +Sometimes we need to serve files in a dynamic context, in this sense a static file server is limiting. +Imagine we have a frontend application that is compiled down to a single `index.html` file, and we want to serve it with Flash +alongside it's javascript and css bundles. The way these compiled applications work is that they rely heavily on +client-side routing, so when the user navigates to a different page, the frontend application will try to fetch the +corresponding file from the server. This is where a dynamic file server comes in handy, as no route is pre-registered. + +::: warning +The dynamic file server relies heavily on the concept of dynamic handlers, which are handlers that will resolve for +any subpath of the endpoint they are registered to (see [Handler Types](/flash/dynamic-handlers) for more info). +::: + +## Usage + +To serve static files in Flash, you need to call the `server.serveDynamic()` method with the endpoint path and an instance of `DynamicFileServerConfig`. +The configuration object is instanced like so : + +```java +DynamicFileServerConfiguration( + boolean enableFileWatcher, + String destinationPath, + String dynamicEntrypoint, + SourceType sourceType +) +``` + +- `enableFileWatcher` : If set to `true`, the server will watch for changes in the served files and reload them automatically. +- `destinationPath` : The path to the directory containing the files to be served. +- `dynamicEntrypoint` : The path to the file that will be served when the client navigates to the endpoint eg. `index.html`. +- `sourceType` : The type of source to serve files from. It can be either `FILESYSTEM` or `RESOURCESTREAM`. + +Registering the dynamic file server is as simple as calling the `server.serveDynamic()` method with the desired path and configuration object: + +```java +public class Example { + public static void main(String[] args) { + FlashServer server = new FlashServer(8080); + + server.serveDynamic("/*", new DynamicFileServerConfiguration( + true, + "path/to/my/files", + "index.html", + SourceType.FILESYSTEM + )); + } +} +``` + +Now you can access the files (or frontend) in the specified directory by navigating to `http://localhost:8080/`. + +Similarly, you can serve the same content from the jar's resources folder by setting the `sourceType` to `RESOURCESTREAM`: + +```java +public class Example { + public static void main(String[] args) { + FlashServer server = new FlashServer(8080); + + server.serveStatic("/static", new DynamicFileServerConfiguration( + true, + "path/to/my/files", + "index.html", + SourceType.RESOURCESTREAM + )); + } +} +``` + +## 💻 Note on Fullstack Development + +![flash-fullstack.png](assets/flash-fullstack.png) + +The dynamic file server opens up the possibility for fullstack development with Flash. +You can easily serve your frontend application alongside your backend, and build the entire application in a single jarfile. + +This is possible thanks to the `RESOURCESTREAM` source type, which allows you to serve files from the jar's resources folder: +the ideal cycle for packaging your app would be to compile the frontend application and place the compiled files in the resources folder (or setup the build script to do it for you), +then build the jarfile with the compiled frontend and the backend code. + +This approach works for any frontend framework that can compile down to static files (React, Angular, Vue, etc.). + +For more in-depth information on how to build a fullstack application with Flash, check out the [Fullstack Development](/flash/fullstack-development) guide. + diff --git a/flash/handler-default-implementations.md b/flash/handler-default-implementations.md index 85ae6b4..6f355e4 100644 --- a/flash/handler-default-implementations.md +++ b/flash/handler-default-implementations.md @@ -30,6 +30,7 @@ public abstract class APIKeyProtectedHandler extends RequestHandler { if (apiKey == null || !isValidApiKey(apiKey)) { res.status(403); + res.type("application/json"); return "{\"error\":\"Invalid API Key\"}"; } @@ -58,6 +59,7 @@ public class GetDataHandler extends APIKeyProtectedHandler { @Override protected Object handleAuthorized() { + res.type("application/json"); return "{\"data\":\"Your API response here\"}"; } } @@ -109,6 +111,7 @@ public abstract class AuthenticatedHandler extends ProtectedHandler { user = getUserFromDatabase(authToken); if (user == null) { res.status(403); + res.type("application/json"); return "{\"error\":\"User not found\"}"; } return handleWithUser(); @@ -132,6 +135,7 @@ public class UserProfileHandler extends AuthenticatedHandler { @Override protected Object handleWithUser() { + res.type("application/json"); return "{\"username\":\"" + username + "\"}"; } } diff --git a/flash/handlers.md b/flash/handlers.md new file mode 100644 index 0000000..fad1e26 --- /dev/null +++ b/flash/handlers.md @@ -0,0 +1,63 @@ +--- +banner-title: "Flash - Handlers" +banner-description: "Learn about handlers in Flash and the different types available." +--- + +# 📚 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](/flash/handler-default-implementations) section). + +### 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.()` 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[Example] +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/request-handler.md b/flash/request-handler.md index ff88096..97b1d3d 100644 --- a/flash/request-handler.md +++ b/flash/request-handler.md @@ -6,6 +6,7 @@ banner_description: "Learn how to create and manage Request Handlers in Flash." # ⚙️ Request Handler In this section, we illustrate the powerful concept of `RequestHandler` in Flash, which are used to handle incoming requests and generate responses. +RequestHandler classes provide the most control over the request lifecycle and allow you to use routing, expected operators and HDI's to create custom logic for handling requests. ## Creating a Request Handler @@ -18,7 +19,7 @@ The `req` (request) and `res` (response) objects are available in the handler to You must call the super constructor with the `req` and `res` objects to initialize the handler. ```java{1,4} -@RouteInfo(method = HttpMethod.GET, path = "/hello") +@RouteInfo(endpoint="/hello", method = HttpMethod.GET) public class MyHandler extends RequestHandler { public MyHandler(Request req, Response res) { super(req, res); diff --git a/flash/server-router.md b/flash/server-router.md index 7ec1988..54e0581 100644 --- a/flash/server-router.md +++ b/flash/server-router.md @@ -16,7 +16,7 @@ To access the router instance, you can call the `route()` method on the `FlashSe 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, -```java{9} +```java{6} // Example.java public class Example { public static void main(String[] args) { @@ -30,11 +30,8 @@ public class Example { } ``` -```java{6} +```java{3} // MyHandler.java -import flash.Request; -import flash.Response; -import flash.models.RequestHandler; @RouteInfo(method = HttpMethod.GET, path = "/hello") public class MyHandler extends RequestHandler { @@ -50,8 +47,8 @@ public class MyHandler extends RequestHandler { } ``` -In the example above, we create a route `/api` and register the `MyHandler` class to handle requests on the `/api/hello` endpoint. +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 route, which in this case is `/api`. +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