서버와의 데이터 통신은 웹 애플리케이션에서 매우 중요한 역할을 한다. Dart에서는 HTTP 패키지를 활용하여 쉽게 서버와 통신할 수 있다. 이 챕터에서는 Dart의 HTTP 패키지를 사용하여 서버에 요청을 보내고, 데이터를 주고받는 방법을 설명한다. 다양한 HTTP 요청 방식과 서버 응답 처리 방법에 대해 다룬다.
HTTP 요청 방식
서버와의 통신을 위해 HTTP 요청 방식을 이해하는 것이 중요하다. HTTP 요청은 클라이언트가 서버에 데이터를 요청하거나 전달하는 방식이다. Dart에서 HTTP 요청을 수행할 때 사용할 수 있는 주요 방식은 다음과 같다:
- GET: 서버로부터 데이터를 요청하는 방식이다.
- POST: 서버에 데이터를 제출하는 방식이다.
- PUT: 서버의 기존 데이터를 업데이트하는 방식이다.
- DELETE: 서버에서 데이터를 삭제하는 방식이다.
GET 요청
GET
요청은 서버로부터 데이터를 요청하는 가장 기본적인 방식이다. 클라이언트가 서버에 요청을 보내면 서버는 해당 요청에 대한 데이터를 응답으로 돌려준다. Dart에서는 http.get
메소드를 사용하여 GET 요청을 보낼 수 있다.
import 'package:http/http.dart' as http;
void fetchData() async {
var response = await http.get(Uri.parse('https://example.com/data'));
if (response.statusCode == 200) {
print('Response data: ${response.body}');
} else {
print('Failed to load data');
}
}
위 코드에서는 http.get
메소드를 사용하여 https://example.com/data
주소로 GET 요청을 보내고, 서버가 성공적으로 응답한 경우 그 데이터를 출력한다.
POST 요청
POST
요청은 클라이언트가 서버로 데이터를 전송할 때 사용된다. 이를 통해 새로운 데이터를 서버에 저장하거나 처리할 수 있다. Dart에서 POST 요청을 보내려면 http.post
메소드를 사용한다.
import 'package:http/http.dart' as http;
void sendData() async {
var response = await http.post(
Uri.parse('https://example.com/data'),
body: {'key1': 'value1', 'key2': 'value2'},
);
if (response.statusCode == 200) {
print('Data sent successfully');
} else {
print('Failed to send data');
}
}
이 예제에서는 POST 요청을 통해 서버로 데이터를 전송하고, 성공적으로 전송된 경우 "Data sent successfully"라는 메시지를 출력한다.
비동기 처리
HTTP 요청은 네트워크 통신이기 때문에 응답 시간이 길어질 수 있다. 이를 처리하기 위해 Dart에서는 비동기 프로그래밍을 활용하여 HTTP 요청이 완료될 때까지 기다리는 동안 다른 작업을 수행할 수 있도록 한다. Dart에서 비동기 처리를 위해 async
, await
키워드를 사용한다.
async
는 비동기 함수임을 나타내며, await
는 해당 작업이 완료될 때까지 대기한다는 의미이다.
Future<void> fetchDataAsync() async {
var response = await http.get(Uri.parse('https://example.com/data'));
print(response.body);
}
위 코드에서 fetchDataAsync
함수는 async
키워드를 사용하여 비동기적으로 실행되며, await
키워드를 사용하여 HTTP 요청이 완료될 때까지 기다린다.
서버 응답 처리
서버가 클라이언트로 응답을 보내면, 해당 응답에는 상태 코드와 응답 본문이 포함된다. 상태 코드는 서버가 요청을 성공적으로 처리했는지 여부를 나타내며, 대표적인 상태 코드는 다음과 같다:
- 200: 성공 (OK)
- 404: 요청한 리소스를 찾을 수 없음 (Not Found)
- 500: 서버 오류 (Internal Server Error)
서버 응답 본문은 요청한 데이터를 포함하거나, 에러 메시지를 포함할 수 있다. Dart에서는 http.Response
객체를 사용하여 응답의 상태 코드와 본문을 처리할 수 있다.
void handleResponse(http.Response response) {
if (response.statusCode == 200) {
print('Success: ${response.body}');
} else {
print('Error: ${response.statusCode}');
}
}
이 코드는 서버의 응답 상태 코드를 확인하고, 성공적인 응답과 에러를 구분하여 처리하는 방법을 보여준다.
JSON 데이터 처리
서버와 클라이언트 간의 데이터 통신에서는 주로 JSON 형식을 사용하여 데이터를 주고받는다. Dart에서 JSON 데이터를 처리하기 위해 dart:convert
패키지를 사용할 수 있다. JSON 데이터를 Dart 객체로 변환하거나, Dart 객체를 JSON 형식으로 변환할 때 사용된다.
import 'dart:convert';
void parseJson(String jsonString) {
var data = jsonDecode(jsonString);
print('Parsed data: $data');
}
String jsonString = jsonEncode({'key': 'value'});
이 예제에서는 jsonDecode
를 사용하여 JSON 문자열을 Dart 객체로 변환하고, jsonEncode
를 사용하여 Dart 객체를 JSON 문자열로 변환하는 과정을 보여준다.
PUT 요청
PUT
요청은 서버의 기존 데이터를 수정하거나 업데이트할 때 사용된다. 서버에서 기존 리소스를 업데이트하거나 새 리소스를 생성할 때 유용하게 사용된다. Dart에서는 http.put
메소드를 사용하여 PUT 요청을 보낼 수 있다.
import 'package:http/http.dart' as http;
void updateData() async {
var response = await http.put(
Uri.parse('https://example.com/data/1'),
body: {'name': 'updated_name', 'value': 'updated_value'},
);
if (response.statusCode == 200) {
print('Data updated successfully');
} else {
print('Failed to update data');
}
}
위 코드에서는 PUT
요청을 통해 특정 리소스(/data/1
)의 데이터를 업데이트하고, 서버 응답 상태 코드가 200
일 경우 업데이트 성공 메시지를 출력한다.
DELETE 요청
DELETE
요청은 서버에서 리소스를 삭제할 때 사용된다. 클라이언트가 서버에 특정 데이터를 삭제하도록 요청하는 방식이다. Dart에서는 http.delete
메소드를 사용하여 DELETE 요청을 보낼 수 있다.
import 'package:http/http.dart' as http;
void deleteData() async {
var response = await http.delete(Uri.parse('https://example.com/data/1'));
if (response.statusCode == 200) {
print('Data deleted successfully');
} else {
print('Failed to delete data');
}
}
이 예제에서는 특정 리소스(/data/1
)를 서버에서 삭제하고, 성공적인 응답을 처리하는 방법을 보여준다.
헤더 설정
서버와의 통신에서 헤더(Header)
는 클라이언트가 서버에 요청할 때 함께 전송하는 추가적인 정보를 포함한다. 예를 들어, Content-Type
이나 인증 정보 등을 헤더에 포함하여 서버에 요청을 보낼 수 있다.
import 'package:http/http.dart' as http;
void sendDataWithHeaders() async {
var response = await http.post(
Uri.parse('https://example.com/data'),
headers: {'Content-Type': 'application/json'},
body: '{"key": "value"}',
);
if (response.statusCode == 200) {
print('Request sent with headers');
} else {
print('Failed to send request with headers');
}
}
이 코드에서는 Content-Type
을 application/json
으로 지정하여 JSON 데이터를 서버에 전송하고, 서버 응답을 처리하는 방법을 설명한다.
인증 처리
서버와 클라이언트 간의 보안 통신에서는 인증(Authorization)이 중요한 요소이다. Dart에서 서버와의 통신 시 인증 정보를 헤더에 포함하여 보낼 수 있다. 가장 일반적인 방식 중 하나는 Bearer
토큰을 사용하는 방식이다.
import 'package:http/http.dart' as http;
void sendAuthenticatedRequest() async {
var response = await http.get(
Uri.parse('https://example.com/protected'),
headers: {'Authorization': 'Bearer your_token_here'},
);
if (response.statusCode == 200) {
print('Authenticated request successful');
} else {
print('Failed to authenticate request');
}
}
이 예제에서는 Authorization
헤더에 Bearer
토큰을 포함하여 서버의 보호된 리소스에 접근하는 방법을 보여준다.
Stream을 통한 데이터 처리
Dart의 Stream
은 서버로부터 지속적으로 데이터를 받아야 할 때 유용하다. 예를 들어 실시간으로 데이터를 주고받는 WebSocket 통신이나 서버에서 데이터를 스트리밍 방식으로 받아야 할 때 사용된다.
Dart의 Stream
은 비동기 데이터 이벤트를 처리하는 데 유용한 도구이며, HTTP 패키지에서도 Stream
기반으로 서버와의 데이터를 주고받을 수 있다.
import 'package:http/http.dart' as http;
void streamData() async {
var request = http.Request('GET', Uri.parse('https://example.com/stream'));
var response = await request.send();
response.stream.transform(utf8.decoder).listen((value) {
print('Received chunk: $value');
});
}
이 코드는 Request
객체를 사용하여 서버에 스트리밍 요청을 보내고, 서버가 반환하는 데이터를 스트리밍 방식으로 받아서 처리하는 방법을 설명한다.
서버로 데이터 보내기: Form 데이터 전송
Dart에서는 서버에 데이터를 보낼 때 다양한 방식으로 데이터를 전송할 수 있다. 가장 기본적인 방법 중 하나는 Form
데이터를 사용하는 방식이다. Form
데이터는 일반적으로 키-값 쌍으로 이루어진 데이터를 서버에 전송하는 방식으로, 특히 HTML 폼에서 입력된 데이터를 전송할 때 많이 사용된다.
import 'package:http/http.dart' as http;
void sendFormData() async {
var response = await http.post(
Uri.parse('https://example.com/form'),
body: {
'username': 'exampleUser',
'password': 'examplePassword',
},
);
if (response.statusCode == 200) {
print('Form data sent successfully');
} else {
print('Failed to send form data');
}
}
위 코드에서는 Form
형식으로 데이터를 서버에 전송하고, 성공적으로 전송되었을 경우 statusCode
가 200
인지를 확인하는 방법을 보여준다.
서버로 파일 전송
서버와의 통신에서 파일을 전송할 때는 MultipartRequest
를 사용하여 파일을 업로드할 수 있다. Dart의 HTTP 패키지에서는 http.MultipartRequest
클래스를 사용하여 여러 파트로 이루어진 요청을 서버에 보낼 수 있다.
import 'package:http/http.dart' as http;
import 'dart:io';
void sendFile() async {
var request = http.MultipartRequest(
'POST',
Uri.parse('https://example.com/upload'),
);
request.files.add(await http.MultipartFile.fromPath('file', 'path/to/file'));
var response = await request.send();
if (response.statusCode == 200) {
print('File uploaded successfully');
} else {
print('Failed to upload file');
}
}
이 코드는 MultipartRequest
를 통해 서버로 파일을 전송하는 방법을 설명한다. http.MultipartFile.fromPath
메소드를 사용하여 파일 경로를 지정하고, 해당 파일을 서버로 업로드한다.
서버로 JSON 데이터 전송
Dart에서 서버와의 통신 시 가장 많이 사용하는 데이터 형식 중 하나는 JSON이다. JSON은 경량 데이터 교환 형식으로, Dart에서 서버로 JSON 데이터를 전송하려면 HTTP 요청의 Content-Type
을 application/json
으로 지정하고, 데이터를 JSON 형식으로 인코딩하여 전송할 수 있다.
import 'package:http/http.dart' as http;
import 'dart:convert';
void sendJsonData() async {
var response = await http.post(
Uri.parse('https://example.com/json'),
headers: {'Content-Type': 'application/json'},
body: jsonEncode({'name': 'example', 'age': 30}),
);
if (response.statusCode == 200) {
print('JSON data sent successfully');
} else {
print('Failed to send JSON data');
}
}
이 예제에서는 jsonEncode
함수를 사용하여 Dart 객체를 JSON 형식으로 변환하고, 이를 서버에 전송하는 방법을 보여준다. 서버에서 응답을 받을 때도 마찬가지로 JSON 데이터를 처리할 수 있다.
서버 응답에 따른 데이터 처리
서버로부터 받은 응답은 다양한 데이터 형식일 수 있다. Dart에서는 서버 응답 데이터를 처리할 때 주로 JSON 형식을 사용하며, 이를 Dart 객체로 변환한 후 원하는 방식으로 데이터를 사용할 수 있다.
import 'dart:convert';
void handleJsonResponse(String responseBody) {
var data = jsonDecode(responseBody);
print('Name: ${data['name']}');
print('Age: ${data['age']}');
}
서버에서 받은 JSON 응답을 처리할 때는 jsonDecode
함수를 사용하여 문자열을 Dart 객체로 변환하고, 객체의 각 필드를 접근하여 원하는 데이터를 사용할 수 있다.
네트워크 에러 처리
서버와의 데이터 통신에서 발생할 수 있는 다양한 에러를 처리하는 것이 중요하다. Dart에서는 HTTP 요청을 보낼 때 발생할 수 있는 네트워크 오류나 서버 오류를 처리하기 위해 try-catch
구문을 사용할 수 있다.
import 'package:http/http.dart' as http;
import 'dart:convert';
void fetchDataWithErrorHandling() async {
try {
var response = await http.get(Uri.parse('https://example.com/data'));
if (response.statusCode == 200) {
var data = jsonDecode(response.body);
print('Data received: $data');
} else {
print('Server error: ${response.statusCode}');
}
} catch (e) {
print('Failed to fetch data: $e');
}
}
이 코드는 네트워크 오류 및 서버 오류를 처리하는 방법을 보여준다. try-catch
구문을 사용하여 서버가 응답하지 않거나 잘못된 응답을 보낸 경우에 대한 오류 처리를 할 수 있다.