An Optional’s place in Kotlin

Jake Wharton
May 14, 2017 · 2 min read

Heads up, we’ve moved! If you’d like to continue keeping up with the latest technical content from Square please visit us at our new home https://developer.squareup.com/blog

With nullability being a first-class citizen in Kotlin’s type system, the need for an Optional type seems all but diminished. Just because you can explicitly express nullability, however, does not mean that null is always allowed.

For example, Retrofit provides adapters for RxJava 1.x and 2.x which allow modeling your requests as a single-element stream.

interface MyApiService {
@GET("/api/user/settings")
fun userSettings(): Observable<Settings>
}

RxJava 2 differs from RxJava 1 in that it does not allow null in its streams. If we’re using RxJava 2 and the converter for Settings returns null an exception will occur. Thus, in order to represent the absence of a value for the response body inside this stream we need an abstraction like Optional.

Retrofit 2.3.0 introduces two new delegating converters for the Optional types in Guava and Java 8. Unlike the other converters for libraries like Moshi, Gson, and Wire, these new ones are different in that they don’t actually convert bytes to objects. Instead, they delegate to other converters for processing the bytes and then wrap the potentially-nullable result into an Optional.

val retrofit = Retrofit.Builder()
.baseUrl("https://example.com")
.addConverterFactory(Java8OptionalConverterFactory.create())
.addConverterFactory(WireConverterFactory.create())
.addCallAdapter(RxJava2CallAdapterFactory.create())
.build()

With one of the Optional converters added alongside a serialization converter, requests whose bodies may deserialize to null can be changed to instead return an Optional.

interface MyApiService {
@GET("/api/user/settings")
fun userSettings(): Observable<Optional<Settings>>
}

Today’s Retrofit 2.3.0 release contains the same JSR 305 annotations for explicit nullability in Java and Kotlin as our recent Okio and OkHttp releases. As we’ve seen above, though, just having these annotations​ or a type system that can model nullability sometimes is not enough. For these cases, in Java and Kotlin alike, the use of Optional has its place.

This post is part of Square’s “Square Open Source ♥s Kotlin” series.

Square Corner Blog

Buying and selling sound like simple things - and they…

Thanks to Jesse Wilson

Jake Wharton

Written by

Stop stopping.

Square Corner Blog

Buying and selling sound like simple things - and they should be. Somewhere along the way, they got complicated. At Square, we're working hard to make commerce easy for everyone.

Jake Wharton

Written by

Stop stopping.

Square Corner Blog

Buying and selling sound like simple things - and they should be. Somewhere along the way, they got complicated. At Square, we're working hard to make commerce easy for everyone.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store