Bringing Kotlin to the cloud — my project to explore the possibilities — Part 1
With my background in Android development, how could I not be a fan of Kotlin lang? Moving from Java (which I am still using for any legacy codebase I encounter) to Kotlin is something that has helped me to really love what I do, to put me in a better mood as I work.
Part 1 — What I build and primary setup
The app — Calories Intake tracker app — will help me to know how much food/energy I have consumed during the day and let me know if I have reached my goal.
(Disclosure: I’m in the process of gaining weight)
Now for the interesting part! In the Backend, I would like for my app to store my historical data, and for this data to be accessible anywhere with an internet connection. I’d like to make it simple by building a Restful API Backend with the following CRUD operations:
- Create a new log entry for food intake
- Read all the entries I have
- Update a certain log entry
- Delete log entry
Time to explore
A Google search of “kotlin google cloud” brings back ‘https://cloud.google.com/kotlin/’ as the top result.
So what I need from the “Backend” in terms of engineering here is:
- It must be somewhat familiar to me (i.e. the language, the concept)
- It must be quick to create a prototype, with super-easy deployment (I’m not going to spend weeks learning how to configure the server properly)
- It must auto-scale — Just in case my app is going to hit the market hard!! 💵 💵 💵 💵 💵 💵 💵 💵 💵 💵 💵 💵 💵 💵 💵 💵 💵 💵 💵 💵 💵 💵 💵 💵 💵 💵
- Google App engine as the option to use on Google Cloud
- Ktor as the framework for my API app
- Google Cloud Datastore as the Storage Backend
All good, we are almost done!
Google provides a tutorial on how to proceed on the Ktor + App Engine https://cloud.google.com/community/tutorials/kotlin-ktor-app-engine-java8
- Create a project that will host your Ktor application. You can also reuse an existing project.
- Use the Google Cloud Platform Console to create a new Cloud Platform project. Remember the project ID; you will need it later. Later, commands in this tutorial will use
[PROJECT_ID]as a substitution, so you might consider setting the
PROJECT_IDenvironment variable in your shell.
- Enable billing for your project.
- Install the Google Cloud SDK. Make sure you initialize the SDK and set the default project to the new project you created.
- Version 175.0.0 or later of the SDK is required.
- Install JDK 8 or higher if you do not already have it.
In step 2, I re-used one of the projects on the Google Cloud Platform Console I created when trying out Google Functions (https://medium.com/@toantran/trying-out-function-as-a-service-with-azure-function-ca7b86b74e4f)
The next step, for me, was to explore the sample that GoogleCloudPlatform Github provided at https://github.com/GoogleCloudPlatform/kotlin-samples
Now that the configuration is set up and running on my local machine, that’s it for Part1! We’ll talk more about the business logic of our application and the deployment to Production with Google Cloud in Part 2.
Bringing Kotlin to the cloud — my personal project to explore the possibilities — Part 2
Part 2 will continue to discuss the business implementation (after Part 1 has already discussed the setup). You can find part 1 above.
As I mentioned in Part 1, we are looking for a very easy way to set up and deploy. Let’s verify this first.
I’m checking for
All good. Also, checking that my PROJECT_ID is set as default.
gcloud config set project my-project-id
It’s verified — one command deployment and my app is now live for the public.
Using gcloud app logs tail -s default I can check the logstream from my app on App Engine.
This would be the routing for my web application
The placeholder for my request only.
A get(“entries”) will return all the entries of food intake available
A post(“entries”) will send an array of food intake entries to our server to store in DataStore.
But there’s a problem! I want to check what will the request body of my “post” to our server look like? println()? no, thanks! Let’s do it the formal way, by having the debugger help here.
When I check on the quickstart page of Ktor, it seems there is something I missed here.
I’ll need to add ktor netty plugin to be able to run the web app inside IntelliJ and then I can debug! What’s next? Adding a new Run Configuration to invoke the app.
And I can read the json body of my POST request in debug mode
Next, save them to the local datastore
We need a data model to represent what fields we will capture and store in our database.
and the data repository to help us save/retrieve data in general.
Let’s connect them together.
And run the app with
./gradlew appengineRun (because it won’t work in IntelliJ without a correct AppEngine project template — I’ll fix this later!)
Trigger the POST and get the result. Check out at http://localhost:8080/_ah/admin/
It works but something seems wrong with the encoding when I try to create the content in Vietnamese. A quick search showed this https://github.com/ktorio/ktor/issues/384 The issue is still open with Ktor and seems to have an impact on the body content of requests only. I found a workaround on this https://github.com/ktorio/ktor/issues/384#issuecomment-458542686
It works! (I’ll revisit this later) — at least I can get my “bún bò” to display correctly now!
It’s good again! but wait! the id of your FoodEntry is a Long field and will be sent from the client. This is not scalable because I will have to keep track by counting for the next entry if I don’t want to accidentally delete/override an existing entry — which will cause a problem with data consistency.
I’ll modify the data model for FoodEntry.
The updated model for FoodEntry
And it’s time to deploy 🚀
My “bún bò” data entities are now live on Data Store.
Voila! The basis of our app is live! You can find the complete sample here under Github https://github.com/toantran-ea/food-intake-backend.
- I should have set the project up with the Google App Engine template to debug the app properly.
- I had some hiccups with the Ktor framework (related to encoding) but found work-arounds for it in the end.
- Short learning curve: As I had some previous experience with Google App Engine, and have used other web frameworks before (ExpressJS/Flask) the concepts were not too alien to me.
- The prototype was quick and easy to make, and show live, thanks to the great support of Google Cloud SDK CLI tools.
- It was quick to deploy (as you can see!)
- Working with Kotlin is very comfortable: As expected, I can use all the Kotlin features I want to without any problem.