diff --git a/articles/api-with-handy-httpd.html b/articles/api-with-handy-httpd.html index e1f3a74..60b5dcf 100644 --- a/articles/api-with-handy-httpd.html +++ b/articles/api-with-handy-httpd.html @@ -141,6 +141,71 @@ } +

+ You're not limited to only JSON though; users can upload URL-encoded data, or XML, or literally anything else. It's just that D's standard library provides a JSON implementation, so Handy-Httpd gives you some help with it. +

+

+ Under the hood, Handy-Httpd uses the streams library for the underlying data transfer, so if you're looking for a completely custom solution, you'll need to read from ctx.request.inputStream, which is a InputStream!ubyte. Also note that each request has a pre-allocated receiveBuffer that you can use instead of creating your own separate buffer. +

+ +
+

Adding Middleware with Filters

+

+ One of the buzz words these days in web programming is "middleware", which is just a fancy term for anything that sits between two systems and performs some limited set of functions on the data that is passed between the systems. +

+

+ In Handy-Httpd, we've provided a convenient method of adding middleware to the HTTP request handling flow with the HttpRequestFilter, FilterChain, and the FilteredRequestHandler. +

+
+ +
An illustration of how an HTTP request is processed by a FilteredRequestHandler: first it goes through all pre-request filters, then the underlying handler, and finally any post-request filters.
+
+

+ Suppose we want to authenticate requests to certain endpoints. That's a pretty straightforward task that many web frameworks deal with. In Handy-Httpd, you'd create a filter that reads a JWT token from the request's header, decodes it, and adds user info to the request context's metadata property. +

+
+

+				class TokenFilter : HttpRequestFilter {
+					void apply(ref HttpRequestContext ctx, FilterChain filterChain) {
+						Nullable!UserInfo userInfo = tryParseToken(ctx.request.getHeader("Authorization"));
+						if (userInfo.isNull) {
+							ctx.response.setStatus(HttpStatus.UNAUTHORIZED);
+							ctx.response.writeBodyString("Invalid or missing token.");
+							return; // Exit without continuing the filter chain.
+						}
+						ctx.metadata["userInfo"] = userInfo.get();
+						filterChain.doFilter(ctx);
+					}
+
+					private Nullable!UserInfo tryParseToken(string authHeader) {
+						// Actual implementation omitted for brevity.
+					}
+				}
+			
+
+

+ Then to actually use your newly-created TokenFilter to safeguard your endpoint, you'd use the FilteredRequestHandler to wrap your endpoint and set the TokenFilter as one of the pre-request filters. +

+
+

+				FilteredRequestHandler frh = new FilteredRequestHandler(
+					mySuperSecretEndpoint,
+					[new TokenFilter()]
+				);
+			
+
+

+ That's all there is to it! No runtime magic, just composing a handler that does exactly what you tell it to. +

+
+
+

Additional Remarks

+

+ While I've done my best (which admittedly isn't that good) to keep Handy-Httpd lightweight and performant, that really isn't the number 1 goal. My goal was always to build a simple HTTP server with some nice-to-have conveniences that don't require months of diligent study to use effectively. I wanted something with sufficient documentation so that Handy-Httpd can be a D programmer's first introduction to HTTP servers. +

+

+ We're now on version 7.10.4 as of writing this article, and I feel like Handy-Httpd is in a place where I can comfortably say that it's reached those goals. Thanks for reading all the way through, and if you do try out Handy-Httpd, please do let me know what you think! +

Back to Articles diff --git a/articles/images/handy-httpd-filter-diagram.svg b/articles/images/handy-httpd-filter-diagram.svg new file mode 100644 index 0000000..d7680e8 --- /dev/null +++ b/articles/images/handy-httpd-filter-diagram.svg @@ -0,0 +1,195 @@ + + + + + + + + + + + + + + + + Server + + Handler + + + + + + + Pre-Request Filters + + Post-Request Filters + + + Request + + + diff --git a/articles/images/handy-httpd-filter-diagram.webp b/articles/images/handy-httpd-filter-diagram.webp new file mode 100644 index 0000000..d6167be Binary files /dev/null and b/articles/images/handy-httpd-filter-diagram.webp differ