본문 바로가기
스파르타/Flutter

[Flutter] API 살펴보기 - ( week 4 )

by bakcoding_sparta 2023. 4. 26.

API

 Application Programming Interface

다른 사람들이 내 컴퓨터에 있는 데이터에 접근할 수 있도록 만들어둔 기능을 API라고 부른다.

 

기상청 API 매뉴얼

 

API를 어떻게 사용할 수 있는지 설명이 나와있다. 

설명을 보면서 어떤 식으로 API 구조가 만들어 있는지 살펴볼 수 있다.

 

Public APIs

공공 API 모음

 

Network

API는 서로 다른 컴퓨터 간에 주고받는 통신이다.

이러한 통신을 네트워크라고 하며 예를 들어서 네이버 주소로 접속했을 때 웹 브라우저가 네이버에 있는 컴퓨터로 요청을 보내고 네이버에서 다시 내 컴퓨터로 응답을 해주는데 이때 요청하는 컴퓨터를 클라이언트, 응답하는 컴퓨터를 서버라고 한다.

 

 

프로토콜

컴퓨터 간에 통신을 하기 위해서는 정보에 규칙이 있어야 한다. 

이러한 규칙을 프로토콜이라고 하며 웹의 경우 컴퓨터 간의 HTTP라는 규칙을 따라 통신하게 된다.

 

HTTP

요청

URL(목적지) : 요청을 보내는 인터넷상에 연결된 다른 컴퓨터의 주소이다.

 

Method(원하는 액션) : 서버가 수행해야 할 동작을 영어로 표현한 것이다.(GET, POST)

HTTP 요청 메서드

 

Parameter(파라미터) : 요청을 보낼 때 추가로 보낼 수 있는 데이터이다.

 

응답 

Web Page : 웹 페이지로 응답을 보낸다.

Data : 데이터를 보내줄 때에도 정해진 형식이 있으며 일반적으로 JSON 형식을 많이 사용한다.

State code : HTTP 응답 결과를 반환하는 약속된 숫자이다. ( 200: 성공, 4xx: 잘못된 요청, 5xx: 서버 문제로 실패)

 

Google Books APIs

구글 책 검색 API의 사용법을 살펴본다.

 

Google Books APIs

 

예제 API를 호출해 본다.

GET https://www.googleapis.com/books/v1/volumes?q={search terms}

검색된 책들이 데이터(JSON) 형태로 들어오는 것을 볼 수 있다.

웹 브라우저는 암묵적으로 GET 방식으로 요청을 하고 있다.

 

Dart API Request

Dart 코드상에서 API를 호출할 수 있다.

 

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

void main() async {
  // Uri.https 는 아래와 같은 URL을 만들어줍니다.
  // https://www.googleapis.com/books/v1/volumes?q=고양이
  final url = Uri.https('www.googleapis.com', '/books/v1/volumes', {'q': '고양이'});

  // GET 방식(Method)로 요청을 보내겠다는 뜻입니다.
  // GET 외에도, POST, PUT, DELETE 등 다양한 방식으로 요청을 보낼 수 있습니다.
  final res = await http.get(url);

  if (res.statusCode == 200) {
    // 성공시 응답의 body 에 담긴 내용을 출력합니다.
    print(res.body);
  } else {
    // 실패시 응답의 상태 코드를 출력합니다.
    print(res.statusCode);
  }
}

Google API 샘플로 호출한 것과 동일한 결과를 Dart에서 API를 호출해서 가져올 수 있다.

코드에서 사용한 async와 await은 한쌍의 키워드로 비동기 방식으로 처리할 때 사용한다.

 

동기와 비동기

동기 : 하나의 일이 끝난 뒤 다음 일을 진행하는 방식으로 요청이 있으면 결과가 있을 때까지 대기한다.

비동기 : 하나의 일이 끝나기 전에 동시에 다른 일을 하는 방식으로 요청을 하고 결과를 기다리지 않고 다음 작업을 진행한다.

 

 

결과를 기다리는 시간이 없기 때문에 비동기 방식이 소요되는 시간이 더 짧다.

따라서 오래 걸리는 작업은 비동기 방식으로 처리하는 게 좋다. 지금까지 작성한 대부분의 코드는 결과가 오래 걸리는 작업들이 아니었기 때문에 동기 방식으로 작성되었다. 하지만  네트워크 요청, 데이터베이스 접근처럼 시간이 오래 걸리는 작업들은 기본적으로 비동기 방식으로 동작하도록 되어있다.

 

하지만 HTTP 요청을 보낸 뒤 응답받은 결과를 보여주는 코드를 작성해야 하는 경우 응답이 들어오기 전에 다음 코드가 진행되면서 에러가 발생하기 때문에 이러한 경우에는 동기 방식으로 동작하는 게 좋다.

 

따라서 요청을 보내기만 하면 되는 코드의 경우 비동기 방식으로 처리하고 요청에 대한 응답을 받아야 하는 경우 동기 방식으로 처리하는 것이 좋다.

 

async, await

void main() {
  print("1");

  // Future.delayed 는 기본적으로 "비동기" 로 동작하는 함수입니다.
  // 즉, 일단 넘어가고 나중에 실행됩니다.
  Future.delayed(Duration(seconds: 1), () {
    print("2");
  });

  print("3");
}

Future.delayed() 함수는 대표적인 비동기 방식으로 동작하는 코드로 1초 뒤에 실행하도록 만들 때 사용한다.

코드를 실행하면 결과는 1 -> 3 -> 2 순서대로 출력된다.

 

이걸 1 -> 2 -> 3 순서대로 출력하도록 만들려면 동기 방식으로 실행해야 한다.

// await 키워드를 쓰기 위해서는 함수에 async 키워드를 써야합니다.
// 이는 이 함수를 비동기 함수로 만들어줍니다.
void main() async {
  print("1");

  // await 키워드를 넣어 동작이 끝날때까지 기다립니다.
  await Future.delayed(Duration(seconds: 1), () {
    print("2");
  });

  print("3");
}

 

async라고 선언된 함수는 비동기 방식으로 실행되는 코드를 동기 방식으로 실행시킬 수 있으며 이때 await을 함께 사용해서 결과를 기다려야 하는 코드 앞에 붙여주면 된다.

 

Future

함수가 반환하는 타입의 형태이다.

async/await을 사용하는 함수는 반환값을 미래에 해당 타입을 반환한다는 의미로 Future <반환타입> 형태로 표시한다.

 

void main() async {
  print("1");
  String pizza = await getFood();
  print(pizza);
  print("2");
}

Future<String> getFood() async {
  await Future.delayed(Duration(seconds: 1), () {
    print("cooking...");
  });

  return "pizza";
}

Future로 한번 감싸는 것은 언젠가 내부에서 값을 반한 한다는 의미이다.

해당 함수를 호출하는 영역에서도 await을 함수 앞에 붙여주면 동기 방식으로 결과가 응답될 때까지 기다리기 때문에 Future를 벗겨낸 타입으로 반환 값을 받을 수 있다.

 

 

즉 비동기를 동기로 동작시키기 위해서는 await을 해당 코드 앞에 붙이면 되는데 코드가 속한 함수에 async를 넣어주면 동기 방식으로 실행이 가능하고 async가 선언된 함수의 반환값은 Future <return type> 형식으로 표현된다.

 

Future<String> getName() async {
	String name = await HTTP요청;
	return name;
}