We're sorry but this page doesn't work properly without JavaScript enabled. Please enable it to continue.
Feedback

Idiomatic Kotlin Microservices

00:00

Formal Metadata

Title
Idiomatic Kotlin Microservices
Subtitle
A live coding session on how to go pure Kotlin with microservices
Title of Series
Number of Parts
490
Author
License
CC Attribution 2.0 Belgium:
You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal purpose as long as the work is attributed to the author in the manner specified by the author or licensor.
Identifiers
Publisher
Release Date
Language

Content Metadata

Subject Area
Genre
Abstract
Although Kotlin is, from a language perspective, 100% interoperable with Java, due to the slight paradigm shift (nullability) there might be some pain when using Java frameworks, e.g.: the need of private var lateinit when using JUnit, having to use compiler plugins to open up Spring annotated beans or a generated zero-arg constructor for Hibernate. This talk goes through a full fledged alternative to the common Java stack when writing microservices, using: Ktor (Web framework), Kodein (DI container), Exposed (SQL library), Spek (test framework), Gradle Kotlin DSL, ...
Library (computing)Java appletContent (media)Process (computing)CodeMenu (computing)Software testingServer (computing)RootExpected valueSuite (music)Real numberReading (process)Hand fanCartesian coordinate systemRootSpring (hydrology)Software testingKeyboard shortcutINTEGRALWeb 2.0Multiplication signZoom lensResultantEquals signDependent and independent variablesImplementationStatement (computer science)CodeLaptopFront and back endsServer (computing)Computer animation
Server (computing)Execution unitConfiguration spaceCartesian coordinate systemConfiguration spaceLambda calculusRoutingGame controllerDemonComputer animation
String (computer science)Execution unitConfiguration spaceSummierbarkeitSequenceSoftware testingExpected valueParameter (computer programming)2 (number)System callDrum memoryArithmetic meanSoftware testingComputer animation
Software testingServer (computing)RootLibrary (computing)System callRoutingJava appletContext awarenessCartesian coordinate systemComputer animation
Software testingServer (computing)RootRoutingAsynchronous Transfer ModeInterface (computing)Service (economics)InjektivitätPresentation of a groupSpring (hydrology)Computer clusterComputer programService (economics)Cartesian coordinate systemExterior algebraEnterprise architectureImplementationBitSoftware frameworkBootingCodeComputer animation
Interface (computing)Service (economics)String (computer science)CodeInterface (computing)Reading (process)Object (grammar)Keyboard shortcutFunctional (mathematics)Computer animation
Service (economics)Interface (computing)String (computer science)Endliche ModelltheorieDependent and independent variablesParameter (computer programming)Computer animation
Factory (trading post)Java appletSinguläres IntegralDependent and independent variablesSoftware testingService (economics)Installation artLibrary (computing)Endliche ModelltheorieObject (grammar)Electronic mailing listSoftware testingComputer animation
Software testingRootInstallation artRoutingService (economics)Interface (computing)String (computer science)Programming paradigmBitPlug-in (computing)Software frameworkShift operatorUniform resource locatorSocial classParameter (computer programming)CompilerConstructor (object-oriented programming)Formal languageComputer animation
String (computer science)Service (economics)Interface (computing)Software testingData modelLibrary (computing)Server (computing)RootContent (media)Level (video gaming)String (computer science)SpacetimeTest-driven developmentComputer animation
String (computer science)Content (media)Dependent and independent variablesRootServer (computing)Software testingExtension (kinesiology)Object (grammar)Library (computing)Expected valueFunctional (mathematics)SpacetimeComputer animation
String (computer science)Content (media)RootSoftware testingSoftware testingMereologyComputer animation
RootSoftware testingContent (media)RootDefault (computer science)Cartesian coordinate systemProper mapFunction (mathematics)Context awarenessSpring (hydrology)Parameter (computer programming)Instance (computer science)Service (economics)Computer animation
Software testingRootContent (media)Source codeFactory (trading post)Service (economics)Interface (computing)Data modelExtension (kinesiology)MereologyService (economics)Endliche ModelltheorieInterface (computing)Computer animation
Content (media)Service (economics)Endliche ModelltheorieRootExtension (kinesiology)Software testingInformationBuildingError messageData modelData typeExpressionFormal languageElectronic mailing listVarianceRow (database)Constructor (object-oriented programming)Computer animation
Software testingRootContent (media)Error messageTypinferenzData modelData typeEndliche ModelltheorieService (economics)Suite (music)Java appletDependent and independent variablesMountain passLibrary (computing)Interface (computing)Social classRepository (publishing)Repository (publishing)Endliche ModelltheorieMultiplication signInversion (music)InjektivitätSoftware testingJava appletImplementationGame controllerComputer animation
Data modelRepository (publishing)Interface (computing)Service (economics)AbstractionElectric currentImplementationModemLatent heatReading (process)Object (grammar)Type theoryDatabaseFilm editingComputer animation
Repository (publishing)Interface (computing)Data modelService (economics)ExpressionSequenceSoftware repositorySoftware testingCompilerFigurate numberType theorySoftware repositoryComputer animation
Library (computing)Interface (computing)Repository (publishing)Data modelSoftware testingInstance (computer science)Service (economics)Repository (publishing)Endliche ModelltheorieComputer animation
Repository (publishing)Data modelError messageSoftware repositoryInterface (computing)String (computer science)Table (information)Formal languageInteractive televisionEndliche ModelltheorieSelectivity (electronic)DatabaseTable (information)ResultantBitRotationReal numberComputer animation
Table (information)Data modelString (computer science)Repository (publishing)Interface (computing)Table (information)Endliche ModelltheorieResultantRight angleMappingComputer animation
Java appletDatabase transactionAsynchronous Transfer ModeData modelTable (information)Software testingException handlingDatabaseUsabilityRepository (publishing)Connected spaceSystem callDatabaseParameter (computer programming)Default (computer science)Computer animation
Table (information)Data modelRepository (publishing)DatabaseString (computer science)Installation artGeneric programmingInstance (computer science)Software testingElectric currentDatabase transactionRootExtension (kinesiology)Configuration spaceWeb 2.0Software testingConnected spaceDatabaseComputer animation
Software testingRootData modelTable (information)Repository (publishing)String (computer science)DatabaseSystem callLibrary (computing)Context awarenessDatabase transactionQuery languageFunction (mathematics)WebsiteNavigationDifferent (Kate Ryan album)Database transactionComputer animation
Data modelTable (information)String (computer science)Database transactionDatabaseRepository (publishing)Software testingDefault (computer science)Exception handlingStatement (computer science)Query languageState of matterTable (information)Endliche ModelltheorieDatabase transactionComputer animation
Data modelRepository (publishing)Database transactionString (computer science)DatabaseTable (information)Software testingInterface (computing)Spring (hydrology)BootingSocial classBitComputer animation
String (computer science)DatabaseDatabase transactionData modelTable (information)Repository (publishing)Instance (computer science)Generic programmingServer (computing)Dependent and independent variablesInstallation artService (economics)IntelInterface (computing)Software repositoryWeb 2.0Server (computing)Connected spaceDatabaseSerial portLibrary (computing)InjektivitätSoftware frameworkService (economics)Endliche ModelltheorieProper mapComputer animation
Service (economics)Data modelInterface (computing)Repository (publishing)Software repositoryString (computer science)Table (information)Duality (mathematics)Database transactionDatabaseDevice driverSoftware testingRootExtension (kinesiology)Generic programmingSoftware testingRepository (publishing)Endliche ModelltheorieInstance (computer science)Object (grammar)Functional (mathematics)Computer animation
Interface (computing)Service (economics)Software repositoryData modelString (computer science)Software testingGeneric programmingRootSerial portLibrary (computing)Computer animation
Data modelString (computer science)Interface (computing)Service (economics)Software repositorySoftware testingGeneric programmingRootEndliche ModelltheorieContent (media)Endliche ModelltheorieSoftware testingBusiness objectDifferent (Kate Ryan album)DatabaseRepresentation (politics)Extension (kinesiology)Data transmissionFunctional (mathematics)MappingObject (grammar)Computer animation
SicEmailSoftware testingData modelGeneric programmingRootGradientServer (computing)BuildingImplementationModulo (jargon)String (computer science)Revision controlTask (computing)Plug-in (computing)Repository (publishing)Context awarenessScripting languageModule (mathematics)LoginException handlingProjective planeConfiguration spaceSource codeDirectory serviceBuildingObject (grammar)Computer animation
Software testingGradientPlug-in (computing)Revision controlImplementationContext awarenessModule (mathematics)String (computer science)Scripting languageTask (computing)Repository (publishing)LoginMultiplication signRevision controlNumberComputer animation
Web 2.0Lecture/Conference
Open sourcePoint cloudFacebook
Transcript: English(auto-generated)
Hi everyone, thank you for coming. So, I'm happy to welcome Christoph that is going to talk about adiomatic Kotlin microservices. Please give him a warm welcome.
Can you hear me? Yes. So, nice and dry and warm in here and no free Wi-Fi. I guess that's the reason why most of us, or some of you are using your laptop here. Still, if you want to pay attention to me, that would be nice. Otherwise, just do whatever you're doing.
How many of you actually are 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? Thought so. Great. Time is very limited and precious, therefore I will start right away. We're 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 mistyped anything. Yes, this works. Great success. What's the shortcut again? Here. I'm a big fan of TDD, so test-first approach, therefore just go here.
And 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 test-ng 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 immediately store the result here.
And so we can immediately take that result and say the response of the result, the status code should be equal to...
Come on. Okay. Let's zoom out a little bit here. Can you read that? Code is readable? Yes, thank you. Foo might not be a nice name, so when we get the root path, then 200 OK, then return 200
OK. Let's give that 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 Netty 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 daemon in the background. Definition of a routing, no REST controllers and weird things, just pure Kotlin, so we do have our lambdas here, the route to...
Why won't you work? Routing route here, yes. Oh, we need the second argument here. And when you get the GET, we just respond the call with some text here and say, hello, Fosden.
So, run the test again. Drum roll, spibble. Still null, meaning he can't find the endpoint. So, what we have to do is we actually need to wire up 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 an amazingly lightweight alternative to Spring Boot. I remember I gave a presentation about Spring more than ten years ago, and I was announcing it
as the lightweight alternative to EJBs, enterprise Jesus beans, the really 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 for Spring. Nowadays, Spring is the heavyweight thing, slow. It can do everything, maybe nothing. It's holy. It's really heavy.
So, Ktor for me is what Spring used to be ten 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 injection 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 used to 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. 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 singletoner 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 you will see in a minute.
We just get the service, but telling Cody 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, or the 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. Jesus and Jackson 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 to Java. Yes, this is true from a language perspective, but from a framework perspective, that's due to the paradigm shift that's not fully true. They came up with solutions, maybe more like hex, with compiler plug-ins to have zero R constructor and to open up all my classes afterwards.
You know, everything is fine and suddenly compiler goes there and makes it open. Like, wow. For me, that'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 plug-in 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. 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 know,
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 a JSON? Let's just do it like this. We haven't seen anything.
And this is me cheating a little bit. This is an asset K. Asset K is the K port of asset 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 will ignore all the white space and ordering and stuff.
So, I just assume that this is already existing. Maybe the asset K library should, could use some pull request to actually incorporate that extension function 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? 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're going to change that. But first, I'd like to split those tests. So, give a stub service when get root prof then return proper JSON, whatever.
Remember here, I passed in an instance of Corinne, but I immediately used a default argument. Because now I can actually override my, in Spring speak application context.
We, therefore, extend the original Corinne part. We extend the original binding of a single bean. 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 stub 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. It's so amazing. Yeah, I'm in love with this language. Let's run it again. Ooh, what the fuck just happened here?
Yeah, we need to pass in the 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 arg and record the same constructor, but just transform it to a list. Why won't you, why won't you work?
Oh yeah, thank you so much. Wow, if I would have something to give away, you would get it now. You can have a sticker. Too bad. 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,
and so the testing is in full control of what's going on. Kotlin put into Ktor, everything lightning fast, everything Kotlin. Brief. 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 sequel, 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, like dependency injection and inversion of control, that's awesome. And like, I don't know what you're talking about, but I really feel stupid now. And like two years later, I actually got to know the words, the buzzwords, like dependency injection.
Like, yeah, I actually used it for years already. Like, fuck you. If I would have known that like 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 this 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 value here, repo read all. So here, compiler thank you. And 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, bleh, strange. Singleton instance actually. So actually here he says, binding the dummy service requires a model repository.
So let's give him a model repository. I have no clue what's going to happen. Here, missing some parenthesis. Compiler, I like statically typed languages so much. So this all goes through. Still, I'm a little bit concerned, because actually there is nothing happening here.
There is no real database interaction going on. So how about defining the table, which is basically, oh, surprise, a table. And it is varchar and the table column should be named name and the length, whatever, something like 50.
So in the rotation, rather than have our dummy rotation 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 is only one property, which is name. So we get back from the model table dot 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 back in the good old days, and just map it with this magic.
Right. Let's give the run. Please call database connect. Oh, yeah, let's do that. That's nice. Thank you. 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 to the database. That should work, right? Bless you. Please call connect. What's happening here?
Oh, yeah, test. 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 Ktor with this Ktor 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 magic here. So just go there and say transaction. Are we done yet? Come on. Like step by step. No, we're not. There's still one more thing missing because he states, where is it?
Table not existing. Table model not found. Yeah, then 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. You do it once.
Make a transaction. 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 a one-time setup.
Now, come on. Come on. Do it. Do it. Done. Yeah. Looking good so far. Connect to the database. We have our web server. We have our cater using CodeIn as a dependency injection framework. We have JSON serialization. We have the CodeIn X serialization library.
It's a routing, quite straightforward. We can marshal our model into proper JSON for services. We don't have tests for the exposed model repository here. It would be nice to have some, but I decided not to do that. Something I personally like doing is instead of instantiating my value objects here manually,
because I actually don't care what value is in there, so I'd rather go here and say any. That's not possible. Okay, 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 do this, but for some magical reason, I guess because of the serialization annotation. Yes.
Interesting. I didn't know that. I usually use Jackson, to be honest. Shame on me. I'm not using a pure CodeIn library. Maybe I will. So now we can go there, and this is kind of reusable test infrastructure, all this 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 CodeIn, so the greater configuration is CodeIn 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 CodeIn 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 CodeIn version two times. But having this thing actually solves the problem.
Yes, I'm done. Thank you for your attention. I hope you understood. Any questions? Yeah, we have a couple of minutes for one or two questions.
Simple questions. Yes. May I know your opinion about Ktor versus Micronaut or Guarco frameworks? Thank you for asking 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 there. That's highly biased, 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 are 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.