Welcome to this lesson on sending data with POST requests. As you continue your exploration of interacting with RESTful APIs, you'll learn how to send data to a server using the POST
method. POST
requests are essential when you want to create new resources or submit data, such as filling out a web form or adding a new entry to a database. Unlike GET
requests, which you have already encountered, POST
requests do not solely retrieve information; they actually transmit data to an API.
Understanding these differences is crucial as you expand your skill set in HTTP methods. Let’s dive deeper into utilizing POST
requests to comprehend how they stand apart from GET
requests.
Before diving into POST
requests, let's briefly compare them to GET
requests:
-
GET Requests:
- Purpose: Retrieve data from a server.
- Data Location: Data is sent in the URL as path or query parameters.
- Success Status: Expect a
200
status code for successful data retrieval. - Security and Data Visibility: Data is appended to the URL, making it visible in browser history, server logs, and network tools, which is unsuitable for sensitive information.
-
POST Requests:
- Purpose: Send data to a server to create or update a resource, such as submitting a form, uploading a file, or adding a new item to a database.
- Data Location: Data is sent in the request body.
- Success Status: Expect a
201
status code for successful resource creation. - Security and Data Visibility: Data is sent in the request body, making it less exposed and more suitable for transmitting sensitive information.
These differences clarify when to use each method. POST
requests, in particular, require careful handling of the request body.
For POST
requests, the request body is crucial as it holds the data you want to send to the server. This data is usually structured in formats like JSON, XML, or form data, with JSON being a common choice due to its readability and compatibility.
Here's an example of a JSON request body:
JSON1{ 2 "title": "Learn Kotlin OkHttp library", 3 "description": "Complete a course on Kotlin API calls.", 4 "done": false 5}
This represents a new todo item, including a title, completion status, and description. Noticeably, we are not sending an id
, as this is typically managed by the server upon resource creation.
With a solid understanding of GET
vs. POST
and the role of the request body, you’re ready to explore how to utilize Kotlin's OkHttp
library to handle POST
operations.
Let's walk through an example of how to craft a POST
request to add a new todo item to our API using OkHttp
.
First, you will need to prepare the data you wish to send. Here, we'll create a new todo item with a specific title, completion status, and description. The data will be structured as a JSON string:
Kotlin1// New todo data in JSON format 2val newTodo = """ 3 { 4 "title": "Learn Kotlin OkHttp library", 5 "description": "Complete a course on Kotlin API calls.", 6 "done": false 7 } 8""".trimIndent() 9 10val client = OkHttpClient() 11val mediaType = "application/json; charset=utf-8".toMediaTypeOrNull() 12val requestBody = newTodo.toRequestBody(mediaType) 13 14// Build and execute the POST request 15val request = Request.Builder() 16 .url("$baseUrl/todos") 17 .post(requestBody) 18 .build() 19 20val response = client.newCall(request).execute()
In Kotlin, you use OkHttp
's features to build a Request
object with a JSON request body.
Interpreting the response from a POST
request is an integral part of the process. After sending the request, the server provides a response indicating whether the operation was successful. Here’s how to handle the responses:
Kotlin1if (response.isSuccessful) { 2 if (response.code == 201) { 3 println("New todo added successfully!") 4 println(response.body?.string() ?: "No response body") 5 } 6} else { 7 // Handle potential errors 8 println("Failed to add a new todo") 9 println("Status Code: ${response.code}") 10 println("Error Details: ${response.body?.string()}") 11}
The code assesses the server's response: a 201
status code confirms successful creation, allowing you to print and use the details of the new todo, typically included in the server's response. Otherwise, the code handles potential errors by outputting relevant error information.
A POST
request may fail if required fields are missing. For example, omitting a "title" might lead to an error response:
Kotlin1// New todo data with missing title 2val incompleteTodo = """ 3 { 4 "done": false, 5 "description": "Complete a course on Kotlin API calls." 6 } 7""".trimIndent() 8 9val requestBodyIncomplete = incompleteTodo.toRequestBody(mediaType) 10 11// Build and execute the POST request 12val requestIncomplete = Request.Builder() 13 .url("$baseUrl/todos") 14 .post(requestBodyIncomplete) 15 .build() 16 17val responseIncomplete = client.newCall(requestIncomplete).execute() 18 19if (responseIncomplete.isSuccessful) { 20 println("New todo added successfully!") 21 println(responseIncomplete.body?.string() ?: "No response body") 22} else { 23 // Handle potential errors 24 println("Failed to add a new todo") 25 println("Status Code: ${responseIncomplete.code}") 26 println("Error Details: ${responseIncomplete.body?.string()}") 27}
Running this code could produce an error similar to:
Plain text1Failed to add a new todo 2Status code: 400 3Error Details: {"error": "Invalid request. 'title' is required."}
The 400
status code signifies a bad request, often caused by missing or incorrect data in the request body.
In this lesson, you have learned how to send data to an API using POST
requests. We explored how POST
differs from GET
in terms of its function of creating new resources. With Kotlin and the OkHttp
library, you are equipped to craft and send POST
requests, handle responses, and manage errors to ensure robust API interactions.
As you proceed to the practice exercises, you will have the opportunity to apply everything you have learned here. Practice creating POST
requests to reinforce your understanding and discover firsthand the nuances of sending data to an API. Keep up the excellent work, as each lesson brings you closer to mastering API interactions with Kotlin!
