Search code examples
androidkotlinretrofitretrofit2

What are the disadvantage of declaring all request parameter of an endpoint?


Since Kotlin enables us to define default values for a method's parameters and lets us optionally pass parameters by their name, I prefer to define all the endpoint request parameters when declaring an API endpoint. The following is an example for the Foursquare places search endpoint:

private interface RetrofitFsqNetworkApi {
    @GET(value = "{version}/places/search")
    suspend fun placesSearch(
        @Path(value = "version", encoded = true) version: String = "v3",
        query: String? = null,
        ll: String? = null,
        radius: Int? = null,
        categories: String? = null,
        chains: String? = null,
        @Query("exclude_chains") excludeChains: String? = null,
        @Query("exclude_all_chains") excludeAllChains: Boolean? = null,
        fields: String? = null,
        @Query("min_price") minPrice: Int? = null,
        @Query("max_price") maxPrice: Int? = null,
        @Query("open_at") openAt: String? = null,
        @Query("open_now") openNow: Boolean? = null,
        ne: String? = null,
        sw: String? = null,
        near: String? = null,
        polygon: String? = null,
        sort: String? = null,
        limit: Int? = null,
        @Query("session_token") sessionToken: String? = null,
    ): NetworkPlacesSearch
}

So the caller can call with optional parameters with any combination such as:

placesSearch()
placesSearch(query="burgur")
placesSearch(ll="1234,-12322", radius=100)
//...

I need to know if are there any disadvantages to doing this.


Solution

  • Mainly, the code readability and simplicity decrease drastically. It may be hard for another programmer to read such method.

    First of all, as I see, a lot of your parameters are nullable, so they are also optional for API call. If the request misses some of optional parameters, the server's API is totally fine with it and can easily omit their processing. That means that you probably don't need to declare all of these parameters if you never use them.

    However, if you do use all of parameters in some of your application use cases, it is better to create data class which will represent the body of your request.

    data class MyRequest(
        val version: String,
        val query: String? = null,
        ... // All other parameters.
        ... // If some of the parameters are not used in any use case,
        ... // simply don't add them to the data class
    )
    

    Then, in the service interface:

    suspend fun placesSearch(@Body request: MyRequest)
    

    By now it should probably be easy to see the difference in simplicity.