 Hi everyone. Thank you for coming. So I'm happy to welcome Christophe. There is going to talk about automatic coupling microservices. Please give him a warm welcome. Can you hear me? Yes. So nice and dry and warm in here and no free wifi. I guess it's the reason why most of us, some of you are using your laptop here. Still if you want to pay attention to me, that would be nice. Just do whatever you're doing. How many of you are actually using Kotlin? Wow, love that. Nice. Who of you are using Kotlin as an Android developer? As a backend developer? Great. Something else? I mean native? Anyone doing that? Yeah, thought so. Great. Time is very limited and precious. Therefore I will start right away. I'm going to write a microservice. So just for the sake of... Oh, I'm a little bit shaky and nervous. So just to give it a try. Please excuse if I mistab anything. Yes, this works. Great success. That's the shortcut again here. I'm a big fan of TDD. So test first approach. Therefore just go here. I'm not going to use spec. I wanted to use spec, but it didn't feel right. It is like tailored to Kotlin, but honestly I want to be honest and therefore I use TestNG because I just figured out it suits my needs better than JUnit or spec. So therefore we're going to go here and say we've got a test application. We are firing a request and we can immediately store the result here and so we can immediately take the result and say the response of the result. The status code should be equals to... Come on. Okay. Let's zoom out a little bit here. Can you read that? Kotlin's readable? Yes. Thank you. That would be a nice name. So when we get the root path, then 200 okay. Then return 200 okay. Let's give it a try. Can we? No, we can't. That's interesting. I can't collapse that import statement here. Anyway, it fails with actual null. So it doesn't fail with 404, which is strange because the implementation of Ktor's test engine so we are not spinning up a real HTTP server here. It's kind of a fake thing. Therefore it's lightning fast. Everyone who has used Spring Boot, yeah, we know the pain of having integration tests and they take like four hours. Ktor is quite fast because it doesn't actually spin up a web server, which comes with some drawbacks as well, to be honest. So we are going to actually start an embedded server here. We are using native for that purpose. And here, just externalize the application configuration. We don't need you. And we need to tell Ktor to not immediately die afterwards. So we tell him run as a demon in the background. The definition of a routing, no rest controllers and weird things, just pure Kotlin. So we do have our lambdas here. The root to, why won't you work? Routing root here, yes. Oh, you need the second argument here. And when you get the get, we just respond the car with some text here and say hello foster. So run the test again. Drum rules. Still null, meaning he can't find the endpoint. So what we have to do is we actually need to wire up our, let's do it like this, our test application context and tell the application context here to also configure the Ktor endpoint here. Run it again. Great success. Is everyone still following me? Yeah, it's like in school. Yeah. Thank you. Are you still awake? Yes, great. So that's for Ktor. It's like amazingly lightweight alternative to spring boot. I remember I gave a presentation about spring more than 10 years ago and I was announcing it as the lightweight alternative to EJBs and perhaps Jesus Beans. Heavyweight XML, you know, like really cumbersome. And it was spring, yeah, nice, quick and fast and like really like I could actually enjoy writing applications with spring. Nowadays spring is the heavyweight thing, slow, it can do everything, maybe nothing. Can like it's holy, it's really heavy. So Ktor for me is what spring used to be 10 years ago now. It's really nice. I love working with it. Add some magic. How about something like spring used to be a spring framework, used to be a dependency and texture framework. Nowadays it's a Jesus, I can do everything, silver bullet. Sorry for my bashing. I'm very much opinionated, so don't take me serious. So the way you register beans, no spring configuration, no annotation tree, like nowadays we in Java, we program annotations, not in Java anymore. We use the program in XML, which is quite a little bit of an improvement, but in Kotlin we actually can use code to configure our application, that's awesome. Imagine the possibilities, what we can do with code. Oh, maybe I should first define some bean, let's say you have a service and we read all models. Oh yeah, what's a model? We just have a model, let's give it a name, it needs to be a property. So some dummy implementation of that service, strip. So let's return a dummy, bless you. We return a model and give it some name, doesn't matter. So we bind that interface with that singletner and pass it. Actually we don't need to instantiate that guy, so make it an object class, nice. This here is, these are infix functions. We don't need dots, reads like a novel. Now I want to actually wire in here my code in guy, so just use default arguments, I don't need to pass it over there. I'm doing that for a reason that you will see in a minute. We just get the service, but telling code in give me some service. There is some lazy initialization here and when we respond, we don't respond with a text actually, but we respond with the other models. So run the tests again. So couldn't transform singleton list, so he is not capable of transforming this list of models into a JSON object, so let's just tell him how to do that. We are going to install a feature, a feature which is called content negotiation. We've got several possibilities here, JSON and JSON, and I would like to go pure Kotlin and that's the Kotlin exteriorization library. So that should be enough, right? So now he magically registered some things. Oh no, he still doesn't know how to do that. Can't locate argument less serializer. JetBrains claims that Kotlin is compatible with Java. Yes, this is true from a language perspective, but from a framework perspective, due to the paradigm shift, that's not fully true. They came up with solutions, maybe more like hex, with compiler plugins, they have a zero R constructor and to open up all my classes afterwards, everything is fine and suddenly compiler goes there and makes it open, like wow. For me, it's a little bit like a smell, but anyway, so if you work with Hibernate, you also were already in the misery of having the need of introducing zero R constructors through some plugin and bam. So much for Kotlin. Now I actually would like to test that. Oh, fuck me, sorry. I just didn't write the test first. Happens. Yeah, blame me, blame me, please. This is really not good. So we could of course go there and assert on string level and then you need to watch out for white space and stuff, so I don't want to do that. So I want to say it should be, hmm, hmm, how do we do that as I'm chasing? Let's just do it like this. You haven't seen anything. And this is me cheating a little bit. This is as a K, as a K is the K port of as a J, oh wow, so creative. On a string, and it says, given that, you know, do some magic that expected should be transformed and there should be no extra arguments, it just really ignore all the white space and ordering and stuff. So I just assume that this is already existing. Maybe the SFK library could use some pull request to actually incorporate that extension function. It would be nice. So let's run the test again. You know, always fail first. Bam, it fails. Expected values, but got one. Can you please tell me which one you got? Hmm, anyway, I know there's one object whose name is, I guess, X. Is it X? Yes. Great success. I don't like that. I don't like that there are implicit assumptions in the given part. There is something which is actually not in the then part, in the assert part. It doesn't show up in the given part. So we are going to change that. Let's run those tests. So give them a sub-service when get root path then return proper JSON, whatever. Remember here, I passed in instance of code in, but I immediately used a default argument. Because now I can actually override my in SpringSpeak application context. We therefore extend the original code in part. We extend the original binding of a single beam. But in my test, I'm going to override it with a testable service and we will give it some model. So first of all, I need some model. And the testable service is just a kind of a stop here. So it requires a list of models. It implements the service interface as well. Singer expression method, nice. That's so nice and shiny. I love Kotlin so much. That's amazing. Yeah, I'm in love with the language. Let's run it again. What the fuck just happened here? I need to pass it a list. Actually, I don't like it to pass a list. You know, that's somehow weird. Maybe do some constructor magic here. Secondary constructor, which requires a var arc and recall the same constructor, but just transform it to a list. Why won't you work? Oh yeah, thank you so much. Wow, if it would have something to give away, you would get it now. You can have a sticker. Why won't it work? Yeah, of course. Because in my here, what I can do now is what I like way better is IntelliJ and Kotlin. It's not there yet. Java is still ahead. In my opinion, Java support IntelliJ is still superior than Kotlin's. Done. So I like that in my given part, I actually repeat what is asserted in the then part. In full control of what's going on. Kotlin put into Cater. Everything lightning fast. Everything Kotlin. Breathe. Seven more minutes. The last nice thing I want to show you is exposed. Ten minutes. Oh wow, even nicer. In that case, I can talk a little bit slower. Exposed. It's JetBrains hibernate alternative, I would say. It's not really hibernate alternative. It's just a lightweight whatever it is. I'm not good with words. I just do writing code. That's what I love. Someone once told me at the beginning of my studies, you know, dependency injection and inversion of control, that's awesome. I don't know what you're talking about, but I really feel stupid now. Two years later, I actually got to know the words, the buzzwords, dependency injection. Yeah, I actually used it for years already. Fuck you. If I would have known that years ago, so I'm kind of bad with words, but I actually know them, but I don't know how to call it most of the time. So if you come up and someone is, you know, like playing cards and use all these buzzwords just, yeah, whatever. So we have an implementation of the model repository. We call it the exposed repository. It's a model repository. Yeah, quite boring. We just do a read all again and we won't have a specific database object kind of type for the sake of simplicity. Maybe we're going to introduce it if there's still time. So I'm just going to cheat here, cut that here, paste it in here for the time being. And I actually want the service, which now needs to be a class because it will have a reference to our, let's call it repo. So it just delegates to the repo. Missing a while here. Repo, read all. So here compiler, thank you. That's interesting. I just say instance. You know, just figure out the type which is needed here and somehow do your magic. So I need to satisfy here. I'm again here doing no test first, shame on me. I maybe just run the test now. So we require a bean which he cannot find, I guess. So no binding found for model repository with strange. Sing it an instance actually. So actually here he says binding the dummy service requires a model repository. So let's give him a model repository and I have no clue what's going to happen. I'm here missing some parentheses. Compiler, I like statically type language so much. So this all goes through. Still I'm a little bit concerned because actually there's nothing happening here. There is no database interaction going on. So how about defining the table which is basically surprise, a table and it is a var char and the table column should be named name and the length whatever, something like 50. So in implementation rather than have our dummy implementation here we can actually go and say the model table select R we need to transform this kind of result set into a model and there's only one property which is name so we get back from the model table name. So this is how you do a mapping. The select R gives you back a result row a result set we used to call it in the good old days and just map it with this magic. Let's give it a run. Please call database connect. Let's do that. So let's call it connect to database. Database URL. I'm going to do some magic here again and immediately make it a default argument parameter. I don't want you to close immediately your connection. So please wait with that. The URL and the driver I use H2 database. Of course this needs to be invoked somewhere so maybe when we start up the web server we also start up the connection database that should work right? Bless you. Please call connect. What's happening here? We need to do that in the test as well because this is out of the scope of the test. The test is actually just starting up Cater with this Cater configuration. So really dirty. I would not recommend doing that in real test. This is just for the sake of demoing it here. Just want to use a different in memory name here. No transaction. Oh well. Then maybe he needs some transactional logic here. So we just go there and say transaction. Are we done yet? Come on. There's still one more thing missing because he states where is it? Table not existing. Table model not found. Let's create the table model. Thank you. So we just after we connected immediately we're going to do a schema utils. This is just something you have to know and create model table. Make it transactional otherwise he will complain. In my work project I have implemented some class path scanning and it feels a little bit like spring boot again. Yes, to be honest. I annotate things and actually I use interfaces rather than annotations. So yeah, this is one time setup. Come on. Come on. Do it. Do it. Yeah. Looking good so far. Connect to the database. We have our web server. We have our caterer using code in as a dependency injection framework with Jason serialization with the code in X serialization library. It's a routine quite straightforward. You can marshal our model into proper Jason for services. We don't have tests for the exposed model repository here would be nice to have some but I decided not to do that. But something I personally like doing is instead of instantiating my value objects here manually because I actually don't care what values in there. So I rather go here and say any. That's not possible. So we just say model.companion.any make it a function so it's reusable test instances. Right. And it actually works. I didn't expect it to work because usually what's necessary is to do this but for some magical reason I guess because of the serializer annotation. Yes. Interesting. I didn't know that. I usually use Jackson to be honest. Shame on me. I'm not using a pure Kotlin library. Maybe I will. So now we can go there and this is kind of reusable test infrastructure. All these stuff and I can rather go here and say model.any. That's also the way I do it with transforming mapping it from rest data transfer objects to domain objects to database objects. There are extension functions which can transform your model into different representations. Yes. I guess that's it. This project is on GitHub. It's of course everything pure Kotlin so the greater configuration is Kotlin here so I can actually declare functions here. That's really nice and I really like the build source directory here because what I do here is I have an object with all my versions because you might have encountered a problem in Gradle with the Kotlin DSL that if you got here a version number you can't actually declare a version number here and reference it here because of the way Gradle is just designed that's not possible so you have to re-declare the Kotlin version two times but having this thing actually solves the problem. Yes. I'm done. Thank you for attention. I hope you understood. Any questions? We have a couple of minutes for one or two questions. Simple questions. Yes. May I know your opinion about Ktor versus Micronaut or Quarkus frameworks? What do you think about my opinion? I like that. My opinion about Ktor versus Micronaut and the other one I didn't get but I think I also don't know it which also applies to Micronaut, therefore my opinion is I go for Ktor because I know it it's from JetBrains. When I went and looked for Microservices, web frameworks the first thing we popped up was Ktor and I think it's more popular so please don't take my answer too seriously. Micronaut, I've heard about it, never used it so I can't answer that. Still go for Ktor. Anyone? One more? People leaving, people coming? Otherwise, I will be here if you feel like talk, chat, exchange please feel free to approach me. Thank you so much. Thank you very much.