
15일차 과제 링크 👉 15일차 과제
→ 서버가 수행해야 할 동작을 지정하여 요청을 보내는 방법
| 메소드 | 설명 | 
|---|---|
| GET | 리소스 조회, 주로 데이터를 받을 때 사용 | 
| POST | 요청 데이터 처리, 주로 데이터 생성할 때 사용 | 
| PUT | 리소스를 대체 (덮어쓰기), 해당 리소스가 없으면 생성 | 
| PATCH | 리소스 부분 변경 (PUT이 전체 변경, PATCH는 일부 변경) | 
| DELETE | 리소스 삭제 | 
http 패키지 설치
http: ^0.13.5 등록HTTP 사용할 대상의 URL 정의
Method 선택 (GET, POST)
요청 보내기
요청 응답받기
출력
var url = 'https://sniperfactory.com/sfac/http_test';
var response = await http.get(Uri.parse(url)); // string 형태의 url을 Uri로 바꿈
print(response.statusCode);  // 200 : 요청 성공
print(response.body);        // {"result":"스나이퍼팩토리 비밀 URL에 접근하시다니."}
[URI와 URL의 차이]
URI
- "Uniform Resource Identifier"의 약자로, 인터넷에서 식별 가능한 리소스를 나타내는 일반적인 용어
 - 식별자와 리소스의 위치를 모두 나타낼 수 있음
 URL
- "Uniform Resource Locator"의 약자로, 인터넷에서 리소스의 위치를 나타내는 것
 - 일반적으로 웹 브라우저에서 입력하는 것과 같이, 프로토콜, 호스트명, 리소스 경로 등을 포함하는 문자열
 - 일반적으로 인터넷에서 식별 가능한 리소스를 나타내는 데 사용됨
 차이
- URI는 리소스의 위치뿐만 아니라 식별자도 포함할 수 있지만, URL은 리소스의 위치만 포함한다.
 - 예를 들어, URI는 ISBN 번호와 같은 고유한 식별자를 사용하여 책을 나타낼 수 있지만, URL은 해당 책이 있는 위치를 식별함
 
void main() async {
	var url = 'https://sniperfactory.com/sfac/http_only_get';
	
	var getResponse = await http.get(Uri.parse(url));
	print(getResponse.body);      // {"result":"정답입니다! GET 요청만 받는 경우도 정말정말 많습니다."}
	
	var postResponse = await http.post(Uri.parse(url));
	print(postResponse.body);  // {"error":"GET 요청만 받습니다."}
}void main() async {
  var url = 'https://sniperfactory.com/sfac/http_only_post';
  
  var postResponse = await http.post(Uri.parse(url));
  print(postResponse.body);      // {"result":"정답입니다! POST 요청만 받는 경우도 정말정말 많습니다."}
  
  var getResponse = await http.get(Uri.parse(url));
  print(getResponse.body);  // {"error":"POST 요청만 받습니다."}
}var dio = Dio();
dio.options.baseUrl = url;    // baseUrl: 가장 기본이 되는 RouteURL (도메인 최상위 URL)var dio = Dio();
var getRes = await dio.get('https://sniperfactory.com/sfac/http_only_get');
// var postRes = await dio.post('https://sniperfactory.com/sfac/http_only_get');
print(getRes);   // {"result":"정답입니다! POST 요청만 받는 경우도 정말정말 많습니다."}
// print(postRes);  // 400: Bad Requestvar dio = Dio();
var postRes = await dio.post('https://sniperfactory.com/sfac/http_only_post');
// var getRes = await dio.get('https://sniperfactory.com/sfac/http_only_post');
print(postRes); // {"result":"정답입니다! POST 요청만 받는 경우도 정말정말 많습니다."}
// print(getRes);  // 400: Bad Requestvar dio = Dio();
var res = await dio.get(
  'https://sniperfactory.com/sfac/http_only_chrome_browser',
  options: Options(
    headers: {
      'user-agent': 'Chrome'
      // 'user-agent': 'Safari'  // 400: Bad Request
    }
  )
);
print(res);   // {"result":"정답입니다! 이런 꿀잼 과제라니"}var dio = Dio();
var res = await dio.get(
  'https://sniperfactory.com/sfac/http_only_jwt_included',
  options: Options(
    headers: {
      // 인증키를 첨부할 수 있는 key 값
      'authorization': 'asdfasdf'
    }
  )
);
print(res);   // {"result":"정답입니다! 이런 꿀잼 과제라니"}import 'package:dio/dio.dart';
import 'package:http/http.dart' as http;
var dio = Dio();
var url = 'https://sniperfactory.com/sfac/http_json_data';
void main() {
  getDataUsingDio();
  getDataUsingHttp();
}
void getDataUsingHttp() async {
  var res = await http.get(Uri.parse(url));
  print('Http : $res');   // Instance of 'Future<Response>'
  print('Http res.body : ${res.body}');   // {"item":{"name":"스나이퍼팩토리 플러터 과정","description":"스나이퍼팩토리의 플러터 과정입니다! 지금 바로 신청해볼까요?","image":"https://picsum.photos/200/200","price":4000000}}
  print('Http res.body.runtimeType : ${res.body.runtimeType}');   // String
}
void getDataUsingDio() async {
  var res = await dio.get(url);
  print('Dio : $res');    // {"item":{"name":"스나이퍼팩토리 플러터 과정","description":"스나이퍼팩토리의 플러터 과정입니다! 지금 바로 신청해볼까요?","image":"https://picsum.photos/200/200","price":4000000}}
  print('Dio res.data : ${res.data}');    // {item: {name: 스나이퍼팩토리 플러터 과정, description: 스나이퍼팩토리의 플러터 과정입니다! 지금 바로 신청해볼까요?, image: https://picsum.photos/200/200, price: 4000000}}
  print('Dio res.data.runtimeType : ${res.data.runtimeType}');  // _InternalLinkedHashMap<String, dynamic>
	print('Dio res.data item : ${res.data['item']['name']}');
}[추가 비교]
HTTP
- GET, POST, PUT, DELETE 등 HTTP 메서드를 지원
 - 헤더 및 쿼리 매개변수를 설정할 수 있음
 - 인증 정보를 설정할 수 있음
 - 쿠키를 사용할 수 있음
 - 인터셉터를 사용하여 요청과 응답을 수정할 수 있음
 - 타임아웃 및 소켓 연결 설정을 지원
 - 플러터 앱과 통합된 예외 처리를 제공
 Dio
