본문 바로가기

네트워킹 - HTTP를 통한 데이터 가져오기 및 보내기

에온르 2024. 6. 6.
반응형

이번 강의에서는 Flutter에서 네트워킹을 처리하는 방법을 배워보겠습니다. HTTP를 통해 데이터를 가져오고 보내는 것은 대부분의 모바일 애플리케이션에서 중요한 기능입니다. 이 강의에서는 http 패키지를 사용하여 REST API와 상호작용하는 방법을 다룹니다.

source: medium @mahamudul hassan

http 패키지 설치

먼저, http 패키지를 설치해야 합니다. pubspec.yaml 파일에 http 패키지를 추가합니다.

dependencies:
  flutter:
    sdk: flutter
  http: ^0.13.3

터미널에서 flutter pub get 명령을 실행하여 패키지를 설치합니다.


GET 요청으로 데이터 가져오기

GET 요청을 사용하여 서버에서 데이터를 가져오는 방법을 살펴보겠습니다.

JSONPlaceholder API 사용하기

JSONPlaceholder는 테스트용으로 사용할 수 있는 무료 API입니다. 여기서 제공하는 API를 사용하여 데이터를 가져오겠습니다.

데이터 모델 정의하기

먼저, 데이터를 저장할 모델 클래스를 정의합니다.

class Post {
  final int userId;
  final int id;
  final String title;
  final String body;

  Post({
    required this.userId,
    required this.id,
    required this.title,
    required this.body,
  });

  factory Post.fromJson(Map<String, dynamic> json) {
    return Post(
      userId: json['userId'],
      id: json['id'],
      title: json['title'],
      body: json['body'],
    );
  }
}

GET 요청 보내기

이제 http 패키지를 사용하여 GET 요청을 보내고 데이터를 가져옵니다.

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

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('HTTP GET 예제'),
        ),
        body: PostsScreen(),
      ),
    );
  }
}

class PostsScreen extends StatefulWidget {
  @override
  _PostsScreenState createState() => _PostsScreenState();
}

class _PostsScreenState extends State<PostsScreen> {
  late Future<List<Post>> futurePosts;

  @override
  void initState() {
    super.initState();
    futurePosts = fetchPosts();
  }

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

    if (response.statusCode == 200) {
      List jsonResponse = json.decode(response.body);
      return jsonResponse.map((post) => Post.fromJson(post)).toList();
    } else {
      throw Exception('Failed to load posts');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Center(
      child: FutureBuilder<List<Post>>(
        future: futurePosts,
        builder: (context, snapshot) {
          if (snapshot.connectionState == ConnectionState.waiting) {
            return CircularProgressIndicator();
          } else if (snapshot.hasError) {
            return Text('Error: ${snapshot.error}');
          } else {
            return ListView.builder(
              itemCount: snapshot.data!.length,
              itemBuilder: (context, index) {
                return ListTile(
                  title: Text(snapshot.data![index].title),
                  subtitle: Text(snapshot.data![index].body),
                );
              },
            );
          }
        },
      ),
    );
  }
}

POST 요청으로 데이터 보내기

POST 요청을 사용하여 서버에 데이터를 보내는 방법을 살펴보겠습니다.

데이터 보내기

이번에는 새로운 게시물을 생성하기 위해 POST 요청을 보냅니다.

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

  if (response.statusCode == 201) {
    return Post.fromJson(json.decode(response.body));
  } else {
    throw Exception('Failed to create post');
  }
}

POST 요청 예제

createPost 함수를 사용하여 새로운 게시물을 생성합니다.

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

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('HTTP POST 예제'),
        ),
        body: CreatePostScreen(),
      ),
    );
  }
}

class CreatePostScreen extends StatefulWidget {
  @override
  _CreatePostScreenState createState() => _CreatePostScreenState();
}

class _CreatePostScreenState extends State<CreatePostScreen> {
  final TextEditingController _titleController = TextEditingController();
  final TextEditingController _bodyController = TextEditingController();
  late Future<Post> _futurePost;

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: EdgeInsets.all(16.0),
      child: Column(
        children: <Widget>[
          TextField(
            controller: _titleController,
            decoration: InputDecoration(labelText: '제목'),
          ),
          TextField(
            controller: _bodyController,
            decoration: InputDecoration(labelText: '본문'),
          ),
          ElevatedButton(
            onPressed: () {
              setState(() {
                _futurePost = createPost(Post(
                  userId: 1,
                  id: 0,
                  title: _titleController.text,
                  body: _bodyController.text,
                ));
              });
            },
            child: Text('게시물 생성'),
          ),
          FutureBuilder<Post>(
            future: _futurePost,
            builder: (context, snapshot) {
              if (snapshot.connectionState == ConnectionState.done) {
                if (snapshot.hasData) {
                  return Text('게시물 생성됨: ${snapshot.data!.title}');
                } else if (snapshot.hasError) {
                  return Text('Error: ${snapshot.error}');
                }
              }
              return CircularProgressIndicator();
            },
          ),
        ],
      ),
    );
  }
}

FAQ

Q: HTTP 요청에서 타임아웃을 설정할 수 있나요?

A: 네, http.Client를 사용하여 타임아웃을 설정할 수 있습니다. 예를 들어, http.Client().get(Uri.parse('url')).timeout(Duration(seconds: 10));와 같이 설정할 수 있습니다.

Q: JSON 데이터를 파싱하는 다른 방법이 있나요?

A: 네, json_serializable 패키지를 사용하면 코드 생성으로 JSON 파싱을 자동화할 수 있습니다. 이 방법은 더 간결하고 유지보수가 쉬운 코드를 작성하는 데 유용합니다.

Q: 데이터 요청 시 에러를 어떻게 처리하나요?

A: try-catch 문을 사용하여 HTTP 요청에서 발생하는 에러를 처리할 수 있습니다. 또한, FutureBuilder를 사용하여 비동기 작업의 상태에 따라 UI를 업데이트할 수 있습니다.


결론

이번 강의를 통해 Flutter에서 HTTP를 통해 데이터를 가져오고 보내는 방법을 배웠습니다. http 패키지를 사용하여 GET 및 POST 요청을 보내고, JSON 데이터를 파싱하는 방법을 익혔습니다. 실습을 통해 실제 애플리케이션에 네트워킹 기능을 구현해 보며, REST API와 상호작용하는 방법을 이해할 수 있었습니다. 다음 강의에서는 Firebase와 같은 백엔드 서비스를 사용하여 데이터를 저장하고 관리하는 방법을 알아보겠습니다. Flutter로 다양한 네트워킹 기능을 구현해 보세요!

반응형

댓글