Retrofit — Send Data Form-Urlencoded

Multiple methods exist to send data to your server. You may already know how to send data within the request body or how to make use of multipart/form-data to upload files using Retrofit. If not and you’re interested, follow the lead :) There’s another type available to send data to an API or server with your request: form-urlencoded. This post shows you how to annotate your service interface and execute form encoded requests using Retrofit.

Retrofit Series Overview

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

Form Encoded Requests

Performing form-urlencoded requests using Retrofit is sort of straight forward. It’s just another Retrofit annotation, which will adjust the proper mime type of your request automatically to application/x-www-form-urlencoded. The following interface definitions for Retrofit 1 and 2 will show you how to annotate your service interface for form-encoded requests. We’ll describe the magic behind the curtain below the code snippets :)

Retrofit 2

public interface TaskService {  
    @FormUrlEncoded
    @POST("tasks")
    Call<Task> createTask(@Field("title") String title);
}

Retrofit 1.9

public interface TaskService {  
    @FormUrlEncoded
    @POST("/tasks")
    void createTask(@Field("title") String title, Callback<Task> cb);
}

We’re using the TaskInterface to illustrate the code. The important part is the @FormUrlEncoded annotation. Please be aware of the fact, that you can’t use this annotation for GET requests. Form encoded requests are intended to send data to the server!

Additionally, you need to use the @Field annotation for the parameters which you’re going to send with your request. Place your desired key inside the @Field("key") annotation to define the parameter name. Further, add the type of your value as the method parameter. If you don’t use String, Retrofit will create a string value using Java’s String.valueOf(yourObject) method.

Let’s have a look at an example to illustrate all the theory! Using the following service call

service.createTask("Research Retrofit form encoded requests");  

results in the following form encoded request body:

title=Research+Retrofit+form+encoded+requests  

Of course, you can have multiple parameters for your request. Just add further @Field annotations with the desired type.

Form Encoded Requests Using an Array of Values

The example above describes the usage of the @Field annotation only for a single value. If you don’t use string as the object type, Retrofit will do the job to parse a string value from the given object.

However, you can pass an array of values using the same key for your form encoded requests.

Retrofit 2

public interface TaskService {  
    @FormUrlEncoded
    @POST("tasks")
    Call<List<Task>> createTasks(@Field("title") List<String> titles);
}

Retrofit 1.9

public interface TaskService {  
    @FormUrlEncoded
    @POST("/tasks")
    void createTasks(@Field("title") List<String> titles, Callback<List<Task>> cb);
}

As you can see, the only difference to the previously described service interface is the list of titles as the parameter. Retrofit will map a given list titles to the respective key title.

Alright, time to touch another example to get an impression of how the final request will look like.

List<String> titles = new ArrayList<>();  
titles.add("Research Retrofit");  
titles.add("Retrofit Form Encoded")

service.createTasks(titles);  

results in the following form encoded request body:

title=Research+Retrofit&title=Retrofit+Form+Encoded  

Each item within the list of task titles will be mapped to a key-value-pair by Retrofit. The title key will be the same for every pair. The key-value-pairs are separated by an ampersand (&) and the values are separated from their keys by an equal symbol =.

Field Options

The @Field annotation has an option field for encoding:

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

The encoded option defines whether your provided key-value-pair is already url encoded. To specify the encoded option value, you need to pass it within the @Field annotation. The example below illustrates a code examples and sets the encoded option to true.

@Field(value = "title", encoded = true) String title

Form-Urlencoded vs. Query Parameter

When seeing the results for a form encoded request, you may ask yourself "What is the difference between form-urlencoded and query parameters?". In essence: the request type.

  • form-urlencoded: POST
  • query parameter: GET

Use form-urlencoded requests to send data to a server or API. The data is sent within the request body and not as an url parameter.

Query parameters are used when requesting data from an API or server using specific fields or filter.

Outlook

Using form encoded request is a convenient way sending data to an API or backend. There’s no data object required to map the information into JSON representation. We’ve guided you through the annotations required to execute a form encoded request and also showed you how to pass multiple values for the same key with the request url.

Besides that, you can specifically set the encoded option for your values. If you previously weren’t sure about the difference between query parameter and form encoded requests, you now know when to apply the appropriate one.

If you run into questions or problems, find us on Twitter @futurestud_io or in the comment section below.

Enjoy coding & make it rock!


Explore the Library

Find interesting tutorials and solutions for your problems.

Miscellaneous