- FormData 및 멀티파트 요청을 지원
 - JSON 직렬화 및 역직렬화를 지원
 - Interceptor를 사용하여 HTTP 요청과 응답을 수정하고 로깅할 수 있음
 - 쿠키 지원
 - 자동 취소 기능 제공
 - 다운로드 및 업로드 기능을 제공
 - 자체 캐시 시스템 지원
 
- http 패키지는 간단한 HTTP 요청을 처리하기에 적합
 - Dio 패키지는 좀 더 복잡한 HTTP 요청 및 응답 처리를 위해 사용됨
 

작업을 순차적으로 실행하며, 한 작업이 완료될 때까지 다음 작업을 수행할 수 없음
[동기의 장점과 단점]
장점
- 코드가 간단하며, 순차적으로 실행됨
 - 에러가 발생했을 때 디버깅하기 쉽다
 - 결과가 도착할 때까지 대기하므로 동기적인 방식은 동시성 제어 문제를 해결할 수 있다
 단점
- 대기 시간이 발생하면 블로킹(blocking)이 발생하여 시스템 전체의 처리 속도가 느려짐
 - 대규모 사용자가 있는 시스템에서는 처리 속도가 매우 느려질 수 있음
 - 서버 측의 자원을 많이 차지할 수 있다
 
한 작업이 끝날 때까지 기다리지 않고 다른 작업을 수행할 수 있는 방식
[비동기의 장점과 단점]
장점
- 비동기적 방식이 대부분의 경우 더 빠름
 - 작업이 완료되는 동안 대기할 필요가 없으므로 다른 작업을 수행할 수 있음
 - 다수의 작업이 동시에 수행될 수 있다
 단점
- 비동기적인 방식은 설계가 복잡함
 - 에러 처리가 어려울 수 있음
 - 결과가 순서대로 도착하지 않을 수 있으므로 일부 알고리즘에서는 사용할 수 없다
 
[예시]
I/O 작업을 수행할 때 파일을 읽거나 네트워크를 통해 데이터를 받아오는 등의 작업은 시간이 오래 걸리기 때문에 동기적으로 수행하면 애플리케이션이 블로킹되어 다른 작업을 수행할 수 없음.
비동기적으로 수행하면 I/O 작업이 수행되는 동안 다른 작업을 수행할 수 있으므로 애플리케이션의 성능을 향상시킬 수 있다
asyncawaitvoid main() async {
  print('로그인을 시도합니다.');
  await Future.delayed(Duration(seconds: 3));
  print('로그인에 성공했습니다');
  print('반갑소');
}로그인을 시도합니다.
(3초 뒤)
로그인에 성공했습니다
반갑소thenvoid main() async {
	print('로그인을 시도합니다.');
	Future.delayed(Duration(seconds: 3)).then((res) {
	  print(res);
	  print('로그인에 성공했습니다');
	});
	print('반갑소');
}로그인을 시도합니다.
반갑소
(3초 뒤)
null
로그인에 성공했습니다var message = '';Text(message);Future<String> getData() async {
	var dio = Dio();
	var res = await dio.get('https://sniperfactory.com/sfac/http_test');
	return res.data['result'];
}void handleOnPressed() async {
	message = await getData();
}TextButton(
	onPressed: () {
		handleOnPressed();
	}
	child: Text('데이터 가져오기'),
)
차가운 챗선생......
