Carregando...

Vapor 3 Postgres e OneModel

30 de August de 2018

 

Vapor

 


http://vapor.codes

 

 

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

 

Instalando o Vapor

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.

Link Documentação Fluet

 

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:

 

Configurações de Serviços, IP e porta: 

Providers:

 

/// Register providers first

try services.register(FluentPostgreSQLProvider())

 

 

IP e Porta:

 

//Configure IP And Port

    let serverConfiure = NIOServerConfig.default(hostname: "0.0.0.0", port: 8080)

    services.register(serverConfiure)

 

 

Fluent PostgreSQL DataBase:

 

/// 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)

 

 

Migrations:

 

/// Configure migrations

    var migrations = MigrationConfig()

    migrations.add(model: Todo.self, database: .psql)

    //migrations.add(model: Todo.self, database: .psql)

    services.register(migrations)

 

 

Configurando Model: Sources > App > Models > Todo.Swift

 

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 { }

 

 

Agora abra o arquivo: Sources > App > Controllers > TodoController.Swift

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 { }

 

 

Nosso arquivo após os ajustes deve ficar assim:

 

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 =)

 

Testando API com Postman:

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.

 

Criando um App de Todo e Reaproveitando o Model

 

Primeiro precisamos adicionar um novo Target no projeto:

 

  1. Selecione o Projeto e ckique no icone + conforme imagem abaixo:


     
  2. Selecione Single View App:


     
  3. Preencha os campos conforme preferir e de ok:

 

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. 

 

 

Desenvolvido por Michel Lütz