안드로이드 앱이 서버와 통신하는 방법은 여러가지가 있지만, 일반적으로는 HTTP
를 이용해 통신을 합니다.
HTTP
는 Hypertext Transfer Protocol
의 약자로 인터넷 데이터를 주고 받기 위해 가장 일반적으로 사용되는 네트워크 프로토콜
입니다.
네트워크 프로토콜
이란 네트워크 상에서 컴퓨터나 장치들이 서로 통신할 수 있도록 규칙을 정해놓은 규약(protocol)입니다. 이 규약은 데이터를 전송하는 방식, 데이터의 형식, 데이터가 전송될 때의 처리 방법 등을 규정합니다.
네트워크 프로토콜
은 서로 다른 시스템에서도 상호 운용성(interoperability)을 보장합니다. 즉, 서로 다른 장치나 운영체제에서도 같은 프로토콜을 사용하면 통신이 가능해지며, 이를 통해 전 세계적으로 연결된 인터넷이 가능해졌습니다.
클라이언트는 HTTP
요청 메세지를 보내 서버에 데이터를 요청하고, 서버는 이 요청을 받아 HTTP
응답 메세지를 보내 클라이언트에게 데이터를 제공합니다.
HTTP
는 주로 TCP/IP
프로토콜을 기반으로 하며, 최근에는 보안성을 강화한 HTTPS
(HTTP Secure)가 많이 사용되고 있습니다. HTTPS
는 HTTP
메세지를 TLS
(Transport Layer Security)나 SSL
(Secure Socket Layer)을 통해 암호화하여 통신을 합니다. 하지만 HTTPS
는 암호화 과정에서 더 많은 비용이 발생하기 때문에 보안이 중요한 경우 HTTPS
를 아닌 경우에는 HTTP
를 사용할 수도 있습니다.
안드로이드의 경우 Pie(9) 버전부터는 보안상의 이유로 HTTPS
의 사용을 강제하고, 기본적으로 HTTP
통신을 금지하고 있습니다. 만약 HTTP
통신이 필요한 경우 Manifest에 android:usesCleartextTraffic="true"
를 추가해야 사용 가능합니다.
대표적인 HTTP 요청 메소드에는 GET
, POST
, PUT
, DELETE
가 있습니다.
GET
메소드는 주로 데이터를 읽거나 검색할 때 사용됩니다.
1) 캐싱이 가능하여 같은 데이터를 다시 조회할 때 속도가 빠릅니다.
2) 주소창(URL)에 파라미터가 노출되기 때문에 민감한 정보를 전송하면 안됩니다.
3) 길이의 제한이 존재합니다.
POST
메소드는 주로 새로운 데이터를 생성할 때 사용됩니다.
1) 캐싱이 불가능합니다.
2) 주소창(URL)에 파라미터가 노출되지 않습니다.
3) GET
보다 긴 길이의 요청이 가능합니다.
PUT
메소드는 데이터를 새로 생성하거나 업데이트하여 서버에 보내는데 사용됩니다.
PUT
vs POST
) PUT
메소드는 새로운 데이터를 매번 생성하는 것이 아니라 데이터를 지정하여 업데이트가 가능합니다. 반면 POST
메소드는 요청마다 새로운 데이터를 계속 생성합니다.
DELETE
메소드는 데이터를 삭제하는데 사용됩니다.
HTTP 상태 코드(Status Code)는 서버에서 클라이언트에게 전송된 HTTP 응답의 상태를 나타내며, 3자리의 숫자
형태입니다.
1. 1xx
: 클라이언트의 요청이 처리 중인 상태입니다.
2. 2xx
: 클라이언트의 요청이 성공적으로 처리 된 상태입니다.
3. 3xx
: 클라이언트가 요청한 리소스가 다른 곳에 있는 상태입니다.
4. 4xx
: 클라이언트 측에서 오류가 발생한 상태입니다.
5. 5xx
: 서버 측에서 오류가 발생한 상태입니다.
TCP/IP
는 두 개의 프로토콜인 TCP
(Transmission Control Protocol, 전송 제어 프로토콜)와 IP
(Internet Protocol, 인터넷 프로토콜)로 이루어져 있습니다. TCP
는 데이터의 안정적인 전송을 보장하기 위한 프로토콜이며, IP
는 인터넷에서 데이터를 전송하는 역할을 합니다.
TCP/IP
프로토콜을 이용하여 데이터를 전송할 때, 송신자는 데이터를 IP 패킷으로 만들어서 인터넷을 통해 수신자에게 전송합니다. 이 때, IP 패킷은 목적지 IP 주소와 출발지 IP 주소를 가지고 있으며, 인터넷을 통해 전송되기 때문에 여러 개의 라우터를 거쳐 전달됩니다.
TCP/IP
프로토콜은 1:1 통신 방식으로 전송 순서를 보장하고, 수신 여부를 확인한다는 점에서 신뢰성이 높지만 속도는 상대적으로 느리다는 단점이 있습니다. 이러한 점은 UDP
(User Datagram Protocol)라는 프로토콜과 비교할 수 있습니다.
UDP
프로토콜은 1:1, 1:N, N:N 통신이 모두 가능하며, 전송 순서는 보장되지 않고, 수신 여부도 확인하지 않아 상대적으로 빠릅니다. 하지만 신뢰성은 TCP/IP
에 비해 낮습니다.
RESTful API
는 HTTP
를 기반으로 하며, REST
의 아키텍쳐 스타일의 속성을 지켜 설계된 API입니다.
REST
는 Representational State Transfer의 약자로 인터넷 상에서 데이터를 전송하기 위한 아키텍쳐 스타일입니다.
RESTful API
을 통해 앱 간에 데이터를 교환할 수 있고, 플랫폼에 상관없이 다양한 플랫폼 사이의 호환성을 유지할 수 있습니다.
REST에서 가장 중요한 개념은 Resource(리소스)
, Verb(행위)
, Representations(표현)
입니다.
Resource(자원) : 데이터를 의미하며 URI
의 형태의 고유한 ID를 가집니다. URI
는 명시적으로 자원을 표현해야 합니다.
Verb(행위) : 자원에 대해 수행할 작업 CRUD
를 나타내며 HTTP 요청 메소드(GET, POST, PUT, DELETE)
를 사용합니다.
Representations(표현) : 자원을 어떻게 표시할 것인가를 의미합니다. 일반적으로는 JSON
, XML
형태로 리소스를 주고 받습니다.
CRUD | HTTP 요청 메소드 |
---|---|
Create | POST 메소드를 사용하여 새로운 자원을 생성합니다. |
Read | GET 메소드를 사용하여 자원을 조회합니다. |
Update | PUT 메소드를 사용하여 자원을 갱신합니다. |
Delete | DELETE 메소드를 사용하여 자원을 삭제합니다. |
REST에서 가장 중요한 규칙은 2가지입니다.
URI는 정보의 자원을 명시적으로 나타내야 합니다.
자원에 대한 행위는 HTTP 요청 메소드를 사용해야 합니다.
Restful한 아키텍쳐의 특징은 아래와 같습니다.
클라이언트-서버 아키텍처(Client - Server Architecture) : 클라이언트와 서버는 각각 독립적으로 서로에게 종속되지 않아야 합니다.
무상태성(Stateless) : 클라이언트와 서버 간에 통신에 상태 정보는 포함되지 않아야 합니다. 모든 요청과 응답에는 필요한 모든 정보가 포함되어 있어야 합니다.
캐시 처리 가능(Cacheable) : 클라이언트는 서버의 응답을 캐시할 수 있으며, 이를 통해 성능을 향상시킬 수 있습니다.
계층 구조(Layered System) : 클라이언트와 서버 간에 중간 계층을 둘 수 있으며, 인접하지 않은 계층의 구성요소 끼리는 상호작용할 수 없어야 합니다. 이를 통해 시스템을 확장하거나 보안성을 높일 수 있습니다.
인터페이스 일관성(Uniform Interface) : 통신과 관련된 인터페이스는 일관적이어야 합니다. 플랫폼이나, 특정 언어, 기술에 영향을 받지 않고 일관된 통신이 가능해야 합니다.
Code on Demand : 서버 측에서 클라이언트 측으로 코드를 전송하여 실행시키는 기능입니다. 다양한 자원과 메소드만으로는 구현이 어려운 복잡한 로직을 클라이언트에서 실행할 수 있게 해줍니다. 이 특징은 보안상의 문제와 서버 부하의 증가 등의 이슈가 있을 수 있으므로 선택적으로 사용해야 합니다.
단순함 : RESTful API는 HTTP 프로토콜을 기반으로 구현되므로, 구현이 간단합니다.
유연함 : RESTful API는 다양한 클라이언트와 서버에서 사용될 수 있도록 설계되어 있으며, 다양한 프로그래밍 언어와 프레임워크에서 지원됩니다.
확장성 : RESTful API는 자원 중심으로 구성되어 있으므로, 새로운 자원을 추가하거나 기존 자원을 수정하거나 삭제할 수 있습니다.
가시성 : RESTful API는 URI를 사용하여 자원을 표현하므로, 자원의 위치를 명확하게 알 수 있으며, 이를 통해 가시성을 높일 수 있습니다.
캐시 처리 가능 : RESTful API는 캐시 처리가 가능하여, 클라이언트에서 서버로 요청하는 횟수를 줄이고, 성능을 향상시킬 수 있습니다.
보안성 : RESTful API는 클라이언트와 서버 간에 상태 정보를 유지하지 않으므로, 인증과 권한 부여 등에 대한 보안 문제가 발생할 수 있습니다.
버전 관리 어려움 : RESTful API는 인터페이스가 일관성을 유지해야 하므로, 인터페이스를 변경하면 이전 버전과 호환성이 없어질 수 있습니다.
자원 설계 난이도 : RESTful API는 자원 중심으로 구성되어 있으므로, 자원의 구조를 잘못 설계하면 자원을 낭비할 수 있습니다.
서버 부하 : RESTful API는 클라이언트에서 서버로 요청하는 횟수가 많을 수 있으므로, 서버 부하가 높아질 수 있습니다.