티스토리 뷰
[Vapor] Swift로 서버 만들기 06 - Fluent에 HTTP 메소드 만들기 (GET, POST, PUT, DELETE)
말차프라푸치노 2023. 5. 19. 13:16
지난 포스트에서 Fluent와 PostgreSQL을 연결하고 URL을 통해 그 결과를 확인했다.
이번 글에서는 기본으로 제공되는 메소드를 분석해보고, 추가로 메소드를 작성해 CRUD를 할 것이다.
[Vapor] Swift로 서버 만들기 05 - Fluent 통해서 PostgreSQL 사용하기
이번 포스트에서는 PostgerSQL 데이터베이스를 만들고, Fluent를 사용해 데이터를 다뤄볼 것이다. Fluent 개념과 PostrgreSQL에 대해서는 이전 글들을 통해 확인할 수 있다. [Swift] Swift로 서버 만들기 Vapor 0
malchafrappuccino.tistory.com
Postman
API 테스트를 위해 가장 많이 사용하는 Postman을 사용할 것이다.
프로젝트를 실행하고 Postman에 들어가서 기본 호출을 해본다.
에러가 발생한다.
뭐지? 프로젝트 안 켰나하고 크롬창에 쳐보면
잘만 나온다.
Postman Agent 설치
현재 로컬 머신에서 프로젝트를 실행하고 있다. 에러 메시지에 보이는 것처럼 그냥 postman을 사용하면 로컬 호스트에 접속할 수가 없다.
로컬호스트에 접속하기 위해서 Postman Agent라는 추가적인 프로그램을 깔아줘야 한다.
Postman Agent: For Mac, Windows, & Linux
The Postman agent overcomes the Cross-Origin Resource Sharing (CORS) limitations of browsers, and facilitates API request sending from your browser version of Postman.
www.postman.com
설치가 완료되면 프로그램을 클릭해서 실행해준다. 우측 상단에서 실행되고 있는 것을 확인할 수 있다.
프로그램을 실행하고 다시 메소드를 호출해보면
응답이 잘 오는 것을 확인할 수 있다.
TodoController 기본 메소드
Vapor 프로젝트 생성할 때 Fluent를 같이 생성하면 TodoController.Swift 파일이 같이 생성된다.
struct TodoController: RouteCollection {
func boot(routes: RoutesBuilder) throws {
let todos = routes.grouped("todos")
todos.get(use: index)
todos.post(use: create)
todos.group(":todoID") { todo in
todo.delete(use: delete)
}
}
func index(req: Request) async throws -> [Todo] {
//...
}
func create(req: Request) async throws -> Todo {
//...
}
func delete(req: Request) async throws -> HTTPStatus {
//...
}
}
하나하나 살펴보자
boot(routes:)
boot 함수는 TodoController를 시작하는 함수로써 RouteCollection을 채택하면 반드시 구현해주어야 하는 함수이다.
새로운 routes를 등록한다.
boot함수 안을 살펴보자
func boot(routes: RoutesBuilder) throws {
let todos = routes.grouped("todos")
todos.get(use: index)
todos.post(use: create)
todos.group(":todoID") { todo in
todo.delete(use: delete)
}
}
grouped 메소드를 호출한다. 이 메소드는 routes URL에 Path를 더해주는 함수이다.
현재 기본 route URL은 http://127.0.0.1:8080 이다.
grouped 메소드를 통해 path에 경로를 붙여주었으므로 todos 프로퍼티는 http://127.0.0.1:8080/todos 가 된다.
todos에 메소드를 사용해 HTTP 메소드를 등록한다. get(use:), post(use:) 은 클로저를 인자로 받는다.
해당 HTTP 메소드 호출시 실행될 응답 클로저를 인자에 넣어준다.
get 메소드
func index(req: Request) async throws -> [Todo] {
try await Todo.query(on: req.db).all()
}
get 메소드는 index 함수를 인자로 받는다.
index 함수는 Todo 모델이 저장된 db에서 모든 데이터를 배열로 리턴한다.
Postman을 통해 메소드를 날려보면
빈 배열을 확인할 수 있다. (아직 아무 데이터도 추가하지 않음)
Post 메소드
todos.post(use: create)
post 메소드는 create 함수를 인자로 받는다.
func create(req: Request) async throws -> Todo {
let todo = try req.content.decode(Todo.self)
try await todo.save(on: req.db)
return todo
}
- 요청(request)의 content(=body)에서 Todo 모델을 디코드 한다.
- DB에 저장한다.
- 응답으로 저장한 Todo를 리턴한다.
1번을 위해 HTTP post메소드 body에 JSON 형식으로 Todo 모델을 넣어준다.
그리고 응답을 확인하면?
Todo 모델이 잘 도착했다! 잉 근데 나는 title이랑 descrition만 작성했는데??
앞선 포스트에서 작성했듯이 id를 설정하지 않으면 Fluent가 자동으로 id를 생성해준다.
createdAt과 updatedAt과 같은 TimeStamp 필드도 Fluent가 상황에 맞게 자동으로 업데이트 해준다.
get 메소드를 통해 전체 DB를 확인해보면
잘 저장된 것을 확인할 수 있다.
delete 메소드
todos.group(":todoID") { todo in
todo.delete(use: delete)
}
delete 메소드는 get과 post와는 다르게 생겼다.
group 메소드를 통해 추가 path를 받고 해당 path에 todoID를 넣어준다.
http://127.0.0.1:8080/todos/{todoID를 넣어줌}
todo의 delete를 살펴보자
func delete(req: Request) async throws -> HTTPStatus {
guard let todo = try await Todo.find(req.parameters.get("todoID"), on: req.db) else {
throw Abort(.notFound)
}
try await todo.delete(on: req.db)
return .noContent
}
메소드의 todoID로 받은 인자를 사용해 db에서 해당하는 Todo모델을 찾는다. -> 만약 해당하는 모델이 없다면 notFound 에러를 응답으로 보낸다.
db에서 모델을 삭제한 후 컨텐츠 없이 응답만 리턴해준다. 여기서 에러 메시지를 커스텀하고 싶으면 리턴 값을 수정해주면 된다.
메소드를 호출해보면
204 No Content 응답을 확인할 수 있다.
데이터가 삭제된 상태에서 한 번 더 호출하면?
404 Not Found 에러를 확인할 수 있다.
다시 get해 보면 DB에서 다 사라진 것을 확인할 수 있다.
커스텀 HTTP 메소드 추가하기
TodoController의 기본 메소드에는 업데이트가 없다. Todo 모델 업데이트 함수를 작성해보자.
func update(req: Request) async throws -> Todo {
let newTodo = try req.content.decode(Todo.self)
guard let todo = try await Todo.find(newTodo.id, on: req.db) else {
throw Abort(.notFound)
}
todo.title = newTodo.title
todo.description = newTodo.description
try await todo.update(on: req.db)
return todo
}
update 함수는 총 5단계를 거친다.
- 우선 수정할 모델 newTodo을 요청으로 받는다.
- newTodo의 id를 기반으로 DB에서 수정할 모델 todo를 찾는다.
- todo의 title과 description을 newTodo 걸로 수정해준다.
- DB를 업데이트 한다.
- 수정된 모델을 응답으로 리턴한다.
boot 함수에 PUT메소드도 추가해준다.
func boot(routes: RoutesBuilder) throws {
let todos = routes.grouped("todos")
todos.get(use: index)
todos.post(use: create)
todos.group(":todoID") { todo in
todo.delete(use: delete)
}
todos.put(use: update) // PUT 추가하기
}
메소드 작성 완료. Postman에서 확인해보자
POST를 사용해 새로운 내용을 추가해주었다.
PUT 메소드를 추가하자
여기서 post의 body와 다른 점은 id를 필수로 추가해주어야 한다는 것이다. 그래야 id로 db에서 찾을 수 있으니까
메소드를 호출하고 응답을 확인하면
title과 description이 수정된 것을 확인할 수 있다. 또 Fluent가 업데이트를 감지하고 자동으로 updateAt 필드를 업데이트 해주었다.
+ Post를 통해 모델을 몇 개 더 추가해주었다.
이제 조금 DB 다워졌다.
정리
TodoController의 기본 메소드를 살펴보고 Update함수를 추가로 작성해주었다.
처음 사용할 때는 Controller 사용법을 몰라 routes 함수에 메소드를 다 때려넣었는데, Controller를 사용하니 훨씬 깔끔해지고 코드 분리가 명확해졌다.
API를 만드는 것을 처음해보는데 재밌다.
다음에는 쿼리 날리는 공부를 해봐야겠다.
끗!
다음 포스트 - 쿼리(Query) 만들기 Filter, Sort, Count, Paginate 등
[Vapor] Swift로 서버 만들기 07 - Fluent 쿼리(Query) 만들기 Filter, Sort, Count, Paginate 등
지난 포스트에서 HTTP 메소드를 만들어 모델에 대해 CRUD를 했다. Fluent의 query API는 데이터베이스에서 모델을 CRUD할 뿐만아니라 필터링, 조인, 청크, 집계 등을 지원한다. 이번 글에서는 Fluent 공식
malchafrappuccino.tistory.com
출처
Vapor: Fluent → Model
Models Models represent data stored in tables or collections in your database. Models have one or more fields that store codable values. All models have a unique identifier. Property wrappers are used to denote identifiers, fields, and relations. Below is
docs.vapor.codes
'Swift > Vapor' 카테고리의 다른 글
[Vapor] Swift로 서버 만들기 08 - 도커(Docker)로 배포하기 (0) | 2023.05.24 |
---|---|
[Vapor] Swift로 서버 만들기 07 - Fluent 쿼리(Query) 만들기 Filter, Sort, Count, Paginate 등 (0) | 2023.05.20 |
[Vapor] Swift로 서버 만들기 05 - Fluent 통해서 PostgreSQL 사용하기 (0) | 2023.05.18 |
[Vapor] Swift로 서버 만들기 04 - Fluent 설치 및 개념 (Models, Field, Timestamp, Migration 등) (0) | 2023.05.18 |
[Vapor] Swift로 서버 만들기 03 - PostgreSQL 개념, 설치, 사용 (0) | 2023.05.15 |
- Total
- Today
- Yesterday
- SwiftUI
- 부스트캠프iOS
- Swift DocC
- Swift공식문서
- Combine
- 책후기
- 코딩테스트
- 코딩 테스트
- 부스트캠프
- Swift 서버
- 앱개발
- todo앱
- 책
- swiftUI 기초
- 책리뷰
- vapor
- 디자인 패턴
- 필독서
- Swift 디자인 패턴
- Swift
- 애플
- ios
- 부스트캠프7기
- UX
- Swift문법
- TODO
- 프로그래머스
- 개발
- 날씨어플
- 코딩
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |