Ktor: Crafting a Stock Portfolio Endpoint – Part 2
This is the second post in the series of posts that aim to build a single endpoint with Ktor by wrapping the AlphaVantage Quote Endpoint. If you haven't read Part 1, please at least skim through it to make sure we have a similar Ktor setup before continuing. If you have finished setting up all the code in Part 1, let's dive right in.
Secret API Key
One of the required fields of the Alpha Vantage endpoint is apikey
. The API key is used to determine the usage limit based on the plan. Most Alpha Vantage APIs can be accessed for free with the standard limit of 25 requests per day. Even with the most expensive premium plan of $249.99/month, there is still a limit of 1200 requests per minute. For that reason, the API key should be kept private and not committed to the GitHub repo. Otherwise, malicious users could exhaust your limit, rendering your server unusable. To learn more about API keys, you can read this Google Guide.
Storing the API key in an environment variable is arguably the simplest and most common method to hide it from the public. On the topic of environment variables, CircleCI has a great post explaining the basics. Then, assign your API key to an environment variable, as demonstrated in this guide from Nanyang Technology University (NTU).
Congratulations! You have set your API key to an environment variable. The next step is to access ALPHA_VANTAGE_API_KEY
from the application code. Remember choosing YAML
for configuration at the beginning? You can now utilize the application.yaml
to access the variable.
To test whether the key can be accessed correctly, you can modify the Routing.kt
to return the API key to the browser.
Running the application again should result in the browser showing the response with the API key as the value.
Response Model
Most public endpoints return a response in JSON format because it can be used in Javascript (the main language for most web applications) without the need for parsing or serializing. Unfortunately, a Ktor application requires parsing a JSON response to Kotlin code to extract the data effectively. First, let's take a look at a sample response from the Alpha Vantage endpoint.
A simple data class
that mimics the structure of the above sample response should work just fine.
Don't forget to add the @Serializable
annotations on top of the data classes so it can be parseable from the JSON. Those stem from the plugin that you will install in the next section.
API Call
Calling the Alpha Vantage endpoint means the server becomes a client, which requires a different set of plugins. By now, it's probably become second nature when it comes to adding new dependencies.
With all the dependencies set up, you can jump straight to creating a function that calls the API by following the Ktor doc. However, I'm going to apply the Bridge design pattern mainly for testability and cross-platform compatibility.
Note that the HttpClient.get is a suspending function, so getQuote must be a suspending function as well to handle the network call asynchronously. To learn more about suspending functions and Kotlin coroutine, check out this awesome introduction video.
Next, you can simply call the API in the Routing.kt
to test by printing the response to the browser. By now, the main function configureRouting
should look something like this.
Serial Name
After running the current code, the browser displays an error. Fear not. Dealing with errors is always part of the process.
As you may have guessed, @Serializable
annotation isn't smart enough to parse such a weirdly formatted field name from the Alpha Vantage endpoint. In other words, it doesn't know that "Global Quote" should be parsed as globalQuote
or "07. latest trading day" to latestTradingDay
. To fix this, you can use the annotation @SerialName
as suggested in the error message.
Now, the plugin should know how to map each field from the JSON response to the corresponding Kotlin model. The server application is now completed.
Conclusion
That's it! Congratulations, you have successfully wrapped the Alpha Vantage Quote Endpoint in a Ktor server that returns a Kotlin response. However, it is not complete without proper unit tests, which will be explored in Part 3. Stay tuned for Part 3 by subscribing to our newsletter, and please share your thoughts or questions in the comments section below!
Comments ()