Playing with Kotlin: “You actually know everything John Doe!”
How to build a full project entirely with Kotlin? (backend/frontend + app)
After a long android freelance contract, and because I had some free days, I decided to dedicate myself into a full project entirely written in Kotlin, just to know how far I could go with this excellent language.
To concretize this full project, I chose to create a platform that helps developers find out the perfect jobs, selected and approved by other expert developers.
And because I’m currently looking for a remote position, this idea seemed pretty appropriate… 😅
Designing the Architecture
Simplicity is the soul of efficiency — Austin Freeman
Because this project tends to be a Kotlin showcase, I wished to make the first release very simple :
- The Backend/Frontend: Shows the website and allows any user to submit a job. For now, it’s more a frontend than a backend (actually we could consider Firebase as the main backend here). However, especially because this is deployed on GCP, this can evolve into a proper backend easily.
- The Android app: List the jobs approved by expert developers and show each one through a web view.
Implementing the backend 🌏
I’m used to working with Google App Engine (aka GAE) that allows you to build and deploy highly scalable applications on a fully managed serverless platform. It’s like AWS, but made by Google.
Basically, when you are using Ktor to create your web server, you just have to :
- Create the entry point file of your server that will mainly configure its different routes :
- Specify in a dedicated file, for each page/route, how and which REST methods you want to handle:
- Add the related HTML content into a Freemarker file. If you know about String template in Kotlin, you would have no issue with Freemarker :
I also created a template file in order to reuse some HTML components like the header or the footer for instance. This feature is called “macro”.
That’s it 🙂 As you can see with the index page example, the backend code using Ktor is pretty simple and readable.
What about testing?
Ktor provides a simple way to test your server, without actually creating a web test server. Indeed, you have to use the “withTestApplication” method that starts a test application engine. Then, you will be able to handle a request and assert whatever you need to.
I also used Mockk to mock and prevent the connection to the real Firestore database during tests.
Implementing the Android app📱
As an Android Engineer, this part was really the easy one… 😅As you can see in the module “android” inside the repository, the app uses :
- Dagger2 for dependency injection. In a future release, I think I will give a chance to Koin (for both Ktor and Android BTW), especially because it seems so easy to implement using DSL (and also because it’s French… 🥖🥐🇫🇷).
- FirebaseUI to handle more properly and easily the pagination with Firestore.
Right now, this app is pretty simple as you may have seen. Maybe the only thing new (at least for me) that I recently discovered through Google samples, was the ability to define a class as “open” ONLY FOR TESTING with an annotation.
For example, this class (JobDao) is annotated with the OpenForTesting annotation I created (which inherit of the OpenClass annotation), allowing me inside my instrumented tests to create an anonymous class inheriting from JobDao and modify its behavior with some mock:
Don’t forget to create the almost same annotation for the release builds, without the inheritance from the OpenClass annotation, of course 🙂
Finally, the last thing I would like to share with you about this android app is the usage of Mockk. This DSL style mocking library is pretty simple to use and allowed me to mock a complete Firestore response. So useful!
Besides, one of its features I truly loved is the “Relaxed mock”: This allows to skip specifying behavior for each case, while still allow to stub things you need… 👌
The first release of NoBullshit was intended to play with Kotlin and find out the possibility of this fantastic language, especially for the backend side.
FWI, it took me only 5 days to achieve this project (including testing), thanks to all the resources and existing samples. When you think about it, this was very fast, mainly due to the mature and huge Kotlin ecosystem.
This project is open source, so feel free to contribute and push some fresh features or help me pointing out some bugs or best practices!