Motivation is the hardest part of any personal project. The great community here has helped me keep strong interest in the space, but without the express need for this server to be build I am struggling to find motivation to develop on it.
I am a professional software engineer, so even though my day to day isn't 100% coding, my position requires me to critque and plan projects as well as develop them... which is exactly what this project is for me too. So its more of the same. That can kill your motivation after a rough day at work sitting in meetings all day.
So today while writing my original entry about how I've made no progress, I looked at the clock and noticed I still had about 30 minutes to work so decided to do some work instead.
What I came up with was essnetially 2 new classes that abstract away some of the hard implementaiton logic that I originally developed. Those two classes are:
So what you'll be doing is implementing the Router class and registering a collection of routes that will be handled by that router. Then each route will be tied to a function that takes in a request object and returns a response.
MessageHandler is where we tie in the actual input into the routers
Request request = new Request(URI.create(url)); ResponseMessage response = routers.flatMap(Router::routes) .filter(r -> RouteMatcher.match(r.route(), request.uri())) .findFirst() .map(r -> r.handle(request)) .orElse(this.defaultHandler.handle(request.uri())); // is "toResponseMessage()" a good fn name? byte[] data = response.toResponseMessage(); ByteBuf res = ctx.alloc().buffer(data.length); res.writeBytes(data);
And the two new classes:
Router.java
public interface Router { Streamroutes(); }
Route.java
public class Route { private final String route; private final FunctionhandleFn; public Route(String route, Function handleFn) { this.route = route; this.handleFn = handleFn; } public String route() { return this.route; } public ResponseMessage handle(final Request request) { return this.handleFn.apply(request); } }
PingRouter.java - and implementation of all of this.
public class PingRouter implements Router { @Override public Streamroutes() { return Stream.of( new Route("/ping", this::ping) ); } ResponseMessage ping(final Request request) { return new ResponseMessage(GeminiStatus.SUCCESS, "text/plain"); } }
Then in your Server file you can register a bunch of these routers that ultimate get called in that stream to determine how to handle each route.
To reiterate, this is my attempt at creating a generic gemini server that can be used for hosting a myriad of applications within gemini. And the intention is to draw inspiration from the enterprise webserver frameworks I use day to day. Tweaking what I like/don't like about those.
So what was unfun before was how you would register routes to basically instantiate a new "router" in this case and then configure its routes and all this frustrating creating a specific router for each type of route grouping.
This direction I've moved into should make anyone implementing their own server side code able to do so without writing much boiler plate. Essentially, PingRouter and some plumbing is all you'll have to do!
I'll be uploading this to git somewhere soon to browse. I just need to delete a lot of the old code.
P.S - I am trying to find the best way to display this stuff. I use amfora and it looks... passible.. but if you have recommendations on how to format the code dump sections please email me or hit me up on IRC.
Thanks :)
=> Gemlog | Home This content has been proxied by September (ba2dc).Proxy Information
text/gemini; lang=en;