HTTP 는 HyperText Transfer Protocol 의 약자로 HyperText 문서를 주고 받기 위해 만들어졌고, 최근에는 HTML뿐 아니라 모든 웹 관련 API 통신에 이용하고 있는 통신 프로토콜입니다. HTTP 프로토콜은 비연결성(Connectionless)과 무상태성(Stateless)의 특징을 가지는 통신 프로토콜입니다.
비연결성(Connectionless): 처음 연결을 맺은 후 요청(Request)과 한번의 응답(Response)이후 연결이 종료됩니다. 매 요청마다 다시 연결을 맺습니다.
매번 연결을 맺어 느려지는 것을 보완하기 위해 KeepAlive 와 같은 속성을 활용할 수 있습니다.
무상태성(Stateless): 프로토콜에서 Client 의 상태를 기억하지 않습니다.
Client 의 상태를 보관하기 위해 쿠키나 세션, JWT 토큰 등을 이용하여 Client 의 상태를 유지합니다.
HTTPS
HTTPS 는 Hypertext Transfer Protocol Secure 의 약자로 간단히 HTTP 의 보안 버전입니다. HTTP 프로토콜의 최상위에 SSL/TLS 암호화를 구현합니다. 일반 HTTP 프로토콜은 서버에서부터 Client 로 전송되는 정보가 암호화되지 않아 데이터가 쉽게 도난당할 수 있다는 문제가 있습니다. HTTPS 프로토콜은 HTTP + 암호화 + 증명서 + 완전성 으로 HTTP의 보안적 약점을 보완한 프로토콜입니다.
HTTP vs HTTPS
보안 (Security):
HTTP (HyperText Transfer Protocol): HTTP는 데이터를 암호화하지 않고 평문으로 전송합니다. 이는 해커들이 중간에서 데이터를 갈취하거나 조작할 수 있는 보안 취약점을 가지고 있습니다.
HTTPS (HyperText Transfer Protocol Secure): HTTPS는 데이터를 암호화하여 전송합니다. 이것은 중간에서 데이터를 읽거나 변조하는 것을 훨씬 어렵게 만듭니다. 따라서 개인 정보와 민감한 데이터를 전송할 때 더 안전합니다.
인증 (Authentication):
HTTP: HTTP는 서버의 정체성을 확인하지 않으므로, 악의적인 사이트로 유려하게 리디렉션될 수 있습니다.
HTTPS: HTTPS는 SSL/TLS 인증서를 사용하여 웹 사이트의 신뢰성을 확인합니다. 이는 사용자가 신뢰할 수 있는 웹 사이트에 연결되고 있음을 보장합니다.
SEO (Search Engine Optimization):
HTTP: 구글과 같은 검색 엔진은 HTTPS를 선호하며, HTTPS를 사용하는 웹 사이트가 높은 랭킹을 받을 가능성이 높습니다.
브라우저 표시 (Browser Display):
HTTP: 브라우저에서 HTTP 웹사이트는 "안전하지 않음" 또는 "정보를 위조할 수 있음"과 같은 경고를 표시할 수 있습니다.
HTTPS: HTTPS 웹사이트는 브라우저에서 안전한 웹사이트로 표시되며 사용자에게 신뢰감을 줍니다.
var request = URLRequest(url: url)
request.httpMethod = "POST" // 요청에 사용할 HTTP 메서드 설정
// HTTP 헤더 설정
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue("application/json", forHTTPHeaderField: "Accept")
// HTTP 바디 설정
let body = [
"title": "example title",
"body": "example body"
] as [String: Any]
do {
request.httpBody = try JSONSerialization.data(withJSONObject: body, options: [])
} catch {
print("Error creating JSON data")
}
URLRequest 에 메서드를 설정하여 GET, POST, DELETE 등의 메서드를 요청할 수 있습니다.
URLRequest 객체를 조작하여 캐시 정책, 타임 아웃 시간 등을 조작할 수 있습니다.
3. URLSession 객체를 이용하여 요청 및 응답 처리
let task = URLSession.shared.dataTask(with: request) { data, response, error in
if let error = error {
print("Error: \(error)")
} else if let data = data, let response = response as? HTTPURLResponse, response.statusCode == 201 {
do {
if let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] {
print("JSON Response: \(json)")
}
} catch {
print("Error parsing JSON response")
}
} else {
print("Unexpected error")
}
}
// 작업 시작
task.resume()
GET 과 POST 의 차이
GET
GET 은 URL 뒤에 데이터를 붙여서 전달합니다. 즉 데이터는 URL의 쿼리 문자열에 노출되며, 사용자가 주소창에서 볼 수 있습니다.
GET 은 URL 길이에 제한이 있으며, 브라우저 및 웹 서버마다 다를 수 있습니다. 일반적으로 2048자 이하로 제한됩니다.
GET 요청은 브라우저에 의해 캐싱될 수 있으므로 동일한 요청을 반복할 때 서버로의 요청이 줄어들 수 있습니다.
GET 요청은 주로 데이터 조회 또는 검색에 사용되며, 서버에 변경을 가하지 않습니다. 따라서 데이터 무결성과 안전성이 보다 적합합니다.
POST
POST 는 HTTP Request 바디에 데이터를 실어 보냅니다. 데이터는 URL에 노출되지 않으므로 비밀 정보나 큰 데이터를 안전하게 전송할 수 있습니다.
POST 는 일반적으로 더 큰 데이터 양을 처리할 수 있고, 제한은 서버 구성 및 웹 애플리케이션에 따라 다를 수 있습니다.
POST 요청은 브라우저에 의해 캐싱되지 않으므로 항상 새로운 요청으로 처리됩니다.
POST 요청은 서버에 데이터 변경을 요청하는 데 주로 사용됩니다. 예를 들어, 양식을 제출하거나 데이터베이스에 새로운 정보를 추가하는 데 적합합니다.
POST 요청은 GET에 비해 데이터를 더 안전하게 전송하며, 웹 애플리케이션에서 보다 엄격한 권한 및 보안 검사를 수행할 수 있습니다.
요약
GET은 데이터 검색 및 조회에 사용되며, URL에 노출되어 데이터가 제한적이며 캐싱 가능합니다. 반면에 POST는 데이터 변경 및 서버에 대규모 데이터를 안전하게 전송하는 데 사용되며, URL에 노출되지 않으며 캐싱되지 않습니다. 선택은 사용 사례와 보안 요구 사항에 따라 달라집니다.
HTTP 상태 코드
HTTP 상태 코드(HTTP status code)는 웹 서버가 클라이언트에게 보내는 3자리 숫자로 된 응답 코드입니다. 이 코드는 HTTP 요청의 결과를 나타내며, 클라이언트에게 요청 처리 과정에 대한 정보를 전달합니다.
1xx (Informational - 정보)
100 Continue: 요청이 수신되었으며 계속 진행될 것임을 나타냅니다.
101 Switching Protocols: 서버가 프로토콜을 변경할 것임을 알립니다.
2xx (Successful - 성공)
200 OK: 요청이 성공적으로 처리되었음을 나타냅니다.
201 Created: 요청이 성공적으로 처리되어 새로운 리소스가 생성되었음을 나타냅니다.
204 No Content: 요청이 성공적으로 처리되었지만 응답 본문에 내용이 없음을 나타냅니다.
3xx (Redirection - 리디렉션)
301 Moved Permanently: 요청한 리소스가 새로운 위치로 영구적으로 이동했음을 나타냅니다.
302 Found (or Moved Temporarily): 요청한 리소스가 일시적으로 다른 위치로 이동했음을 나타냅니다.
304 Not Modified: 클라이언트가 캐시된 버전을 사용하고 리소스가 변경되지 않았음을 나타냅니다.
4xx (Client Error - 클라이언트 오류)
400 Bad Request: 요청이 잘못되었거나 서버에서 처리할 수 없음을 나타냅니다.
401 Unauthorized: 요청한 리소스에 대한 인증이 필요함을 나타냅니다.
403 Forbidden: 클라이언트가 리소스에 접근할 권한이 없음을 나타냅니다.
404 Not Found: 요청한 리소스를 찾을 수 없음을 나타냅니다.
5xx (Server Error - 서버 오류)
500 Internal Server Error: 서버에서 요청을 처리하는 중에 오류가 발생했음을 나타냅니다.
502 Bad Gateway: 게이트웨이나 프록시 서버가 요청을 처리하는 동안 오류가 발생했음을 나타냅니다.
503 Service Unavailable: 서버가 현재 서비스를 이용할 수 없음을 나타냅니다.
여러 개의 파일을 POST로 한 번에 업로드하는 방법
Multipart
Multipart 는 다중 부분으로 이루어진 데이터 형식을 나타냅니다. HTTP 프로토콜을 통해 데이터를 전송할 때 여러 종류의 데이터를 함께 전송하기 위해 사용되며, 파일 업로드, 웹 양식 데이터 전송 등에서 흔히 사용됩니다. Multipart 데이터 형식은 각 부분이 별도의 데이터 덩어리로 구분되고, 각 부분에는 해당 데이터의 종류, 길이, 이름 등의 정보가 포함됩니다. Multipart 형식을 사용할 때 아래와 같은 특징이 있습니다.
메모리 효율성
파일을 작은 파트로 분리하여 전송하므로 이는 전체 파일을 메모리에 로드하지 않고도 작은 조각들을 순차적으로 전송이 가능합니다.
전체 파일을 메모리에 한 번에 올리지 않고도 업로드할 수 있어서 메모리 사용량을 효율적으로 관리가 가능합니다.
네트워크 대역폭에 효율
멀티파트 폼 데이터는 파트를 순차적으로 전송합니다.
한 번에 전체 파일을 전송하는 것보다 네트워크 대역폭을 더 효율적으로 활용합니다.
대용량 파일의 경우 전체 파일을 한 번에 업로드하는 것보다 작은 파트들로 분할하여 전송하면 더 빠른 전송 속도가 가능합니다.
개별적으로 재전송 가능
멀티파트 폼 데이터는 각각의 파트가 독립적으로 전송니다.
전송 중에 문제가 발생했을 경우 해당 파트만 재전송이 가능합니다.
일반적으로 전체 파일을 한 번에 업로드하는 경우에는 전송이 중단된 경우에 다시 처음부터 전송해야 하지만 멀티파트 폼 데이터를 사용하면 문제가 발생한 파트만 다시 전송하여 효율적으로 재전송이 가능합니다.
Multipart Form Data 전송 구현
let url = URL(string: "https://example.com/upload")
var request = URLRequest(url: url!)
request.httpMethod = "POST"
let uniqString = UUID().uuidString
let contentType = "multipart/form-data; boundary=\(uniqString)"
request.setValue(contentType, forHTTPHeaderField: "Content-Type")
// 폼 데이터 생성
var body = Data()
// 멀티 파트 데이터의 구분자(boundary)
body.append("--\(uniqString)\r\n".data(using: .utf8)!)
// 멀티 파트 데이터의 파트에 대한 헤더를 추가: name 파라미터를 "image"로 설정하고, 업로드된 파일의 원래 이름을 "image.jpg"로 설정
body.append("Content-Disposition: form-data; name=\"image\"; filename=\"image.jpg\"\r\n".data(using: .utf8)!)
// 업로드된 파일의 MIME 타입을 명시
body.append("Content-Type: image/jpeg\r\n\r\n".data(using: .utf8)!)
// 실제 이미지 바이너리 데이터를 담고있는 값 추가
body.append(imageData)
// 각 파트 사이에 빈 줄을 추가하여 파트를 구분하며 멀티파트 데이터의 각 파트를 구분하는 구분자 역할
body.append("\r\n".data(using: .utf8)!)
// 멀티파트 데이터의 끝을 나타내는 경계값을 추가하며 멀티파트 데이터의 마지막을 나타내고 파트들을 닫는 역할
body.append("--\(uniqString)--\r\n".data(using: .utf8)!)
// 전송
let task = URLSession.shared.uploadTask(with: request, from: body) { (data, response, error) in
// completion
}
task.resume()
HTTP와 HTTPS의 연결 방식의 차이와 효과
HTTP
HTTP 는 HyperText Transfer Protocol 의 약자로 HyperText 문서를 주고 받기 위해 만들어졌고, 최근에는 HTML뿐 아니라 모든 웹 관련 API 통신에 이용하고 있는 통신 프로토콜입니다. HTTP 프로토콜은 비연결성(Connectionless)과 무상태성(Stateless)의 특징을 가지는 통신 프로토콜입니다.
비연결성(Connectionless): 처음 연결을 맺은 후 요청(Request)과 한번의 응답(Response)이후 연결이 종료됩니다. 매 요청마다 다시 연결을 맺습니다. 매번 연결을 맺어 느려지는 것을 보완하기 위해 KeepAlive 와 같은 속성을 활용할 수 있습니다.
무상태성(Stateless): 프로토콜에서 Client 의 상태를 기억하지 않습니다. Client 의 상태를 보관하기 위해 쿠키나 세션, JWT 토큰 등을 이용하여 Client 의 상태를 유지합니다.
HTTPS
HTTPS 는 Hypertext Transfer Protocol Secure 의 약자로 간단히 HTTP 의 보안 버전입니다. HTTP 프로토콜의 최상위에 SSL/TLS 암호화를 구현합니다. 일반 HTTP 프로토콜은 서버에서부터 Client 로 전송되는 정보가 암호화되지 않아 데이터가 쉽게 도난당할 수 있다는 문제가 있습니다. HTTPS 프로토콜은 HTTP + 암호화 + 증명서 + 완전성 으로 HTTP의 보안적 약점을 보완한 프로토콜입니다.
HTTP vs HTTPS
보안 (Security):
인증 (Authentication):
SEO (Search Engine Optimization):
브라우저 표시 (Browser Display):
URLSession 을 이용한 RESTful API 연동
1. URLComponents 를 이용한 URL 객체 생성
2. URLRequest 객체 생성
GET
,POST
,DELETE
등의 메서드를 요청할 수 있습니다.3. URLSession 객체를 이용하여 요청 및 응답 처리
GET 과 POST 의 차이
GET
POST
요약
GET은 데이터 검색 및 조회에 사용되며, URL에 노출되어 데이터가 제한적이며 캐싱 가능합니다. 반면에 POST는 데이터 변경 및 서버에 대규모 데이터를 안전하게 전송하는 데 사용되며, URL에 노출되지 않으며 캐싱되지 않습니다. 선택은 사용 사례와 보안 요구 사항에 따라 달라집니다.
HTTP 상태 코드
HTTP 상태 코드(HTTP status code)는 웹 서버가 클라이언트에게 보내는 3자리 숫자로 된 응답 코드입니다. 이 코드는 HTTP 요청의 결과를 나타내며, 클라이언트에게 요청 처리 과정에 대한 정보를 전달합니다.
1xx (Informational - 정보)
2xx (Successful - 성공)
3xx (Redirection - 리디렉션)
4xx (Client Error - 클라이언트 오류)
5xx (Server Error - 서버 오류)
여러 개의 파일을 POST로 한 번에 업로드하는 방법
Multipart
Multipart 는 다중 부분으로 이루어진 데이터 형식을 나타냅니다. HTTP 프로토콜을 통해 데이터를 전송할 때 여러 종류의 데이터를 함께 전송하기 위해 사용되며, 파일 업로드, 웹 양식 데이터 전송 등에서 흔히 사용됩니다. Multipart 데이터 형식은 각 부분이 별도의 데이터 덩어리로 구분되고, 각 부분에는 해당 데이터의 종류, 길이, 이름 등의 정보가 포함됩니다. Multipart 형식을 사용할 때 아래와 같은 특징이 있습니다.
메모리 효율성
네트워크 대역폭에 효율
개별적으로 재전송 가능
Multipart Form Data 전송 구현