Environment: MacOS 13.5.1 Vapor 4.77 Scenario: Attempting to post:
{"title":"String", "description":"String", "Info":"Data"} to a Postgre DB via Vapor version 4.77.
In this case, I'm using application/JSON for info. But Info could also be an image/png.
Problem: Fluent refuses to auto-generate the ID and hence, I'm getting an error.
Here's the server package:
dependencies: [
// A server-side Swift web framework.
.package(url: "https://github.com/vapor/vapor.git", from: "4.77.1"),
// An ORM for SQL and NoSQL databases.
.package(url: "https://github.com/vapor/fluent.git", from: "4.8.0"),
// Fluent driver for Postgres.
.package(url: "https://github.com/vapor/fluent-postgres-driver.git", from: "2.7.2"),
.package(url: "https://github.com/vapor/multipart-kit.git", from: "4.5.4"),
],
Here's a code snippet from the client, building the URLRequest body via multipart/form-data context-type:
// ...
let title = "Frederick C. Lee"
let description = "Mother had a feeling, I might be too appealing."
var body = Data()
let boundary = "Boundary-\(UUID().uuidString)"
// Construct request
var request = URLRequest(url: serverURL)
request.httpMethod = "POST"
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
// Two boundaries: 1) Country Name and 2) Country Info (Data)
// Note: the multiple '\r\n' is necessary syntax.
// 1) Title:
body.append("--\(boundary)\r\n".data(using: .utf8)!)
body.append("Content-Disposition: form-data; name=\"title\"\r\n".data(using: .utf8)!)
body.append("Content-Type: text/plain\r\n\r\n".data(using: .utf8)!)
body.append("\(title)\r\n".data(using: .utf8)!)
// -----------------
// 2) Description
body.append("--\(boundary)\r\n".data(using: .utf8)!)
body.append("Content-Disposition: form-data; name=\"description\"\r\n".data(using: .utf8)!)
body.append("Content-Type: text/plain\r\n\r\n".data(using: .utf8)!)
body.append("\(description)\r\n".data(using: .utf8)!)
// -----------------
// 3) Info (with Data)
body.append("--\(boundary)\r\n".data(using: .utf8)!)
body.append("Content-Disposition: form-data; name=\"info\"\r\n".data(using: .utf8)!)
body.append("Content-Type: application/json\r\n\r\n".data(using: .utf8)!) // Assuming binary data
body.append(infoData!) // Append your actual Data here
body.append("\r\n".data(using: .utf8)!)
// Append the final boundary
body.append("--\(boundary)--\r\n".data(using: .utf8)!)
request.httpBody = body
return request
}
The model:
import Fluent
import Vapor
final class TurkeyGizzard: Model, Content {
static let schema = "turkeygizzard"
@ID(key: .id)
var id: UUID?
@Field(key: "title")
var title: String
@Field(key: "description")
var description: String
@Field(key: "info")
var info: Data?
init() {}
init(title: String, description: String, info: Data) {
self.id = UUID()
self.title = title
self.info = info
}
}
Here's the Migration:
struct CreateTurkeyGizzards: AsyncMigration {
func prepare(on database: FluentKit.Database) async throws {
try await database.schema("turkeygizzard")
.id()
.field("title", .string)
.field("description", .string)
.create()
}
func revert(on database: FluentKit.Database) async throws {
try await database.schema("turkeygizzard").delete()
}
}
Initially, I tried to let Fluent generate the ID for me. But that didn't work, so I created a new self.id via initialization.
But I still get the following run error:
Response String: {"error":true,"reason":"Value required for key at path 'id'. No value associated with key "id"."}
I thought Fluent could auto-generate an ID.
Any remedy?
**Note:** I'll try without the Fluent dependency and work directly with persistent storage. Less hassle.