Reputation: 730
I'm getting familiar with Vapor 2.0 server-side Swift framework, and what confuses me is the extensive use of string literals. For example, implementing the Model
protocol you have to parse and serialize rows like this (taken from auto-generated example project):
// Initializes the Post from the database row
init(row: Row) throws {
content = try row.get("content")
}
// Serializes the Post to the database
func makeRow() throws -> Row {
var row = Row()
try row.set("content", content)
return row
}
As you can see, for every property you use its database name twice as a string literal just for this particular protocol. And there's more in other cases — say, Database
protocol, your own methods, etc.
Using literal strings as parameters here has obvious disadvantage of static analyser not checking them (just like key-value parameters in Objective-C), making this approach highly error-prone. Is there any best practice I'm missing?
Upvotes: 1
Views: 335
Reputation: 1000
Nope! You're doing it right. There is little we can do to mitigate this due to the lack of advanced runtime libraries in Swift.
However, in Swift 4, you can use key paths for the same purpose.
\Post.content
will create a statically checked keypath for the content variable.
The WWDC session on key paths is definitely worth a watch.
Upvotes: 0
Reputation: 4065
You can easily minimize the number of times you repeat the string by storing it as a static property on the model and referencing that instead.
final class Post: Model {
// Keys
static let contentKey = "content"
// Properties
var content: String
// Initializes the Post from the database row
init(row: Row) throws {
content = try row.get(Post.contentKey)
}
// Serializes the Post to the database
func makeRow() throws -> Row {
var row = Row()
try row.set(Post.contentKey, content)
return row
}
...
}
extension Post: Preparation {
static func prepare(_ database: Database) throws {
try database.create(self) { builder in
builder.id()
builder.string(Post.contentKey)
}
}
...
}
Unfortunately that's probably all you can meaningfully do to make things more type-safe. There's currently no way to give the compiler information about the actual structure of the database (or any other string-y thing, like JSON). It would be really amazing if we could do that, though! Maybe some day.
(I'll look into updating the API and Web templates to include this, track the issue here: https://github.com/vapor/api-template/issues/35)
Upvotes: 1