From f747a6c8abd1e3dfa7f62820ac998eb4d2fc9b7c Mon Sep 17 00:00:00 2001 From: Anton Bronnikov Date: Tue, 27 Sep 2016 17:25:34 +0200 Subject: [PATCH 1/4] Explain `context` argument from `makeNode` Based on answer from @loganwright on Slack --- fluent/model.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fluent/model.md b/fluent/model.md index c6cbfe99..ad606f1a 100644 --- a/fluent/model.md +++ b/fluent/model.md @@ -84,6 +84,8 @@ final class User: Model { When a `User` is saved, the `makeNode()` method will be called and the resulting `Node` will be saved to the database. The keys `id` and `name` are what we expect the columns or fields in the database to be named. +> In most of the cases you do not need to be concerned about `context` argument of the `makeNode(context:)` method. It’s a part of the protocol that allows extensibility in more advanced or specific scenarios. + ## Preparations Some databases, like MySQL, need to be prepared for a new schema. In MySQL, this means creating a new table. From 2edb87eee068495ba87811546fc7240133ffd0ef Mon Sep 17 00:00:00 2001 From: Anton Bronnikov Date: Wed, 28 Sep 2016 08:21:47 +0200 Subject: [PATCH 2/4] Fix broken link to ResponseRepresentable --- routing/basic.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routing/basic.md b/routing/basic.md index 193a3832..e7f52ea7 100644 --- a/routing/basic.md +++ b/routing/basic.md @@ -78,7 +78,7 @@ This is useful for creating special responses like redirects. It is also useful ### Response Representable -As you have seen in the previous examples, `String`s can be returned in route closures. This is because they conform to [ResponseRepresentable](../http/responserepresentable.md) +As you have seen in the previous examples, `String`s can be returned in route closures. This is because they conform to [ResponseRepresentable](../http/response-representable.md) A lot of types in Vapor conform to this protocol by default: - String From f595a85e5d3309f411081fdfa7f9b71cbe08e8ca Mon Sep 17 00:00:00 2001 From: Anton Bronnikov Date: Wed, 28 Sep 2016 08:22:52 +0200 Subject: [PATCH 3/4] Whitespace changes My brackets keep changing this file in places where I don't really touch it. --- fluent/model.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/fluent/model.md b/fluent/model.md index ad606f1a..092992f4 100644 --- a/fluent/model.md +++ b/fluent/model.md @@ -4,7 +4,7 @@ currentMenu: fluent-model # Model -`Model` is the base protocol for any of your application's models, especially those you want to persist. +`Model` is the base protocol for any of your application's models, especially those you want to persist. > `Model` is only available in Vapor, the Fluent equivalent is `Entity` @@ -32,7 +32,7 @@ import Fluent Then add the conformance to your class. ```swift -final class User: Model { +final class User: Model { ... } ``` @@ -64,7 +64,7 @@ final class User: Model { } ``` -The keys `id` and `name` are what we expect the columns or fields in the database to be named. The `extract` call is marked with a `try` because it will throw an error if the value is not present or is the wrong type. +The keys `id` and `name` are what we expect the columns or fields in the database to be named. The `extract` call is marked with a `try` because it will throw an error if the value is not present or is the wrong type. ### Node Representable @@ -88,7 +88,7 @@ When a `User` is saved, the `makeNode()` method will be called and the resulting ## Preparations -Some databases, like MySQL, need to be prepared for a new schema. In MySQL, this means creating a new table. +Some databases, like MySQL, need to be prepared for a new schema. In MySQL, this means creating a new table. ### Prepare @@ -108,9 +108,9 @@ final class User { Here we create a table named `users` that has an identifier field and a string field with the key `name`. This matches both our `init(node: Node)` and `makeNode() -> Node` methods. -### Revert +### Revert -An optional preparation reversion can be created. This will be run if `vapor run prepare --revert` is called. +An optional preparation reversion can be created. This will be run if `vapor run prepare --revert` is called. ```swift final class User { @@ -215,7 +215,7 @@ As can be seen in the protocol, Vapor models can automatically convert to `JSON` ## Options -Change the table/collection name +Change the table/collection name ```swift static var entity = "new_name" ``` From cd03a7501035005cffc702bcacf8710c62acc85a Mon Sep 17 00:00:00 2001 From: Anton Bronnikov Date: Wed, 28 Sep 2016 18:29:56 +0200 Subject: [PATCH 4/4] Explanation of the difference between request `parameters` vs. `data` Based on the response from @tanner in slack channel --- routing/parameters.md | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/routing/parameters.md b/routing/parameters.md index 66b6220b..846b8a5e 100644 --- a/routing/parameters.md +++ b/routing/parameters.md @@ -20,11 +20,11 @@ This creates a route that matches `users/:id` where the `:id` is an `Int`. Here' ```swift drop.get("users", ":id") { request in - guard let userId = request.parameters["id"].int else { - throw Abort.badRequest - } + guard let userId = request.parameters["id"].int else { + throw Abort.badRequest + } - return "You requested User #\(userId)" + return "You requested User #\(userId)" } ``` @@ -44,7 +44,7 @@ Our previous example with users can be further simplified. ```swift drop.get("users", User.self) { request, user in - return "You requested \(user.name)" + return "You requested \(user.name)" } ``` @@ -54,9 +54,9 @@ Here is what this would look like if model didn't conform to `StringInitializabl ```swift drop.get("users", Int.self) { request, userId in - guard let user = try User.find(userId) else { - throw Abort.notFound - } + guard let user = try User.find(userId) else { + throw Abort.notFound + } return "You requested User #\(userId)" } @@ -96,9 +96,9 @@ Type safe routing is currently limited to three path parts. This is usually reme ```swift drop.group("v1", "users") { users in - users.get(User.self, "posts", Post.self) { request, user, post in - return "Requested \(post.name) for \(user.name)" - } + users.get(User.self, "posts", Post.self) { request, user, post in + return "Requested \(post.name) for \(user.name)" + } } ``` @@ -110,14 +110,16 @@ As shown briefly above, you are still free to do traditional routing. This can b ```swift drop.get("v1", "users", ":userId", "posts", ":postId", "comments": ":commentId") { request in - let userId = try request.parameters.extract("userId") as Int - let postId = try request.parameters.extract("postId") as Int - let commentId = try request.parameters.extract("commentId") as Int + let userId = try request.parameters.extract("userId") as Int + let postId = try request.parameters.extract("postId") as Int + let commentId = try request.parameters.extract("commentId") as Int - return "You requested comment #\(commentId) for post #\(postId) for user #\(userId)" + return "You requested comment #\(commentId) for post #\(postId) for user #\(userId)" } ``` +> Property `request.parameters` is used to extract parameters encoded in the URI _path_ (for example, `/v1/users/1` has a parameter `:userId` equal to `"1"`). In case of parameters passed as a part of a _query_ (e.g. `/v1/search-user?userId=1`), the `request.data` should be used (e.g. `let userId = request.data["userId"]?.string`). + Request parameters can be accessed either as a dictionary or using the `extract` syntax which throws instead of returning an optional. ### Groups