Objetivo: Criar uma api com reaproveitamento de modelo de dados para uso em aplicativo nativo.
Keynote: https://www.slideshare.net/michelboss/cocoaheads-poa-agosto-18
Siga as instruções do site oficial: https://docs.vapor.codes/3.0/install/macos/
Após instalado e com o XCode aberto, vamos instalar o Fluent para o PostreSQL, que será o responsável por toda a comunicação de model / vapor com nosso banco de dados.
Adicione o pacote no arquivo Package.swift
dependencies: [
// 💧 A server-side Swift web framework.
.package(url: "https://github.com/vapor/vapor.git", from: "3.0.0"),
.package(url: "https://github.com/vapor/fluent-sqlite.git", from: "3.0.0")
.package(url: "https://github.com/vapor/fluent-postgresql.git", from: "1.0.0"),
],
targets: [
.target(name: "App", dependencies: ["FluentSQLite", "FluentPostgreSQL", "Vapor"]),
Após adicionar as linhas e dependências execute novamente o comando:
$ vapor xcode
Para que sejam instaladas as dependências no projeto.
Faça isso sempre que adicionar e ou remover alguma dependência
Feito isso vamos começar as configurações:
/// Register providers first
try services.register(FluentPostgreSQLProvider())
//Configure IP And Port
let serverConfiure = NIOServerConfig.default(hostname: "0.0.0.0", port: 8080)
services.register(serverConfiure)
/// Configure a PostgreSQL database
var databases = DatabasesConfig()
let databaseConfig = PostgreSQLDatabaseConfig(hostname: "localhost", username: "michel", database: "todoDemo1")
let dataBase = PostgreSQLDatabase(config: databaseConfig)
databases.add(database: dataBase, as: .psql)
services.register(databases)
/// Configure migrations
var migrations = MigrationConfig()
migrations.add(model: Todo.self, database: .psql)
//migrations.add(model: Todo.self, database: .psql)
services.register(migrations)
Vamos alterar o model Todo para o seguinte formato. Removendo o import do FluentSQLite também o protocolo SQLiteModel substituindo por Codable, vamos adicionar um atributo / campo do tipo Bool
import Foundation
/// A single entry of a Todo list.
final class Todo: Codable {
/// The unique identifier for this `Todo`.
var id: Int?
/// A title describing what this `Todo` entails.
var title: String
/// A flag describing if this `Todo` is done.
var done: Bool?
/// Creates a new `Todo`.
init(id: Int? = nil, title: String, done: Bool? = false) {
self.id = id
self.title = title
self.done = false
}
}
Vamos recortar agora as seguintes linhas que estão abaixo da class Todo:
/// Allows `Todo` to be used as a dynamic migration.
extension Todo: Migration { }
/// Allows `Todo` to be encoded to and decoded from HTTP messages.
extension Todo: Content { }
/// Allows `Todo` to be used as a dynamic parameter in route definitions.
extension Todo: Parameter { }
Logo abaixo do import Vapor, cole o código que copiamos do arquivo Todo.swift
Vamos aproveitar e importar também a Lib FluentPostgreSQL e adicionar a Extension para o mesmo
extension Todo: PostgreSQLModel { }
import Vapor
import FluentPostgreSQL
extension Todo: PostgreSQLModel { }
/// Allows `Todo` to be used as a dynamic migration.
extension Todo: Migration { }
/// Allows `Todo` to be encoded to and decoded from HTTP messages.
extension Todo: Content { }
/// Allows `Todo` to be used as a dynamic parameter in route definitions.
extension Todo: Parameter { }
/// Controls basic CRUD operations on `Todo`s.
final class TodoController {
/// Returns a list of all `Todo`s.
func index(_ req: Request) throws -> Future<[Todo]> {
return Todo.query(on: req).all()
}
/// Saves a decoded `Todo` to the database.
func create(_ req: Request) throws -> Future<Todo> {
return try req.content.decode(Todo.self).flatMap { todo in
return todo.save(on: req)
}
}
/// Deletes a parameterized `Todo`.
func delete(_ req: Request) throws -> Future<HTTPStatus> {
return try req.parameters.next(Todo.self).flatMap { todo in
return todo.delete(on: req)
}.transform(to: .ok)
}
}
Fizemos estes ajustes para que possamos isolar o arquivo de model Todo para que possamos usá-lo tanto no Vapor quanto em um projeto de app sem se preocupar com dependências.
Neste momento já podemos rodar o projeto e ver o banco criado. com o Terget Run selecionado aperte Command + R para rodar o projeto
Se tudo deu certo você deve ter a seguinte saída no console do XCode.
E se você abrir seu gerenciador de banco, terá o banco criado também. (Eu uso o pgAdmin)
Podemos fazer um commit de nossas alterações e partir para o próximo branch =)
Você pode facilmente testar a api com o Aplicativo Postman
Se fizermos um get no mesmo endereço já teremos a listagem com as todos criadas, se acessarmos no navegador o endereço http://localhost:8080/todos também teremos acesso as todos criadas.
Primeiro precisamos adicionar um novo Target no projeto:
Pronto você tem um novo target criado. Agora precisamos fazer com que o Model seja visto por nosso novo target.
Para isso selecione o arquivo de model e na coluna de Utilities marque o target do App conforme imagem abaixo:
Agora o Model Todo já está visivel para o Target do App.
Não vou entrar no melhor modo de fazer um app de Todo mas vou deixar o projeto final no github para que vocês vejam o tutorial rodando e criando registros.
Link do projeto final: https://github.com/micheltlutz/todoCocoaHeads
Fique a vontade e crie como você preferir.
Espero que tenham gostado e em breve trago novos posts de Vapor.