Retrofit — Send Data Form-Urlencoded Using FieldMap

There are multiple ways to send data from your client to a server. This post continues the first article on how to use form-urlencoded requests with Retrofit to transmit data with your request. If the API you’re going to request accepts a simple JSON payload for processing, this approach is definitely worth a look.

There’s a lot value within this Retrofit series and you may want to scan through the previously published articles before going deep on Retrofit’s FieldMap :)

Retrofit Series Overview

  1. Callbacks (Coming soon)
  2. Annotations (Coming soon)
  3. Fluent Interface with Builders (Coming soon)

What Is @Fieldmap in Retrofit?

You’re already familiar with Retrofit’s annotation to map parameter values into appropriate format. There are multiple annotations for different kinds of situations, like adding query or path parameters, request payload using a given object or create the body from fields with form-urlencoded requests.

Let’s shift focus to an example that makes things more approachable. Assuming that you have the option to update user data within your Android app, you want to call an API endpoint that takes an object of key-value-pairs.

We want to use a form-urlencoded request, because the API accepts a JSON object representing the fields that should be updated. You’re tempted to define the API endpoint on client-side using the following interface definition.

public interface UserService {  
    @FormUrlEncoded
    @PUT("user")
    Call<User> update(
            @Field("username") String username,
            @Field("name") String name,
            @Field("email") String email,
            @Field("homepage") String homepage,
            @Field("location") String location
    );
}

The PUT request requires values for multiple parameters like username, email, homepage, etc.

The downside: every time we want to send an update with the new user data, we have to provide a value for each parameter even though they didn’t change. It blows up your code and imagine that the number of parameters doubles or even triples evolutionary! The length of the method call text will explode Android Studio’s canvas.

Actually, there’s a more elegant solution already integrated with Retrofit: @FieldMap.

Form Encoded Requests Using FieldMap

In situations where you just need to send selected fields that should be updated for a given user, using Retrofit’s @FieldMap is a lot more elegant. You can add the desired key-value-pairs to a standard Java Map implementation and they will be translated as you go.

public interface UserService {  
    @FormUrlEncoded
    @PUT("user")
    Call<User> update(@FieldMap Map<String, String> fields);
}

Specifically, if you only want to update the username, there’s no need to add any other field than the username. Your request payload only consists of the single field!

You’ll find various applications to @FieldMap in your app. Of course, there’s a dark side attached to this approach: you don’t intuitively know which fields are allowed and what are their names. That requires some additional documentation within your code and if that’s the only thing to be aware of, go for it!

FieldMap Options

The @FieldMap annotation has an option field for encoding:

  • encoded: can be either true or false; default is false

The example below outlines the code example to activate the encoded option.

@FieldMap(encoded = true) Map<String, String> fields

The encoded option defines whether each provided key-value-pair is already url encoded. To specify the encoded option value, you need to pass it within the @FieldMap annotation.

Let’s look at an example. We want to update the username field to the new value marcus-poehls. With the default behavior (encoded=false), the key-value-pair results in username=marcus-poehls. Encoding enabled has the result username=marcus%2Dpoehls.

Outlook

Form-urlencoded requests are convenient to create the desired request payload without defining a class representing the data. You can send selected fields with their values and don’t blow up the request body with unnecessary or already known information.

Please let us know about any question or suggestions that come to your mind. Use the comments below or shout out @futurestud_io.

Additional Resources


Explore the Library

Find interesting tutorials and solutions for your problems.

Miscellaneous