Reputation: 151
1) I have the following in Package.swift:
.package(url:
"https://github.com/vapor/postgresql.git", from: "1.0.0")
targets: [
.target(name: "App", dependencies: ["FluentSQLite", "Vapor", "PostgreSQL"]),
... etc.
2) And I have PostgreSQL configured in configure.swift:
let postgreSQLConfig = PostgreSQLDatabaseConfig(
hostname: "localhost",
port: 5432,
username: "postgres",
database: "mydb2",
password: "bigsecret"
)
let psql = PostgreSQLDatabase(config: postgreSQLConfig)
var databases = DatabasesConfig()
databases.add(database: psql, as: .psql)
services.register(databases)
3) And I have a table called article in PostgreSQL 11.3. 4) And I have the following in Article.swift:
import Foundation
import FluentPostgreSQL
import Vapor
struct Article: PostgreSQLModel {
var id: Int?
var title: String
var content: String
init(id: Int? = nil, title: String, content: String) {
self.title = title
self.content = content
}
}
extension Article: Content {}
extension Article: Migration {}
5) routes.swift looks like:
let articleController = ArticleController()
router.get("articles", use: articleController.index)
router.post("articles", use: articleController.create)
6) Both the POST and GET are working (i.e. the GET returns everything I've POSTed) ,but I don't see the table in PostgreSQL, so I have no idea where the data is being stored:
import Vapor
import Foundation
final class ArticleController {
func index(_ req: Request) throws -> Future<[Article]> {
return Article.query(on: req).all()
}
func create(_ req: Request) throws -> Future<Article> {
return try req.content.decode(Article.self).flatMap { article in
print("10j")
return article.save(on: req)
}
}
}
The request has Content-Type set to application/json and the request body looks like:
{"id":1,"title":"GGG","content":"HHH"}
Upvotes: 0
Views: 219
Reputation: 151
Mystery solved. You need to quote the table name because of the capital A: mydb4=# select * from "Article";
Upvotes: 1
Reputation: 151
Also the POST request body (I'm using Rested on the macbook) should not have a PK (PostgreSQL supplies the PK). So:
{"title":"GGG","content":"HHH"}
not
{"id":1,"title":"GGG","content":"HHH"}
Upvotes: 1
Reputation: 151
I forgot to mention back in 2) - configure.swift at the end should have the migration code to create the table when you run the Xcode (or migrate any columns you added or changed in Article.swift):
var migrations = MigrationConfig()
migrations.add(model: Article.self, database: .psql)
services.register(migrations)
Upvotes: 1
Reputation: 5620
You can't just throw away the future like that. This causes a number of problems:
Since everything is asynchronous, you need to change the way you write your code. Instead you should do something like:
router.post(Article.self, at: "article") { req, article -> String in
return article.save(on: req).map { savedArticle in
return("what happened?")
}
}
As for why the save has failed, you should see that printed out in the console.
Upvotes: 1
Reputation: 5656
You need to decode a payload, then save it into database and then transform to desired result
router.post(at: "article") { req -> EventLoopFuture<String> in
let article = try req.content.decode(Article.self)
return article.create(on: req).transform(to: "what happened?")
}
If you haven't created a model yet you can do it via migrations in configure.swift
(example for Vapor3)
var migrations = MigrationConfig()
migrations.add(model: Article.self, database: .psql)
services.register(migrations)
Artice
model file should look like (example for Vapor3)
final class Article {
var id: Int?
var title: String
var content: String
init(id: Int? = nil, title: String, content: String) {
self.title = title
self.content = content
}
}
extension Article: Content {}
extension Article: Migration {}
extension Article: Model {
typealias Database = PostgreSQLDatabase
typealias ID = Int
static var idKey: IDKey { \.id }
}
Upvotes: 2