[Dart 언어강좌] 021. Dart로 API 통신하기, REST API 연동 예제

Dart는 현대 웹과 모바일 애플리케이션 개발을 위한 강력한 언어로, Google이 개발했습니다. 이 블로그 글에서는 Dart를 사용하여 REST API와 통신하는 방법을 깊이 있게 살펴보겠습니다. API(Application Programming Interface)는 다양한 소프트웨어 애플리케이션 간의 상호작용을 가능하게 하며, REST(Representational State Transfer)는 API 설계를 위한 아키텍처 스타일입니다.

1. REST API란 무엇인가?

REST는 웹 서비스를 설계할 때 활용되는 아키텍처 스타일로, 다음과 같은 원칙을 따릅니다:

  • 클라이언트-서버 구조: 클라이언트(프론트엔드)와 서버(백엔드)가 서로 독립적으로 개발 및 배포될 수 있습니다.
  • 무상태성: 각 요청은 독립적이어야 하며, 서버는 클라이언트의 상태를 저장하지 않습니다.
  • 캐시 처리: 클라이언트 요청의 응답은 캐시 가능해야 할 수 있습니다.
  • 계층화 시스템: 클라이언트는 서버 응답을 통해 서비스 레이어를 설정할 수 있습니다.

2. Dart에서 HTTP 패키지 사용하기

Dart에서는 HTTP 통신을 위해 http 패키지를 사용합니다. 이 패키지를 통해 GET, POST, PUT, DELETE와 같은 다양한 HTTP 메소드를 쉽게 사용할 수 있습니다. 이 패키지를 사용하기 위해서는 먼저 프로젝트에 추가해야 합니다:

dependencies:
  http: ^0.13.3

이와 같이 pubspec.yaml 파일에 추가한 후, 프로젝트의 패키지를 업데이트합니다:

flutter pub get

3. GET 요청 예제

이제 REST API에 GET 요청을 보내어 데이터를 받아오는 간단한 예제를 살펴보겠습니다. 우선 JSONPlaceholder라는 가상의 REST API를 사용할 것입니다. 이 API는 테스트 및 프로토타이핑을 위해 제공되는 무료 API입니다.

import 'dart:convert';
import 'package:http/http.dart' as http;

Future fetchPosts() async {
  final response = await http.get(Uri.parse('https://jsonplaceholder.typicode.com/posts'));

  if (response.statusCode == 200) {
    List posts = jsonDecode(response.body);
    for (var post in posts) {
      print('Post ID: ${post['id']}, Title: ${post['title']}');
    }
  } else {
    throw Exception('Failed to load posts');
  }
}

void main() {
  fetchPosts();
}

위의 코드에서는 http.get 메소드를 사용하여 POST 리소스의 목록을 요청합니다. 요청이 성공하면 응답의 상태 코드가 200이 되며, 응답 본문을 jsonDecode 함수를 사용하여 JSON 형식으로 파싱합니다.

4. POST 요청 예제

다음으로 POST 요청을 사용하여 데이터를 서버에 전송하는 방법을 살펴보겠습니다. 이번에는 새 게시물을 추가하는 예제를 보겠습니다.

Future createPost(String title, String body) async {
  final response = await http.post(
    Uri.parse('https://jsonplaceholder.typicode.com/posts'),
    headers: {
      'Content-Type': 'application/json; charset=UTF-8',
    },
    body: jsonEncode({
      'title': title,
      'body': body,
      'userId': '1',
    }),
  );

  if (response.statusCode == 201) {
    print('Post created: ${response.body}');
  } else {
    throw Exception('Failed to create post');
  }
}

void main() {
  createPost('Dart Tutorial', 'This post explains how to use Dart for API communication.');
}

위의 예제에서는 http.post 메소드를 사용하여 JSON 형식으로 새 게시물 데이터를 전송합니다. JSONPlaceholder API는 POST 요청에 대해 새 게시물을 생성한 후 응답을 반환합니다.

5. PUT 요청 예제

PUT 요청을 사용하여 기존 데이터를 수정할 수도 있습니다. 아래의 예제에서는 특정 게시물을 수정하는 방법을 설명합니다.

Future updatePost(int postId, String title, String body) async {
  final response = await http.put(
    Uri.parse('https://jsonplaceholder.typicode.com/posts/$postId'),
    headers: {
      'Content-Type': 'application/json; charset=UTF-8',
    },
    body: jsonEncode({
      'title': title,
      'body': body,
      'userId': '1',
    }),
  );

  if (response.statusCode == 200) {
    print('Post updated: ${response.body}');
  } else {
    throw Exception('Failed to update post');
  }
}

void main() {
  updatePost(1, 'Updated Title', 'This body has been updated.');
}

위의 코드에서는 http.put 메소드를 사용하여 특정 ID를 가진 게시물을 수정합니다. URI에 게시물 ID를 포함하여 요청을 보냈습니다.

6. DELETE 요청 예제

마지막으로, DELETE 요청을 통해 서버에서 데이터를 삭제하는 방법을 보여드리겠습니다.

Future deletePost(int postId) async {
  final response = await http.delete(
    Uri.parse('https://jsonplaceholder.typicode.com/posts/$postId'),
  );

  if (response.statusCode == 200) {
    print('Post deleted successfully');
  } else {
    throw Exception('Failed to delete post');
  }
}

void main() {
  deletePost(1);
}

여기서는 http.delete 메소드를 사용하여 특정 게시물을 삭제하는 과정을 보여줍니다. 삭제 요청을 보내면 서버는 해당 게시물을 삭제하고 응답합니다.

7. 에러 처리

API 통신을 할 때는 반드시 에러 처리를 고려해야 합니다. 네트워크 오류나 서버 오류 등의 상황을 미리 예외 처리하여 사용자에게 유용한 피드백을 줄 수 있습니다. Dart의 try-catch 문을 사용하여 에러 처리를 구현해보겠습니다.

Future fetchPostsSafe() async {
  try {
    await fetchPosts();
  } catch (e) {
    print('An error occurred: $e');
  }
}

위 코드에서는 fetchPosts 함수에서 발생하는 모든 예외를 포착하고, 적절한 에러 메시지를 출력합니다. 이를 통해 사용자에게 안정적인 경험을 제공할 수 있습니다.

8. 결론

Dart를 사용하여 REST API와 통신하는 방법을 살펴보았습니다. GET, POST, PUT, DELETE 요청을 통해 간단한 CRUD(Create, Read, Update, Delete) 작업을 수행하는 방법을 배웠습니다. API와의 통신은 현대 애플리케이션에서 매우 중요한 요소이며, Dart의 http 패키지를 통해 간편하게 구현할 수 있습니다.

이 글을 통해 Dart로 API 통신을 구현하는 방법에 대한 기본적인 이해가 도움이 되었기를 바랍니다. 추가적인 학습을 통해 더 많은 기능들을 탐색하고, 여러분의 프로젝트에서 유용하게 활용해보세요!