[MOBILE-005][기초] 모바일 API 오류를 나눠서 보여 주기
페이지 정보

본문
[이번 수업]
모바일 API 호출의 성공, HTTP 오류, 네트워크 오류를 나눠 화면에 표시합니다.
[선수지식]
HTTP 요청·응답과 상태 코드, MOBILE-004의 화면 상태를 알면 좋습니다.
[학습목표]
1. API 호출 단계를 순서대로 설명한다.
2. 네트워크·HTTP·데이터 오류를 구분한다.
3. 재시도와 화면 상태를 안전하게 설계한다.
[핵심개념]
API 통신은 요청→전송→상태 확인→본문 해석→화면 갱신 순서입니다. 네트워크 작업은 결과를 기다리는 동안 화면을 막지 않는 비동기로 실행합니다. 화면을 `loading`, `success`, `empty`, `error` 상태로 나누면 중복 로딩과 오래된 오류가 섞이는 일을 줄일 수 있습니다.
오프라인·DNS 실패·시간 초과는 응답을 못 받은 네트워크 오류입니다. 401·404·429·503처럼 응답은 왔지만 성공 범위가 아니면 HTTP 오류입니다. 2xx여도 JSON이나 필수 필드가 틀리면 데이터 오류입니다. 로그에는 비밀값 없이 오류 종류와 요청 식별자만 남깁니다.
재시도는 횟수와 간격을 제한합니다. 멱등성은 같은 요청을 반복해도 서버 효과가 한 번과 같은 성질입니다. 조회나 서버가 멱등성을 보장한 작업만 자동 재시도합니다. 화면이 사라지면 불필요한 요청을 취소하고 늦은 응답이 새 상태를 덮지 않게 합니다.
[따라하기]
내 컴퓨터의 임시 API로 200과 503을 구분합니다. mobile_api.py로 저장하세요.
```python
import json
from http.server import BaseHTTPRequestHandler, HTTPServer
from threading import Thread
from urllib.error import HTTPError, URLError
from urllib.request import urlopen
class Handler(BaseHTTPRequestHandler):
def do_GET(self):
ok = self.path == "/items"
body = json.dumps(
{"items": ["note", "photo"]} if ok else {"error": "busy"}
).encode()
self.send_response(200 if ok else 503)
self.end_headers()
self.wfile.write(body)
def log_message(self, *args):
pass
server = HTTPServer(("127.0.0.1", 0), Handler)
Thread(target=server.serve_forever, daemon=True).start()
base = f"http://127.0.0.1:{server.server_port}"
def fetch(path):
try:
with urlopen(base + path, timeout=2) as response:
data = json.load(response)
return f"success {len(data['items'])}"
except HTTPError as error:
return f"http_error {error.code}"
except URLError:
return "network_error"
except (json.JSONDecodeError, KeyError, TypeError):
return "data_error"
print(fetch("/items"))
print(fetch("/busy"))
server.shutdown()
server.server_close()
```
macOS·Linux는 `python3 mobile_api.py`, Windows는 `py mobile_api.py`로 실행합니다. 예상 결과입니다.
```text
success 2
http_error 503
```
127.0.0.1은 자기 컴퓨터만 가리킵니다. 실제 앱에서도 전송 실패, 상태 코드, JSON 해석을 차례로 분리하세요.
[흔한 실수]
- 모든 실패를 “인터넷 오류”로 표시해 로그인이나 서버 문제를 숨깁니다.
- 시간 제한 없이 기다리거나 같은 요청을 겹쳐 보냅니다.
- 2xx만 확인하고 본문 형식과 필수 필드를 검증하지 않습니다.
- 늦게 도착한 응답이 새 화면 상태를 덮습니다.
[보안 주의]
운영 통신은 HTTPS와 기본 인증서 검증을 사용하고 검증을 끄지 마세요. 토큰·개인정보·전체 응답을 기록하거나 앱에 서버 비밀키를 넣지 않습니다. 응답 크기와 시간 제한을 두고 실습은 본인 소유의 로컬·격리 환경에서만 실행하세요.
[직접 해볼 과제]
1. `/missing`에 404를 돌려주고 사용자 안내 문구를 정하세요.
2. JSON에서 items를 제거해 `data_error`가 되는지 확인하세요.
[확인문제]
1. 네트워크 오류와 HTTP 오류는 무엇이 다른가요?
2. 2xx 응답에서도 데이터 오류가 발생할 수 있는 이유는 무엇인가요?
3. 모든 POST 요청을 자동 재시도하면 위험한 이유는 무엇인가요?
[다음 학습]
MOBILE-006에서는 로컬 저장·캐시·오프라인 상태를 연결하는 방법을 배웁니다.
[공식 참고 자료]
- 모바일 네트워크 작업 안내: https://developer.android.com/develop/connectivity/network-ops
- URLSession 공식 문서: https://developer.apple.com/documentation/foundation/urlsession
- RFC 9110 HTTP Semantics: https://www.rfc-editor.org/rfc/rfc9110.html
- MASVS 네트워크 보안 기준: https://mas.owasp.org/checklists/MASVS-NETWORK/
모바일 API 호출의 성공, HTTP 오류, 네트워크 오류를 나눠 화면에 표시합니다.
[선수지식]
HTTP 요청·응답과 상태 코드, MOBILE-004의 화면 상태를 알면 좋습니다.
[학습목표]
1. API 호출 단계를 순서대로 설명한다.
2. 네트워크·HTTP·데이터 오류를 구분한다.
3. 재시도와 화면 상태를 안전하게 설계한다.
[핵심개념]
API 통신은 요청→전송→상태 확인→본문 해석→화면 갱신 순서입니다. 네트워크 작업은 결과를 기다리는 동안 화면을 막지 않는 비동기로 실행합니다. 화면을 `loading`, `success`, `empty`, `error` 상태로 나누면 중복 로딩과 오래된 오류가 섞이는 일을 줄일 수 있습니다.
오프라인·DNS 실패·시간 초과는 응답을 못 받은 네트워크 오류입니다. 401·404·429·503처럼 응답은 왔지만 성공 범위가 아니면 HTTP 오류입니다. 2xx여도 JSON이나 필수 필드가 틀리면 데이터 오류입니다. 로그에는 비밀값 없이 오류 종류와 요청 식별자만 남깁니다.
재시도는 횟수와 간격을 제한합니다. 멱등성은 같은 요청을 반복해도 서버 효과가 한 번과 같은 성질입니다. 조회나 서버가 멱등성을 보장한 작업만 자동 재시도합니다. 화면이 사라지면 불필요한 요청을 취소하고 늦은 응답이 새 상태를 덮지 않게 합니다.
[따라하기]
내 컴퓨터의 임시 API로 200과 503을 구분합니다. mobile_api.py로 저장하세요.
```python
import json
from http.server import BaseHTTPRequestHandler, HTTPServer
from threading import Thread
from urllib.error import HTTPError, URLError
from urllib.request import urlopen
class Handler(BaseHTTPRequestHandler):
def do_GET(self):
ok = self.path == "/items"
body = json.dumps(
{"items": ["note", "photo"]} if ok else {"error": "busy"}
).encode()
self.send_response(200 if ok else 503)
self.end_headers()
self.wfile.write(body)
def log_message(self, *args):
pass
server = HTTPServer(("127.0.0.1", 0), Handler)
Thread(target=server.serve_forever, daemon=True).start()
base = f"http://127.0.0.1:{server.server_port}"
def fetch(path):
try:
with urlopen(base + path, timeout=2) as response:
data = json.load(response)
return f"success {len(data['items'])}"
except HTTPError as error:
return f"http_error {error.code}"
except URLError:
return "network_error"
except (json.JSONDecodeError, KeyError, TypeError):
return "data_error"
print(fetch("/items"))
print(fetch("/busy"))
server.shutdown()
server.server_close()
```
macOS·Linux는 `python3 mobile_api.py`, Windows는 `py mobile_api.py`로 실행합니다. 예상 결과입니다.
```text
success 2
http_error 503
```
127.0.0.1은 자기 컴퓨터만 가리킵니다. 실제 앱에서도 전송 실패, 상태 코드, JSON 해석을 차례로 분리하세요.
[흔한 실수]
- 모든 실패를 “인터넷 오류”로 표시해 로그인이나 서버 문제를 숨깁니다.
- 시간 제한 없이 기다리거나 같은 요청을 겹쳐 보냅니다.
- 2xx만 확인하고 본문 형식과 필수 필드를 검증하지 않습니다.
- 늦게 도착한 응답이 새 화면 상태를 덮습니다.
[보안 주의]
운영 통신은 HTTPS와 기본 인증서 검증을 사용하고 검증을 끄지 마세요. 토큰·개인정보·전체 응답을 기록하거나 앱에 서버 비밀키를 넣지 않습니다. 응답 크기와 시간 제한을 두고 실습은 본인 소유의 로컬·격리 환경에서만 실행하세요.
[직접 해볼 과제]
1. `/missing`에 404를 돌려주고 사용자 안내 문구를 정하세요.
2. JSON에서 items를 제거해 `data_error`가 되는지 확인하세요.
[확인문제]
1. 네트워크 오류와 HTTP 오류는 무엇이 다른가요?
2. 2xx 응답에서도 데이터 오류가 발생할 수 있는 이유는 무엇인가요?
3. 모든 POST 요청을 자동 재시도하면 위험한 이유는 무엇인가요?
[다음 학습]
MOBILE-006에서는 로컬 저장·캐시·오프라인 상태를 연결하는 방법을 배웁니다.
[공식 참고 자료]
- 모바일 네트워크 작업 안내: https://developer.android.com/develop/connectivity/network-ops
- URLSession 공식 문서: https://developer.apple.com/documentation/foundation/urlsession
- RFC 9110 HTTP Semantics: https://www.rfc-editor.org/rfc/rfc9110.html
- MASVS 네트워크 보안 기준: https://mas.owasp.org/checklists/MASVS-NETWORK/
- 이전글[IOT-005][기초] UART·I2C·SPI 통신 차이 한눈에 보기 26.09.01
- 다음글[SWE-005][기초] API 약속을 지키며 기능을 바꾸는 법 26.09.01
댓글목록
등록된 댓글이 없습니다.
