@anderseknert My previous AP server was in kotlin w/ #vertX because I wanted an excuse to use vert.x and wanted to play with what building an AP system with something like actors and routing directives would actually look like.
This time I am trying to learn OCaml, which has been on my list for a while but I never got around to it, so this feels like a good excuse and it has a rich type system for expressing some of the things I know make life easier up front.
Good progress for today. Added my initial #vertx authorization provider implementation to loom. Permissions can be assigned to roles and users. I'm using #jooq to persist RBAC and caffeine to cache the authorizations. Dagger subcomponents will now be used to create DI subgraphs per request.
I hope to get more done until my summer break.
Does somebody know why https://vertx.io is not accessible ? #vertx #vertxio
@nurkiewicz SSE is easier in Java with the typical JAX-RS/Spring APIs... WebSockets are a dream if you use #VertX. I think the problem is not the technology, but the implementation in Java being overly complex.
Why I think it is a good fit:
Imagine basically writing a rule along the lines of:
"When bob attempts to follow alice automatically approve the request if alice follows bob or if it comes from a set of known-good instances; if from a known-suspected instance autodecline; else ask for manual approval."
This is lots of handlers and logic or like… three lines of datalog to do the categorizing.
This plays nicely with #vertx too because you can basically just point the logic at the event bus.
""Best framework and textbook I've seen in years. So refreshing to write Java without Spring magic."
https://news.ycombinator.com/item?id=34226905 #vertx @ManningPublications
This isn't a fault in #vertx nor in #mockist approaches, this is a paradigm mismatch.
It would be foolish for me to go out and then write articles about how mockist thinking falls apart because it is difficult in vertx. It would also be foolish for me to judge vertx harshly for not thinking in my preferred paradigm.
Better to learn and adapt.
I am less tolerant of more generalist libraries (*cough* guava *cough*) not playing nicely here, but that's because those _should_ be fairly generic.
I will say that it _is_ important to try to understand the paradigm a library is coming from.
I am currently working with #vertx. Vertx presupposed certain patterns that make my testing approach ("mockist" as distinct from "integrationist") difficult.
I spent about a day trying to figure out how to get vertx to play nicely in a mockist way of thinking and decided it wasn't worth it.
But if you play by Vertx's way of doing things? It tests very cleanly.
Also, re queuing in #LcCircle: I must say I _really_ like #vertx here for creating abstractions.
Like I have my frustrations and feel a strong need to put patterns on top of everything, but the fundamental architecture makes it so easy to just… pass through data and then implement a queue later.
One of the challenges of doing this is that you end up with a rather difficult parsing situation out of the buffer if you don't know what kind of object you are looking at… and several of these types require additional type information in order to decode successfully.
So you end up with this hodgepodge of different codecs that all have to be tested and maintained and where they have to know how to "speak #vertx." This is… acceptable, I guess, but unaesthetic.
The way I think I'm going to do #vertx event bus serialization in my toy #ActivityPub project, after mulling over it for a few days and playing around with a few options, is to have two layers to the decoding process. This is not Efficient™ (though there are ways to make it more so), but it will be pretty snappy still.
The challenge is basically a few different things I'm trying to solve simultaneously.
Also not an idle point that #vertx was _already_ doing a lot of this wrapping for me. We were getting heavily into inception-land as I kept working through the use cases, and the leaky abstraction was bugging me.
So I took three steps back and decided that instead I'd just make it really, really easy to register types. Register types in ALL OF THE THINGS, because why not.
I already had the wiring for protobuf, and for some reason I thought I'd see about getting kotlinx serialization working.
#Vertx, despite having a pretty strong #Json bent, is flexible and pretty well designed for providing your own serialization tools on top of it (going back to my description of vertx as more of a good base layer to put the tooling on top of that you will _then use_ to build your service).
My first pass was to write a wrapper protocol with protobuf and having a byte array as one of its fields along with some metadata for deserialization purposes.
This works! But…
I need to go in and refactor it now that I have a better idea of what I am doing there and clean up the patterns where there's duplication.
The basic challenge is making sure that other parts of the ecosystem have an easy time registering the types they use with the #Vertx EventBus. My original plan was to do everything in protobuf, but as I moved away from the ersatz actor framework that became less appealing. Also #Kotlin data classes are _great_ for this sort of use case
Rabbit hole time!
But (3) we can definitely do.
Since we need a factory method anyways, we also might as well get cute in how we build it so that the class is fully abstracted and doesn't need to care that it is depending on Kotlin Serialization. We can do that with a sort of lightweight command pattern.
It basically creates a "reified chain" from the instantiation to the object that then allows for it to be reused later by someone less familiar with the type's specifics (e.g. #vertx).
Option 1: We can force the call site to know what they are deserializing. This seems appealing except that the point of this exercise is make it easy to pass data class objects over the #vertx event bus. It also requires downstream clients to know it in two different places and keep those in sync.
Option 2: We can pass in the type at object creation time at the same time we pass in class. We need both because we check for annotations and KTypes don't support them.
Okay, toy #ActivityPub progress:
I managed to get the web server actually up and running and most of the wiring in place to allow for the webfinger endpoint to work using OpenAPI.
There's been an excessive amount of gnashing of teeth to get here, but the end result is not bad.
I continue to think that #vertx is best thought of as a pretty low level library—it shines at the level of primitives and then you need to build your actual app framework on top of it.
I also think that it is doing a lot of things that are done very cleanly outside of #vertx by #gRPC and if I were going to focus on this as an area or work I'd rather put my time into making that sort of integration seamless. The gRPC plugin for vertx is ripe with possibilities here, but it is more focused on the #JAXRS-style use case instead of the internal one.
But I am more interested in other aspects of this problem right now and on getting a test bed up and running.