19 | {% if site.github.is_project_page %}
20 | View on GitHub
21 | {% endif %}
22 | {% if site.show_downloads %}
23 | Download .zip
24 | Download .tar.gz
25 | {% endif %}
26 |
27 |
28 |
29 | {{ content }}
30 |
31 |
37 |
38 |
39 | {% if site.google_analytics %}
40 |
48 | {% endif %}
49 |
50 |
69 |
70 |
--------------------------------------------------------------------------------
/android-chrome-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twof/VaporNation/99353024b48a22494d9b8c85b1dffa061144cf1d/android-chrome-192x192.png
--------------------------------------------------------------------------------
/android-chrome-384x384.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twof/VaporNation/99353024b48a22494d9b8c85b1dffa061144cf1d/android-chrome-384x384.png
--------------------------------------------------------------------------------
/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twof/VaporNation/99353024b48a22494d9b8c85b1dffa061144cf1d/apple-touch-icon.png
--------------------------------------------------------------------------------
/assets/css/style.scss:
--------------------------------------------------------------------------------
1 | ---
2 | ---
3 |
4 | @import "{{ site.theme }}";
5 |
6 | .newsLetterSignup {
7 | color: black;
8 | }
9 |
--------------------------------------------------------------------------------
/browserconfig.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | #da532c
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twof/VaporNation/99353024b48a22494d9b8c85b1dffa061144cf1d/favicon-16x16.png
--------------------------------------------------------------------------------
/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twof/VaporNation/99353024b48a22494d9b8c85b1dffa061144cf1d/favicon-32x32.png
--------------------------------------------------------------------------------
/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twof/VaporNation/99353024b48a22494d9b8c85b1dffa061144cf1d/favicon.ico
--------------------------------------------------------------------------------
/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | ---
4 | * [Week 0](https://twof.github.io/VaporNation/week0-18-01-21)
5 | * [Week 1](https://twof.github.io/VaporNation/week1-18-01-29)
6 | * [Week 2](https://twof.github.io/VaporNation/week2-18-02-05)
7 | * [Week 3](https://twof.github.io/VaporNation/week3-18-02-12)
8 | * [Week 4](https://twof.github.io/VaporNation/week4-18-02-19)
9 | * [Week 5](https://twof.github.io/VaporNation/week5-18-02-26)
10 | * [Week 6](https://twof.github.io/VaporNation/week6-18-03-05)
11 | * [Week 7](https://twof.github.io/VaporNation/week7-18-03-12)
12 | * [Week 14](https://twof.github.io/VaporNation/week14-18-05-03)
13 | * [Week 15](https://twof.github.io/VaporNation/week15-18-05-11)
14 | * [Week 16](https://twof.github.io/VaporNation/week16-18-05-18)
15 | * [Week 17](https://twof.github.io/VaporNation/week17-18-05-25)
16 | * [Week 18](https://twof.github.io/VaporNation/week18-18-06-02)
17 | * [Week 19](https://twof.github.io/VaporNation/week19-18-06-08)
18 | * [Week 20](https://twof.github.io/VaporNation/week20-18-06-15)
19 | * [Week 21](https://twof.github.io/VaporNation/week21-18-06-22)
20 | * [Week 22](https://twof.github.io/VaporNation/week22-18-06-29)
21 | * [Week 23](https://twof.github.io/VaporNation/week23-18-07-06)
22 |
--------------------------------------------------------------------------------
/mstile-150x150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twof/VaporNation/99353024b48a22494d9b8c85b1dffa061144cf1d/mstile-150x150.png
--------------------------------------------------------------------------------
/safari-pinned-tab.svg:
--------------------------------------------------------------------------------
1 |
2 |
4 |
387 |
--------------------------------------------------------------------------------
/site.webmanifest:
--------------------------------------------------------------------------------
1 | {
2 | "name": "",
3 | "short_name": "",
4 | "icons": [
5 | {
6 | "src": "/android-chrome-192x192.png",
7 | "sizes": "192x192",
8 | "type": "image/png"
9 | },
10 | {
11 | "src": "/android-chrome-384x384.png",
12 | "sizes": "384x384",
13 | "type": "image/png"
14 | }
15 | ],
16 | "theme_color": "#ffffff",
17 | "background_color": "#ffffff",
18 | "display": "standalone"
19 | }
20 |
--------------------------------------------------------------------------------
/week0-18-01-21.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | ---
4 | # Week 0
5 |
6 | The format is heavily inspired by [Swift Weekly (RIP)](https://swiftweekly.github.io/issue-98/) and [Swift Web Weekly](http://swiftwebweekly.com/) to a lesser extent.
7 |
8 | ## Discussions
9 |
10 | Listing discussions will hopefully attract folks who are current heavy Vapor users or have a lot of server-side experience in general.
11 |
12 | ### Naming changes to `Request`
13 |
14 | This week in discussion is the proposal to rename `Request` to `RequestContext` in order to differentiate between `HTTPRequest` and `Request` which in addition to an `HTTPRequest` (`req.http`) also contains `Container`s and an `EventLoop`.
15 |
16 | [vapor/vapor#1443](https://github.com/vapor/vapor/issues/1443)
17 |
18 | ### Maximum Body Size
19 | This discussion is around the question of whether or not small request bodies should be treated differently than larger request bodies; specifically if small ones should be accessed synchronously. After a [pull request to support streaming bodies](https://github.com/vapor/vapor/pull/1435) the week before, all content access was required to be treated as asynchronous, but the changed also increased complexity of user code.
20 |
21 | [vapor/engine#205](https://github.com/vapor/engine/issues/205)
22 |
23 | ### Case Sensitive Routing
24 |
25 | Should `/helloWorld` and `/helloworld` be sent to the same route? Should one throw `404`? Discuss!
26 |
27 | [vapor/vapor#1196](https://github.com/vapor/vapor/issues/1196)
28 |
29 | ## New Features
30 | New features are listed after PRs are merged. New features are specifically user facing changes, and should come with a short description and a minimal code sample that displays usage. Small userfacing tweaks will not be listed.
31 |
32 | ### Fluent Cache
33 |
34 | You can now use your Fluent database as a `KeyedCache`. Any struct/class that conforms to Codable can be stored (data is JSON-encoded).
35 |
36 | Setup looks like ths:
37 |
38 | ```swift
39 | /// Register providers
40 | try services.register(FluentSQLiteProvider())
41 |
42 | ...
43 |
44 | /// Setup a simple in-memory SQLite database
45 | var databases = DatabaseConfig()
46 | let sqlite = try SQLiteDatabase(storage: .memory)
47 | databases.add(database: sqlite, as: .sqlite)
48 | services.register(databases)
49 |
50 | /// Configure migrations
51 | var migrations = MigrationConfig()
52 | /// Ensure SQLiteCache has the tables it will need
53 | migrations.prepareCache(for: .sqlite)
54 | services.register(migrations)
55 | ```
56 |
57 | Usage like this:
58 |
59 | ```swift
60 | let cache = try req.make(KeyedCache.self)
61 | cache.get(Foo.self, forKey: "my-foo") // Future
62 | ```
63 |
64 | [vapor/fluent#358](https://github.com/vapor/fluent/pull/358)
65 |
66 | ### PostgreSQL Support for JSON/JSONB and Arrays
67 |
68 | With this update, you can now store arbitrarily structured data in your PostgreSQL database.
69 |
70 | ```swift
71 | final class User: PostgreSQLModel, Migration {
72 | static let idKey = \User.id
73 | var id: Int?
74 | var name: String
75 | var age: Int?
76 | var favoriteColors: [String]
77 | var pet: Pet
78 | var dict: [String: String]
79 |
80 | init(id: Int? = nil, name: String, pet: Pet) {
81 | self.favoriteColors = []
82 | self.dict = [:]
83 | self.id = id
84 | self.name = name
85 | self.pet = pet
86 | }
87 | }
88 |
89 | struct Pet: PostgreSQLJSONType {
90 | var name: String
91 | }
92 | ```
93 |
94 | The above Swift class and struct result in the following schema:
95 |
96 | ```sql
97 | CREATE TABLE "users" (
98 | "id" BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
99 | "name" TEXT NOT NULL,
100 | "age" BIGINT,
101 | "favoriteColors" TEXT[] NOT NULL,
102 | "pet" JSONB NOT NULL,
103 | "dict" JSONB NOT NULL
104 | )
105 | ```
106 |
107 | [vapor/postgresql#2](https://github.com/vapor/postgresql/issues/2)
108 | [vapor/fluent-postgresql#4](https://github.com/vapor/fluent-postgresql/pull/4)
109 |
110 | ### KeyedCache Sessions
111 |
112 | This update allows you to use any `KeyedCache` conformer to power your `SessionsMiddleware`. Just make sure to
113 | configure `KeyedCacheSessions` as your preferred `Sessions` conformer, and Vapor will automatically create an
114 | instance of your preferred `KeyedCache`.
115 |
116 | [vapor/vapor#1444](https://github.com/vapor/vapor/pull/1444)
117 |
118 | ### Client Now Supports String URIs
119 |
120 | This welcome update allows you to pass simple `String`s as the `URI` for requests made to `Client` (i.e., `EngineClient`).
121 |
122 | ```swift
123 | req.make(Client.self).get("https://www.google.com")
124 | ```
125 |
126 | Previously, only `URI`s or literal strings (non-interpolated) could be used.
127 |
128 | [vapor/vapor#1446](https://github.com/vapor/vapor/pull/1446)
129 |
130 | ### Vapor 3 Compiles With Swift 4.1
131 |
132 | XCode 9.3 is now in public beta and ships with Swift 4.1, which includes conditional conformance. Conditional conformance is sure to eliminate significant parts of the Vapor codebase. Yay! You can read more about the changes coming with Swift 4.1 [here](https://github.com/apple/swift/blob/master/CHANGELOG.md).
133 |
134 | Note: You don't actually need Xcode 9.3 as you can also [install Swift 4.1 toolchains to Xcode 9.2](https://gist.github.com/tanner0101/cdb77c7f58d53af2ba2da5d39415389a).
135 |
136 | [vapor/vapor#1384](https://github.com/vapor/vapor/pull/1384)
137 |
138 | ## Under The Hood
139 |
140 | Under the hood changes are things like refactors or optimizations that do not add any significant userfacing features. Everything in this section should come with a short description, but it can be as simple as "Optimizes X.
141 |
142 | ### Stream Refactor
143 |
144 | Simplifies Async streams. This has potential to simplify quite a bit of our async code.
145 |
146 | This change removes the ability to request an arbitrary number of output from a connected upstream.
147 | Now, only one output request can be outstanding at a time. This allows for the protocol to be implemented
148 | by a simple `Promise` (previously used `ConnectionContext` has been deleted).
149 |
150 | This change should better match the semantics of co-routine style streams as well (thinking ahead to future Swift versions).
151 |
152 | [vapor/async#52](https://github.com/vapor/async/pull/52)
153 |
154 | ### Better CodingKey Decoding
155 |
156 | Significantly improves handling of key-string decoding by using conditional conformances (where available) and providing much better error messages if a type doesn't conform to `KeyStringDecodable` (most often `enum`s being used as database fields in models).
157 |
158 | [vapor/core#86](https://github.com/vapor/core/pull/86)
159 |
160 | ### Eventloop and Future Optimizations
161 |
162 | This PR adds some optimizations to the EventLoop and Future implementations.
163 |
164 | - EventLoop: Minimize how many times an EventSource can be suspended/resumed by adding some internal state.
165 | - Future: Minimize array appends by optimizing the case where a Future only has one awaiter.
166 |
167 | [vapor/async#57](https://github.com/vapor/async/pull/57)
168 |
169 | ## Community Contributions
170 |
171 | In this section I'd like to highlight some community PRs that got merged this week and inspire others to submit their first PR to Vapor. Proving that you don't have to know everything to write a small bugfix 😀
172 |
173 | ### Fix parsing WebSocket close frame length
174 |
175 | Props to @tiwoc for their contribution! They fixed a websocket bug and ensured reliability in only 5 lines of code!
176 |
177 | [vapor/engine#203](https://github.com/vapor/engine/pull/203)
178 |
179 | ## Starter Tasks
180 | This section consists of tasks that would be good for beginners to tackle. They do not necessarily have to be issues in the Vapor codebase itself, but they should contribute in some way to Vapor.
181 |
182 | ### Swift Is Broken in Techempower's Framework Benchmarks
183 |
184 | It would be awesome to for Vapor to compete in [TechEmpower's Framework Benchmarks](http://www.techempower.com/benchmarks/), however, their installation of Swift is both broken and a version behind. Their [instructions](https://frameworkbenchmarks.readthedocs.io/en/latest/Codebase/Framework-Files/) will be helpful along with the Vapor/Swift on Unbuntu tutorial below. Drop into the #beta channel if you decide to give this issue a go and you have questions 😀
185 |
186 | [TechEmpower/FrameworkBenchmarks#3181](https://github.com/TechEmpower/FrameworkBenchmarks/issues/3181)
187 |
188 | ## Benchmarks
189 | This is where Vapor gets to flex a little 💪 It'll be nice to let readers track improvements and achievement.
190 |
191 | ### Vapor's engine nearly matches Go's FastHTTP
192 |
193 | Joannis benchmarked Vapor/Engine at 111,324.52 requests/second and FastHTTP at 118,479.28 requests/second. Nice! 🏎🏎🏎
194 |
195 | [vapor/engine#211](https://github.com/vapor/engine/pull/211#issuecomment-360758758)
196 |
197 | ## Tutorials
198 |
199 | This is where any newly written tutorials pertaining to Vapor will be listed. I'm hoping doing so will give the content creators a little bump in traffic
200 |
201 | ### Vapor 3 with Docker
202 |
203 | In this tutorial learn how to run Vapor 3 in Docker! Why? One of the best reasons right now is that Swift (and Vapor) often behaves differently on Linux than on macOS, so being able to locally test your code in a Linux container is much faster than pushing to Heroku every time you need to test something. 10 minute build times anyone?
204 |
205 | [bygri.github.io/2018/01/25/vapor-3-with-docker.html](https://bygri.github.io/2018/01/25/vapor-3-with-docker.html)
206 |
207 | ### How to Install Swift and Vapor on Ubuntu
208 |
209 | In this guide, you'll install Swift and Vapor on Ubuntu 16.04. Then you'll test your setup by creating a simple web application using one of Vapor's templates.
210 |
211 | [digitalocean.com/community/tutorials/how-to-install-swift-and-vapor-on-ubuntu-16-04](https://www.digitalocean.com/community/tutorials/how-to-install-swift-and-vapor-on-ubuntu-16-04)
212 |
213 | ## Built With Vapor
214 |
215 | To showcase what people are doing with Vapor and to inspire others to create and share.
216 |
217 | ### Leaderboard App
218 |
219 | Keep track of your office games.
220 |
221 | [leaderboardapp.com](https://leaderboardapp.com)
222 |
223 | ## Micro Tutorial
224 |
225 | I think it'd be fun to include a tiny tutorial at the end. Ideally it'd just be a code snippet that showcases some Vapor syntax that the devs are proud of along with a short description of what it does.
226 |
227 | Very appropriately, the simplest possible Vapor 3 Hello World:
228 |
229 | ```swift
230 | import Vapor
231 |
232 | let app = try Application()
233 |
234 | let router = try app.make(Router.self)
235 | router.get("hello") { req -> String in
236 | return "Hello, world!"
237 | }
238 |
239 | try app.run()
240 | ```
241 |
242 | ***
243 |
244 | ## Credits:
245 | [@gwynne](https://github.com/gwynne)
246 | [@calebkleveter](https://github.com/calebkleveter)
247 | [@tanner0101](https://github.com/tanner0101)
248 | [@twof](https://github.com/twof)
249 |
--------------------------------------------------------------------------------
/week1-18-01-29.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | ---
4 | # Week 1
5 |
6 | Before we get into it, I'd like to give a shout out to [@0xTim](https://github.com/0xTim) for writing an [awesome article](https://geeks.brokenhands.io/blog/posts/whats-new-in-vapor-3/) on the high level changes between Vapor 2 and Vapor 3. If that sounds like your jam, give it a read! They'll be keeping it up to date all the way up to the official release of Vapor 3 so feel free to check back every once in a while.
7 |
8 | ## News
9 |
10 | ### Vapor 3 Release Schedule Announced!
11 | We're looking at the first tagged Beta release on February 9th, the first stable release on February 23rd, and Vapor 3.0 sometime in mid March to coincide with the Swift 4.1 release. In addition, Vapor 3 relies on the [Swift 4.1 beta](https://swift.org/download/#snapshots) as of this week, so go get it installed!
12 |
13 | [https://medium.com/@qutheory/vapor-3-release-schedule-1179bb080ca4](https://medium.com/@qutheory/vapor-3-release-schedule-1179bb080ca4)
14 |
15 | ## New Features
16 |
17 | ### CHTTP Refactor
18 | - Performance was optimized for all HTTP requests. In addition, convenience accessors like `req.headers` are now gone in favor of more explicit calls to `req.http.*`. So if you were using `req.headers`, that would now be `req.http.headers`.
19 | - Calls to `print(...)` or `debugPrint(...)` where a `Request` or `Response` are given now provide better information.
20 |
21 | [vapor/vapor#1458](https://github.com/vapor/vapor/pull/1458)
22 |
23 | ### PostgreSQL Support for DB Usernames and Passwords
24 | Previously, you were just fine as long as you were using the default PostgreSQL setup, but if you wanted to password protect your DB, you were out of luck. Well that is no more! Protect away my friends.
25 |
26 | [vapor/postgresql#9](https://github.com/vapor/postgresql/issues/9)
27 |
28 | ## Under The Hood
29 |
30 | ### CHTTP Refactor
31 | - Resulted in a more than 20% increase in the number of requests per second Vapor's engine can handle.
32 |
33 | [vapor/engine#211](https://github.com/vapor/engine/pull/211)
34 |
35 | ### SocketSink and SocketSource Refactor
36 | - Moved the TCP socket streaming classes out of the `Async` package and into `Sockets`, allowing necessary behavioral divergence for TLS-enabled sockets. It's also conceptually cleaner to have the sockets-specific code in the `Sockets` package.
37 |
38 | [vapor/sockets#157](https://github.com/vapor/sockets/pull/157)
39 |
40 | ## Community Contributions
41 | Community contributions is where we take the time to highlight community members who saw an issue and put in the work to fix it. Check out what these folks are doing, and maybe get yourself on this list next week! 😀
42 |
43 | ### Changed query comparison operators paths to `KeyPath`
44 | [@calebkleveter](https://github.com/calebkleveter) enabled Vapor users to use both constant and variable model properties in query filter comparisons; previously only non-constant properties were usable in this context. (3 Lines of Code)
45 |
46 | [vapor/fluent#360](https://github.com/vapor/fluent/pull/360)
47 |
48 | ### Allows users to access password protected DBs with `PostgreSQLDatabaseConfig`
49 | While the core Vapor team put in the work to access passworded DBs with the PostgreSQL driver, [@MihaelIsaev](https://github.com/MihaelIsaev) drove it home by exposing that functionality to Vapor's users. (5 Lines of Code)
50 |
51 | [vapor/postgresql#12](https://github.com/vapor/postgresql/pull/12)
52 |
53 | ## Benchmarks
54 |
55 | ### Vapor Beats Go's Gin and Node's Express in Requests per Second
56 | It's an unofficial benchmark run by [@tanner0101](https://github.com/tanner0101), but here are the numbers!
57 | - ~150k RPS Pure TCP echo server (hard ceiling)
58 | - 140k RPS Go/FastHTTP (not a web framework)
59 | - 131k RPS Swift/Vapor
60 | - 99k RPS Go/Gin
61 | - 60k RPS Node/Express
62 |
63 | That's over 91% efficiency we're seeing from Vapor! Nice! Huge gains were made via lazy header parsing. Since most of the time between 0 and 1 headers need to be accessed, header data is copied into a buffer and retrieved only when requested. Another big gain resulted from utilizing [Copy on Write wrappers](https://marcosantadev.com/copy-write-swift-value-types/), which let you fine tune when data actually gets copied. To quote Tanner,
64 |
65 | >Our `HTTPRequest` is a struct, but since the headers are in a CoW wrapper, the request can be copied and mutated as much as desired without copying the headers. The headers will only copy if they detect belonging to _two_ distinct HTTPRequests and one of them is trying to mutate their contents. If no one tries to mutate the headers, it's possible you could have hundreds of HTTP requests all sharing the same header storage in memory. This makes Swift really special because it's a case where being higher level than C can actually yield _more_ performance than is realistically possible in C.
66 |
67 | That's pretty awesome if you ask me 🏁
68 |
69 | ## Tutorials
70 |
71 | ### Routing in Vapor 3, Part 1: Basic Routing
72 | Routing is at the heart of web frameworks, and it's easy with Vapor. This tutorial will teach you what you need to know to get started.
73 |
74 | [https://www.vaporforums.io/thread/34](https://www.vaporforums.io/thread/34)
75 |
76 | ### How to implement Image-Upload [Vapor 2]
77 | In this tutorial, you’ll learn how to upload an image for a user and save it to the disk as well as how to serve it back as a profile picture. This will be core for anyone wanting to set up a site with user generated content.
78 |
79 | [https://medium.com/@martinlasek/tutorial-how-to-implement-image-upload-f8ef5a2af869](https://medium.com/@martinlasek/tutorial-how-to-implement-image-upload-f8ef5a2af869)
80 |
81 | ## Microtutorial
82 | This week we're highlighting Vapor's content API which you'll be using in the vast majority of your projects. By taking advantage of Swift's Codable protocol, Vapor is able to automatically map JSON to Swift objects and back again. Doing so affords you the type safety you not only deserve, but need right now.
83 |
84 | In the below example, if you sent a `POST` request with the body
85 | ```json
86 | {
87 | "email":"user@vapor.codes",
88 | "password":"hunter2"
89 | }
90 | ```
91 | Vapor would automatically provide a `LoginRequest` instance with those values!
92 |
93 | ```swift
94 | struct LoginRequest: Content {
95 | var email: String
96 | var password: String
97 | }
98 |
99 | router.post("login") { req -> Future in
100 | return try req.content.decode(LoginRequest.self).map(to: Response.self) { loginRequest in
101 | print(loginRequest.email) // user@vapor.codes
102 | print(loginRequest.password) // don't look!
103 | return req.makeResponse()
104 | }
105 | }
106 |
107 | ```
108 |
109 | ***
110 |
111 | ## Credits:
112 | [@twof](https://github.com/twof)
113 | [@gwynne](https://github.com/gwynne)
114 | [@Cellane](https://github.com/Cellane)
115 | [@calebkleveter](https://github.com/calebkleveter)
116 |
--------------------------------------------------------------------------------
/week14-18-05-03.md:
--------------------------------------------------------------------------------
1 | # Week 14
2 |
3 | ## News
4 | We are back! A whole lot going on recently, most importantly Vapor 3 is tagged 🎉🎉🎉.
5 |
6 | ## New Features
7 |
8 | ### Add ContentTag
9 | Additional overloads to `req.content.encode(...)` were added. These allow for custom coders to be passed in as needed.
10 |
11 | [vapor/vapor#1648](https://github.com/vapor/vapor/issues/1648)
12 |
13 | ### Add support for parsing header value params without =
14 |
15 | Useful for parsing cookies
16 |
17 | [vapor/core#131](https://github.com/vapor/core/pull/131)
18 |
19 | ### Add types for working with MIME
20 | Added `MediaType`, `HeaderValue`, `CaseInsensitiveString` and `File` for content-type.
21 |
22 | [vapor/core#127](https://github.com/vapor/core/pull/127)
23 |
24 | ### Add 'NestedData' protocol
25 | Adds `NestedData`: a data structure containing arbitrarily nested arrays and dictionaries
26 |
27 | [vapor/core#126](https://github.com/vapor/core/pull/126)
28 |
29 | ### Add Thread.async(_:) method
30 | Runs the supplied closure on a new thread. Calls `Thread.detachNewThread(_:)`
31 |
32 | [vapor/core#121](https://github.com/vapor/core/pull/121)
33 |
34 | ### Adds Data Coders
35 | A type capable of decoding `Decodable`types from `Data`.
36 |
37 | [vapor/core#108](https://github.com/vapor/core/pull/108)
38 |
39 | ### Add a new future debug
40 | Add debugging to future creation
41 |
42 | [vapor/core#101](https://github.com/vapor/core/pull/101)
43 |
44 | ### Add a migration function name
45 | Adds the ability to name migrations and to create migrations easily by just adding a closure
46 |
47 | [vapor/fluent#428](https://github.com/vapor/fluent/pull/428)
48 |
49 | ### Adds a support for the deprecated flag
50 | Adds support for the command's flag with the form `--option=value`
51 |
52 | [vapor/console#63](https://github.com/vapor/console/pull/63)
53 |
54 | ## NIO
55 | ### Optimize for HTTP/1.1 and HTTP/1.0 responses
56 | Motivation:
57 |
58 | Its very likely that the response will be HTTP/1.1 or HTTP/1.0 so we can optimize for it by minimizing the buffer.write(...) calls.
59 | Beside this we should also change the pattern of *.write(into: inout ByteBuffer) to extension on ByteBuffer itself.
60 |
61 | Modifications:
62 |
63 | - Optimize for HTTP/1.0 and 1.1
64 | - Use extensions on ByteBuffer
65 |
66 | Result:
67 |
68 | Faster and more clean code.
69 |
70 | [apple/swift-nio#300](https://github.com/apple/swift-nio/pull/300)
71 |
72 | ### Add support for automatic HTTP error reporting
73 | Motivation:
74 |
75 | Currently the HTTP decoders can throw errors, but they will be ignored
76 | and lead to a simple EOF. That's not ideal: in most cases we should make
77 | a best-effort attempt to send a 4XX error code before we shut the client
78 | down.
79 |
80 | Modifications:
81 |
82 | Provided a new ChannelHandler that generates 400 errors when the HTTP
83 | decoder fails.
84 | Added a flag to automatically add that handler to the channel pipeline.
85 | Added the handler to the HTTP sample server.
86 | Enabled integration test 12.
87 |
88 | Result:
89 |
90 | Easier error handling for HTTP servers.
91 |
92 | [apple/swift-nio#268](https://github.com/apple/swift-nio/pull/268)
93 |
94 | ## Community Contributions
95 | ### Ruby-on-Rails benchmark
96 |
97 | [@grundoon](https://github.com/grundoon)
98 |
99 | [vapor/benchmarks#1](https://github.com/vapor/benchmarks/pull/1)
100 |
101 | ### Added guard for invalid cost
102 | Related to [vapor/crypto#57](https://github.com/vapor/crypto/pull/57)
103 |
104 | [@bre7](https://github.com/bre7)
105 |
106 | [vapor/crypto#58](https://github.com/vapor/crypto/pull/58)
107 |
108 | ### Add the required imports for the sample user model
109 | [@natebird](https://github.com/natebird)
110 |
111 | [vapor/documentation#308](https://github.com/vapor/documentation/pull/308)
112 |
113 | ### Fix a memory leak in QueueHandler
114 | [@MrMage](https://github.com/MrMage)
115 |
116 | [vapor/core#134](https://github.com/vapor/core/pull/134)
117 |
118 | ### Follow API change in Crypto
119 | [@t-ae](https://github.com/t-ae)
120 |
121 | [vapor/core#167](https://github.com/vapor/mysql/pull/167)
122 |
123 | ### Add extra HTTPHeaders to WebSocket client
124 | [@pvels](https://github.com/pvels)
125 |
126 | [vapor/websocket#2](https://github.com/vapor/websocket/pull/2)
127 |
128 | ### Adds git hash capability to vapor cloud
129 | Adds `vapor cloud git-hash`
130 |
131 | [@joscdk](https://github.com/joscdk)
132 |
133 | [vapor/toolbox#221](https://github.com/vapor/toolbox/pull/221)
134 |
135 | ### Adding Host header to requests
136 | [@givip](https://github.com/givip)
137 |
138 | [vapor/http#269](https://github.com/vapor/http/pull/269)
139 |
140 | ### Fixed FormURLEncoded Decoder Media Type Check
141 | [@calebkleveter](https://github.com/calebkleveter)
142 |
143 | [vapor/http#266](https://github.com/vapor/http/pull/266)
144 |
145 | ### Adds TLS to HTTPClient
146 | [@vkill](https://github.com/vkill)
147 |
148 | [vapor/http#260](https://github.com/vapor/http/pull/260)
149 |
150 | ### Fix Timestampable when the models are structs
151 | [ccrazy88](https://github.com/ccrazy88)
152 |
153 | [vapor/fluent#445](https://github.com/vapor/fluent/pull/445)
154 |
155 | ### Fix MySQL transaction support
156 | [@jseibert](https://github.com/jseibert)
157 |
158 | [vapor/fluent-mysql#100](https://github.com/vapor/fluent-mysql/pull/100)
159 |
160 | ### Release pooled conn when catch for requestPooledConnection
161 | [@vkill](https://github.com/vkill)
162 |
163 | [vapor/database-kit#25](https://github.com/vapor/database-kit/pull/25)
164 |
165 | ### Add url config to redis
166 | [@pedantix](https://github.com/pedantix)
167 |
168 | [vapor/redis#99](https://github.com/vapor/redis/pull/99)
169 |
170 | ### Fix synchronization issue in QueueHandler
171 | [@jseibert](https://github.com/jseibert)
172 |
173 | [vapor/core#118](https://github.com/vapor/core/pull/118)
174 |
175 | ### Fix infinite recursion in MySQLCharacterSet.description
176 | [@jseibert](https://github.com/jseibert)
177 |
178 | [vapor/mysql#155](https://github.com/vapor/mysql/pull/155)
179 |
180 | ### Fixed issue with EventLoop assert
181 | When sending asynchronously a ByteBuffer in a WebSocket, it fails since the current execution is not in the same EventLoop as the WebSocket handler.
182 |
183 | [@kikettas](https://github.com/kikettas)
184 |
185 | [apor/http#254](https://github.com/vapor/http/pull/254)
186 |
187 | ### Fix Cloud.yml
188 | Fix the ```cloud.yml``` file so it uses the latest commands required to run an app
189 |
190 | [@0xTim](https://github.com/0xTim)
191 |
192 | [vapor/api-template#55](https://github.com/vapor/api-template/pull/55)
193 |
194 | ### Export Async to avoid an import when conforming to Fluent protocols
195 | [@0xTim](https://github.com/0xTim)
196 |
197 | [vapor/fluent#417](https://github.com/vapor/fluent/pull/417)
198 |
199 | ### Default port in MySQLDatabaseConfig to 3306
200 | [@0xTim](https://github.com/0xTim)
201 |
202 | [vapor/mysql#146](https://github.com/vapor/mysql/pull/146)
203 |
204 | ### Fix MySQL index syntax
205 | [@jseibert](https://github.com/jseibert)
206 |
207 | [vapor/fluent-mysql#88](https://github.com/vapor/fluent-mysql/pull/88)
208 |
209 |
210 | ## Tagged releases
211 | - [HTTP 3.0.3](https://github.com/vapor/http/releases/tag/3.0.3)
212 | - [Fluent 3.0.0 RC 2.4.1](https://github.com/vapor/fluent/releases/tag/3.0.0-rc.2.4.1)
213 | - [Core 3.1.6](https://github.com/vapor/core/releases/tag/3.1.6)
214 | - [Crypto 3.1.1](https://github.com/vapor/crypto/releases/tag/3.1.1)
215 | - [Routing 3.0.1](https://github.com/vapor/routing/releases/tag/3.0.1)
216 | - [DatabaseKit 1.0.0](https://github.com/vapor/database-kit/releases/tag/1.0.0)
217 | - [SQL 1.0.0](https://github.com/vapor/sql/releases/tag/1.0.0)
218 | - [Console 3.0.1](https://github.com/vapor/console/releases/tag/3.0.1)
219 | - [Auth 2.0.0 RC 3.2](https://github.com/vapor/auth/releases/tag/2.0.0-rc.3.1)
220 | - [URL-Encoded Form 1.0.2](https://github.com/vapor/url-encoded-form/releases/tag/1.0.2)
221 | - [**Vapor 3.0.0**](https://github.com/vapor/vapor/releases/tag/3.0.0)
222 |
223 | ## Articles
224 | ### Long article on starting with Vapor for Laravel developers
225 | [Vapor for Laravel Developer](https://laravel-forge-menubar.com/articles/server-side-swift-for-laravel-developers-part-1)
226 |
227 | ### Sending multiple requests to different DBs using an array of Future
228 | Brought to you by Ralph Küepper
229 |
230 | [Vapor 3 Quick Case Study](https://www.skelpo.com/blog/vapor/vapor3-study/)
231 |
232 | ### Big list of tutorials (very good, huge shoutout to Mihaela)
233 | Brought to you by [@mihaelamj](https://github.com/mihaelamj)
234 |
235 | [Vapor 3 tutorials](https://mihaelamj.github.io/Vapor%20%203%20Tutorial/)
236 |
237 | ## Talks
238 | ### Tim Condon on Getting Started with Server Side Swift with Vapor@CODEMOBILE
239 |
240 | [Tim Condon at CODEMOBILE](https://www.youtube.com/watch?v=vXgOMX7hk9s)
241 |
242 | ### Kickstarting a project with Vapor 3 including CRUD operations
243 | Brought to you by Vina Ranti @Engineers.SG
244 |
245 | [Kickstart a project with Vapor 3](https://engineers.sg/video/vapor-3-preview-ios-dev-scout--2585)
246 |
247 | ## Writing Credits
248 | [@frivas](https://github.com/frivas)
249 |
250 | [@twof](https://github.com/twof)
251 |
--------------------------------------------------------------------------------
/week15-18-05-11.md:
--------------------------------------------------------------------------------
1 | # Week 15
2 |
3 | ## News
4 | Weekversary of Vapor 3 🎉🎉🎉. This week has been particularly interesting because of the amount of articles and tutorials the Vapor Community have contributed, Vapor now has its own thread at the [Swift Forums](https://forums.swift.org/c/related-projects/vapor), and most importantly, [Vapor 3.1](https://github.com/vapor/vapor/tree/3.1), yes, you read it right, Vapor's development team is restless already thinking on 3.1, awesome, is not it?
5 |
6 | ## New Features
7 |
8 | ### Add a non-variadic 'on' method to router
9 | Adds a non-variadic overload to ```router.on(...)``` to allow users to crete routes with arrays of parameters.
10 |
11 | The following snippet creates a `Route` at the provided path using an HTTP method. This route will return `"Hello, world"` to `GET` requests to `/hello/world`
12 |
13 | ```swift
14 | router.on(.GET, at: ["hello", "world"]) { req in
15 | return "Hello, world!"
16 | }
17 | ```
18 | You can use anything that conforms to `PathComponentsRepresentable` to create the path, including type constrained parameters.
19 |
20 | ```swift
21 | router.on(.GET, at: ["users", Int.parameter]) { req in
22 | let id = try req.parameters.next(Int.self)
23 | return "User #\(id)"
24 | }
25 | ```
26 | [vapor/vapor#1666](https://github.com/vapor/vapor/pull/1666)
27 |
28 | ### Model cleanup (more than that)
29 | - Cleanup the session persist protocols
30 | - Reduce usage of model to where necessary, adding behavior via extensions
31 | - Allows middlewares to be composed. Fixing [vapor/auth#34](https://github.com/vapor/auth/issues/34)
32 |
33 | [vapor/auth#39](https://github.com/vapor/auth/pull/39)
34 |
35 | ### Export Crypto in Authentication
36 | Export Crypto in ```Authentication``` so using things like the BCryptDigest for setting up a password verifier don't require an ```import Crypto```
37 |
38 | [vapor/auth#3](https://github.com/vapor/auth/pull/33)
39 |
40 | ## NIO
41 | ### Implement lazy selector registration
42 | **Motivation:**
43 |
44 | Previously we would eagerly register any fd with the selector
45 | (epoll/kqueue) which works well with kqueue. With epoll however, you'll
46 | get EPOLLHUP immediately if you supplied a socket that hasn't had
47 | connect/bind called on it.
48 | We got away with this because we took quite a bit of care to always make
49 | sure we call connect/bind pretty much immediately after we registered
50 | it. And crucially before we ever asked the selector to tell us about
51 | new events.
52 |
53 | **Modifications:**
54 |
55 | Made selector registration lazy (when we try activating the channel by calling connect/bind)
56 |
57 | **Result:**
58 |
59 | The user can now register and connect whenever they feel like it, fixes [apple/swift-nio#380](https://github.com/apple/swift-nio/issues/380)
60 |
61 | [apple/swift-nio#388](https://github.com/apple/swift-nio/pull/388)
62 |
63 | ### Add support for compiling and running NIO on Raspberry Pi 32-bit
64 | **Motivation:**
65 |
66 | Pretty much every developer in the world want to run MicroExpress applications on Raspberry Pi K8s clusters. The unfortunate precondition to that is getting NIO compiled for RaspberryPi. This PR makes it work.
67 |
68 | Thanks go to @chnmrc for providing a Swift 4.1 Raspi build, also available via a DockerHub: helje5/rpi-swift.
69 |
70 | **Modifications:**
71 |
72 | Two main changes:
73 |
74 | - Timestamps used to be stored as Int, this needs to be an explicit Int64 to provide the necessary value range for ns values
75 | - Some hardcoded pointers like 0xdeafbeef got mapped to Int values, but Int32 can't represent 0xdeadbeef. Needs to be UInt32 to capture the full deadness.
76 |
77 | **Result:**
78 |
79 | NIO compiles on Raspi 3, 32-bit Ubuntu. I tried the Echo Server, which seems to work, and also the HTTP sample Server, which also seems to work.
80 |
81 | P.S.: This should also allow you to run NIO on AppleWatch, which is 32-bit too.
82 |
83 | [apple/swift-nio#383](https://github.com/apple/swift-nio/pull/383)
84 |
85 | ## Community Contributions
86 | ### Add support for SSL-enabled Postgres servers
87 | - Adds an optional tlsConfiguration property to PostgreSQLDatabaseConfig. An attempt to open an SSL connection will only be made if this is non-nil
88 | - Adds the handshake required by PostgreSQL to check for SSL support
89 | - Uses NIOOpenSSL to add a OpenSSLClientHandler to the PostgresSQLConnection channel pipeline using the aforementioned tlsConfiguration property
90 | - Updates contributing_bootstrap.sh to spin up a second container using a new postgres-ssl Docker image, which creates a self-signed certificate to enable ssl on the Postgres container
91 | - Updates PostgreSQLConnectionTests to add a SSL connection test
92 |
93 | [vapor/postgresql#57](https://github.com/vapor/postgresql/pull/57)
94 |
95 | [vapor/postgresql#50](https://github.com/vapor/postgresql/pull/50)
96 |
97 | ### Rename makeResponse to response
98 | Renames ```req.makeResponse()``` to ```req.response()```
99 |
100 | [vapor/vapor#1672](https://github.com/vapor/vapor/pull/1672)
101 |
102 | [vapor/vapor#1671](https://github.com/vapor/vapor/pull/1671)
103 |
104 | ### Add Data responses and TypedDataResponse
105 | In some cases, you may want to just return raw `Data`
106 |
107 | [vapor/vapor#1657](https://github.com/vapor/vapor/pull/1657)
108 |
109 | ### Feature/infer auth type from context
110 | This PR allows
111 |
112 | ```swift
113 | secured.get("me") { request -> U in
114 | try request.requireAuthenticated()
115 | }
116 | ```
117 |
118 | instead of
119 |
120 | ```swift
121 | secured.get("me") { request -> U in
122 | try request.requireAuthenticated(U.self)
123 | }
124 | ```
125 | Same for the other authentication methods.
126 |
127 | [vapor/auth#37](https://github.com/vapor/auth/pull/37)
128 |
129 | ### Remove unnecessary Model conformance on Authenticatable
130 | `Authenticatable` types no longer need to be `Model`s
131 |
132 | [vapor/auth#35](https://github.com/vapor/auth/pull/35)
133 |
134 |
135 | ## Tagged releases
136 | - [Vapor 3.0.2](https://github.com/vapor/vapor/releases/tag/3.0.2)
137 | - [HTTP 3.0.5](https://github.com/vapor/http/releases/tag/3.0.5)
138 | - [Redis 3.0.0 RC 2.6](https://github.com/vapor/redis/releases/tag/3.0.0-rc.2.6)
139 | - [Auth 2.0.0 RC4](https://github.com/vapor/auth/releases/tag/2.0.0-rc.4)
140 | - [URL-Encoded Form 1.0.3](https://github.com/vapor/url-encoded-form/releases/tag/1.0.3)
141 | - [WebSocket 1.0.1](https://github.com/vapor/websocket/releases/tag/1.0.1)
142 | - [Crypto 3.1.2](https://github.com/vapor/crypto/releases/tag/3.1.2)
143 | - [PostgreSQL 1.0.0 RC 2.2](https://github.com/vapor/postgresql/releases/tag/1.0.0-rc.2.2)
144 |
145 | ## Articles
146 | ### Vapor 3.0.0 release article
147 | Brought to you by Vapor's development team
148 |
149 | [Vapor 3 Release](https://medium.com/@codevapor/vapor-3-0-0-released-8356fa619a5d)
150 |
151 | ### Server Side Swift frameworks comparison
152 | A bit old, given the fact everything changes really fast (Feb)
153 |
154 | [Server Side Swift Frameworks Comparison](https://www.netguru.co/codestories/server-side-swift-frameworks-comparison)
155 |
156 | ### Transforming from Vapor 2 to Vapor 3
157 | Brought to you by [@calebkleveter](https://github.com/calebkleveter)
158 |
159 | [From Vapor 2 to Vapor 3](https://www.skelpo.com/blog/vapor2-to-vapor3/)
160 |
161 | ### CRUD using Leaf
162 | Brought to you by [@MartinLasek](https://github.com/MartinLasek)
163 |
164 | [CRUD using Leaf](https://medium.com/@martinlasek/tutorial-how-to-write-crud-using-leaf-4d7dbae0979c)
165 |
166 | ### Routing and Fluent
167 | Brought to you by [@calebkleveter](https://github.com/calebkleveter)
168 |
169 | [Routing and Fluent](https://medium.com/@caleb.kleveter/diving-into-vapor-part-3-introduction-to-routing-and-fluent-in-vapor-3-221d209f1fec)
170 |
171 | ### Deploying Vapor 3 on Cloud Foundry
172 | Brought to you by [@idev4u](https://github.com/idev4u)
173 |
174 | [Deploying Vapor 3 in Cloud Foundry](https://medium.com/@Soulfected/vapor-3-on-cloud-foundry-e1861ef088d0?source=linkShare-33b4a6236f90-1525563379)
175 |
176 | ### HTTP Basic Auth with Vapor 3
177 | Brought to you by [@anapaix](https://github.com/JoeyBodnar)
178 |
179 | [HTTP Basic Auth with Vapor 3](https://www.vaporforums.io/thread/41)
180 |
181 | ### Getting started with Vapor 3 (Updated)
182 | Brought to you by [Paul Hudson](https://www.hackingwithswift.com/about)
183 |
184 | [Getting started with Vapor 3](https://www.hackingwithswift.com/articles/67/get-started-with-vapor-3-for-free)
185 |
186 | ## Want to know more or get inspired?
187 | - Check out what we are working on now. You might see something you can collaborate with [Issues](https://github.com/search?q=org%3Avapor+is%3Aissue+is%3Aopen+)
188 | - Check out more Vapor awesomeness [Awesome Vapor](https://github.com/Cellane/awesome-vapor)
189 | - Some more Vapor learning material [Vapor School](https://github.com/vaporberlin/vaporschool)
190 | - Vapor's Core team had published an early access book on Vapor through RW [here](https://store.raywenderlich.com/products/server-side-swift-with-vapor)
191 | - Paul Hudson had also updated his Server Side Swift with Vapor book [here](https://www.hackingwithswift.com/files/server-side-swift-vapor-edition-toc.pdf)
192 | - Also the RW's Vapor Video Course [Server Side Swift with Vapor - Video Course ](https://videos.raywenderlich.com/courses/115-server-side-swift-with-vapor/lessons/1)
193 | - Vapor Forum [Vapor Forum](http://vaporforums.io/)
194 | - Vapor Forum @swift.org [Vapor@swift.org](https://forums.swift.org/c/related-projects/vapor)
195 |
196 | ## Take action
197 |
198 | There are many ways you can contribute with Vapor
199 |
200 | - [Star the project in GitHub](https://github.com/vapor/vapor)
201 | - [Follow us on Twitter](https://twitter.com/codevapor)
202 | - [Follow us on Medium](https://medium.com/@codevapor)
203 | - [Become a backer](https://opencollective.com/vapor#backer)
204 | - [Become a sponsor](https://opencollective.com/vapor#sponsor)
205 | - [Come and talk to us](https://vapor.team)
206 |
207 |
208 | ## Writing Credits
209 | [@frivas](https://github.com/frivas)
210 |
211 | [@twof](https://github.com/twof)
212 |
--------------------------------------------------------------------------------
/week16-18-05-18.md:
--------------------------------------------------------------------------------
1 | # Week 16
2 |
3 | ## News
4 | Including a new section for Vapor communities around the world. If you are aware of one, please let us know, we would be glad to include a big shoutout to them. Lets bring more people to the community!.
5 |
6 | ## Community Contributions
7 | ### Add convenience protocol for enums
8 | Allow enums to be easily saved and restored from native types.
9 |
10 | [vapor/fluent-mysql#112](https://github.com/vapor/fluent-mysql/pull/112/files)
11 |
12 | ### Make `on()` public
13 | Fixed to allow creation of custom router methods
14 |
15 | [vapor/vapor#1679](https://github.com/vapor/vapor/pull/1679)
16 |
17 | ### Made Bool conforming to SQLiteDataConvertible
18 | Added conformance to the SQLiteDataConvertible to the Bool type
19 |
20 | [vapor/sqlite#36](https://github.com/vapor/sqlite/pull/36)
21 |
22 | ### Added quotation marks to the serialized header values
23 | Added missing quotes in values other than encoded file content. Check the discussion about this [here](https://github.com/vapor/multipart/issues/22). Fixes [vapor/multipart#22](https://github.com/vapor/multipart/issues/22)
24 |
25 | [vapor/core#144](https://github.com/vapor/core/pull/144)
26 |
27 |
28 | ## Tagged releases
29 | - [Crypto 3.1.7](https://github.com/vapor/crypto/releases/tag/3.1.7)
30 | - [PostgreSQL 1.0.0 RC 2.2.1](https://github.com/vapor/postgresql/releases/tag/1.0.0-rc.2.2.1)
31 | - [HTTP 3.0.6](https://github.com/vapor/http/releases/tag/3.0.6)
32 | - [Auth 2.0.0 RC 4.1](https://github.com/vapor/auth/releases/tag/2.0.0-rc.4.1)
33 | - [Vapor 3.0.3](https://github.com/vapor/vapor/releases/tag/3.0.3)
34 | - [Fluent MySQL 3.0.0 RC 2.5](https://github.com/vapor/fluent-mysql/releases/tag/3.0.0-rc.2.5)
35 |
36 | ## Articles
37 |
38 | ### Username/Password Authentication in Vapor 3
39 |
40 | Brought to you by [@anapaix](https://github.com/JoeyBodnar)
41 |
42 | [Username/Password Authentication with Vapor 3](https://www.vaporforums.io/thread/43)
43 |
44 | ### Token Authentication in Vapor 3
45 |
46 | Brought to you by [@anapaix](https://github.com/JoeyBodnar)
47 |
48 | [Token Authentication with Vapor 3](https://www.vaporforums.io/thread/44)
49 |
50 | ### How to get started with The Vapor 3 Framework
51 |
52 | Brought to you by [@steffendsommer](https://github.com/steffendsommer) and [@siemensikkema](https://github.com/siemensikkema)
53 |
54 | [Get started with Vapor 3](https://www.nodesagency.com/how-to-get-started-with-the-vapor-3-framework/)
55 |
56 | ### Playing Pokemon with Vapor 2
57 |
58 | Brought to you by [@sagnew](https://github.com/sagnew)
59 |
60 | [Playing Pokemon with Vapor](https://www.twilio.com/blog/2018/05/playing-pokemon-via-sms-in-swift-using-vapor-and-twilio.html)
61 |
62 | ### Developing and deploying Vapor 3 with Docker
63 |
64 | Brought to you by [@bygri](https://github.com/bygri)
65 |
66 | [Developing and deploying Vapor 3 with Docker](https://bygri.github.io/2018/05/14/developing-deploying-vapor-docker.html)
67 |
68 | ## Want to know more or get inspired?
69 | - Check out what we are working on now. You might see something you can collaborate with [Issues](https://github.com/search?q=org%3Avapor+is%3Aissue+is%3Aopen+)
70 | - Check out more Vapor awesomeness [Awesome Vapor](https://github.com/Cellane/awesome-vapor)
71 | - Some more Vapor learning material [Vapor School](https://github.com/vaporberlin/vaporschool)
72 | - Great resources from our community [Vapor Forum](https://www.vaporforums.io)
73 | - Vapor's Core team had published an early access book on Vapor through RW [here](https://store.raywenderlich.com/products/server-side-swift-with-vapor)
74 | - Paul Hudson had also updated his Server Side Swift with Vapor book [here](https://www.hackingwithswift.com/files/server-side-swift-vapor-edition-toc.pdf)
75 | - Also the RW's Vapor Video Course [Server Side Swift with Vapor - Video Course ](https://videos.raywenderlich.com/courses/115-server-side-swift-with-vapor/lessons/1)
76 | - Vapor Forum [Vapor Forum](http://vaporforums.io/)
77 | - Vapor Forum @swift.org [Vapor@swift.org](https://forums.swift.org/c/related-projects/vapor)
78 |
79 | ## Take action
80 |
81 | There are many ways you can contribute with Vapor
82 |
83 | - [Star the project in GitHub](https://github.com/vapor/vapor)
84 | - [Follow us on Twitter](https://twitter.com/codevapor)
85 | - [Follow us on Medium](https://medium.com/@codevapor)
86 | - [Become a backer](https://opencollective.com/vapor#backer)
87 | - [Become a sponsor](https://opencollective.com/vapor#sponsor)
88 | - [Come and talk to us](https://vapor.team)
89 |
90 | ## Vapor communities around the world
91 |
92 | [Vapor Berlin](http://vapor.berlin/#/)
93 |
94 | [Vapor London](https://www.meetup.com/VaporLondon/)
95 |
96 | ## Writing Credits
97 | [@frivas](https://github.com/frivas)
98 |
99 | [@twof](https://github.com/twof)
100 |
--------------------------------------------------------------------------------
/week17-18-05-25.md:
--------------------------------------------------------------------------------
1 | # Week 17
2 |
3 | ## News
4 |
5 | New version of SwiftNIO was released this week. Vapor running everywhere, this week on a Raspberry Pi!.
6 |
7 | ## New Features
8 |
9 | ### Process async execute
10 |
11 | Adds support for asynchronously execute a process. Asynchronously the supplied program in a new process. Stderr and stdout will be supplied to the output closure as it is received. The returned future will finish when the process has terminated.
12 |
13 | ```swift
14 | let status = try Process.asyncExecute("echo", "hi", on: ...) { output in
15 | print(output) // ProcessOutput (stderr or stdout)
16 | }.wait()
17 | print(result) // 0
18 | ```
19 |
20 | ## NIO
21 |
22 | ### Current version [1.7.1](https://github.com/apple/swift-nio/releases/tag/1.7.1)
23 |
24 | ### Rename numThreads to numberOfThreads parameter
25 |
26 | **Motivation:**
27 |
28 | We should be consistent with naming and also choose descriptive names.
29 |
30 | **Modifications:**
31 |
32 | Deprecate old init method that uses numThreads
33 | Add new init with numberOfThreads param name
34 | Everywhere use the new init
35 |
36 | **Result:**
37 |
38 | More consistent and descriptive naming. Fixes [#432](https://github.com/apple/swift-nio/issues/432).
39 |
40 | [apple/swift-nio#443](https://github.com/apple/swift-nio/pull/443)
41 |
42 | ### Make removeHandlers public
43 |
44 | **Motivation:**
45 |
46 | If ```ChannelPipeline.removeHandlers``` is internal it is extremely difficult
47 | to implement a correct ChannelCore.
48 |
49 | **Modifications:**
50 |
51 | Make ```ChannelPipeline.removeHandlers``` public.
52 |
53 | **Result:**
54 |
55 | Easier to implement ChannelCore.
56 |
57 | [apple/swift-nio#408](https://github.com/apple/swift-nio/pull/408)
58 |
59 | ### Do not allocate String to check if HTTP message is keep alive
60 |
61 | **Motivation:**
62 |
63 | We can check if a HTTP message is using keep alive without any allocation.
64 |
65 | **Modifications:**
66 |
67 | Directly act on the internal storage of HTTPHeaders to find out if keep alive is used or not.
68 |
69 | **Result:**
70 |
71 | Less allocations
72 |
73 | [apple/swift-nio#402](https://github.com/apple/swift-nio/pull/402)
74 |
75 | ### Channel quiescing support
76 |
77 | **Motivation:**
78 |
79 | In certain cases it's useful to quiesce a channel instead of just
80 | closing them immediately for example when receiving a signal.
81 |
82 | This lays the groundwork by introducing the ```ChannelShouldQuiesceUserEvent``` user event that when received can be interpreted by a ChannelHandler in a protocol & application specific way. Some protocols support tear down and that would be a good place to
83 | initiate the tear down.
84 |
85 | **Modifications:**
86 |
87 | - Introduce ```ChannelShouldQuiesceUserEvent```
88 | - Handle ```ChannelShouldQuiesceUserEvent``` in the ```AcceptHandler``` with closing the server socket
89 | - Handle ChannelShouldQuiesceUserEvent in the HTTPServerPipelineHandler by only handling a already in-flight request and then no longer accepting input
90 |
91 | **Result:**
92 |
93 | Handlers can now support quiescing
94 |
95 | [apple/swift-nio#399](https://github.com/apple/swift-nio/pull/399)
96 |
97 | ### Fix EventLoops that Bootstrap channel initialiser's call out on
98 |
99 | **Motivation:**
100 |
101 | Previously we were not running the (child/server)channelInitializers on the
102 | event loop associated to the Channel we're initialising. Almost all
103 | operations in there are pipeline modifications which are thread safe so
104 | it presumably wasn't a massive correctness issue. However it's very
105 | expensive to hop threads that often and it is also very unexpected. This
106 | addresses this issue.
107 |
108 | **Modifications:**
109 |
110 | Made all (child/server)channelInitializers run on the event loop that is
111 | associated to their Channel
112 |
113 | **Result:**
114 |
115 | - More correctness
116 | - Less unexpected behaviour
117 | - Also seems performance is impacted positively
118 |
119 | [apple/swift-nio#424](https://github.com/apple/swift-nio/pull/424)
120 |
121 | ## Community Contributions
122 |
123 | ### Fix numeric with leading zero fractional
124 |
125 | Numeric numbers with a fractional part with a leading zero (eg: 10.08) will be decoded from the database without the leading zero (ie: 10.80).
126 |
127 | This is a serious issue which results in corrupted numeric values.
128 |
129 | [vapor/postgresql#68](https://github.com/vapor/postgresql/pull/68)
130 |
131 | ## Tagged releases
132 |
133 | - [SQLite 3.0.0 RC 2.4](https://github.com/vapor/sqlite/releases/tag/3.0.0-rc.2.4)
134 | - [PostgreSQL 1.0.0 RC 2.2.2](https://github.com/vapor/postgresql/releases/tag/1.0.0-rc.2.2.2)
135 | - [Core 3.2.1](https://github.com/vapor/core/releases/tag/3.2.1)
136 | - [Bits 1.1.1](https://github.com/vapor-community/bits/releases/tag/1.1.1)
137 | - [BCrypt 1.1.1](https://github.com/vapor-community/bcrypt/releases/tag/1.1.1)
138 |
139 | ## Articles
140 |
141 | ### Working with Futures in Vapor 3
142 |
143 | Brought to you by [@anapaix](https://github.com/JoeyBodnar)
144 |
145 | [Working with Futures in Vapor 3](https://www.vaporforums.io/thread/45)
146 |
147 | ### Basic Authentication with Vapor 3
148 |
149 | Brought to you by [@kezzy](https://github.com/wmcginty)
150 |
151 | [Basic Authentication with Vapor 3](https://medium.com/rocket-fuel/basic-authentication-with-vapor-3-c074376256c3)
152 |
153 | ### Vapor 3 on Raspberry Pi
154 |
155 | Brought to you by [@cakinney](https://github.com/nilvalues)
156 |
157 | [Vapor 3 on Raspberry Pi](http://cakinney.com/code/2018/05/25/vapor3-on-rasperrypi.html)
158 |
159 | ## Want to know more or get inspired?
160 |
161 | - Check out what we are working on now. You might see something you can collaborate with [Issues](https://github.com/search?q=org%3Avapor+is%3Aissue+is%3Aopen+)
162 | - Check out more Vapor awesomeness [Awesome Vapor](https://github.com/Cellane/awesome-vapor)
163 | - Some more Vapor learning material [Vapor School](https://github.com/vaporberlin/vaporschool)
164 | - Great resources from our community [Vapor Forum](https://www.vaporforums.io)
165 | - Vapor's Core team had published an early access book on Vapor through RW [here](https://store.raywenderlich.com/products/server-side-swift-with-vapor)
166 | - Paul Hudson had also updated his Server Side Swift with Vapor book [here](https://www.hackingwithswift.com/files/server-side-swift-vapor-edition-toc.pdf)
167 | - Also the RW's Vapor Video Course [Server Side Swift with Vapor - Video Course ](https://videos.raywenderlich.com/courses/115-server-side-swift-with-vapor/lessons/1)
168 | - Vapor Forum [Vapor Forum](http://vaporforums.io/)
169 | - Vapor Forum @swift.org [Vapor@swift.org](https://forums.swift.org/c/related-projects/vapor)
170 |
171 | ## Take action
172 |
173 | There are many ways you can contribute with Vapor
174 |
175 | - [Star the project in GitHub](https://github.com/vapor/vapor)
176 | - [Follow us on Twitter](https://twitter.com/codevapor)
177 | - [Follow us on Medium](https://medium.com/@codevapor)
178 | - [Become a backer](https://opencollective.com/vapor#backer)
179 | - [Become a sponsor](https://opencollective.com/vapor#sponsor)
180 | - [Come and talk to us](https://vapor.team)
181 |
182 | ## Vapor communities around the world
183 |
184 | [Vapor Berlin](http://vapor.berlin/#/)
185 |
186 | [Vapor London](https://www.meetup.com/VaporLondon/)
187 |
188 | [Vapor Boston](https://www.meetup.com/VaporBoston/)
189 |
190 | ## Writing Credits
191 |
192 | [@frivas](https://github.com/frivas)
193 |
194 | [@twof](https://github.com/twof)
195 |
--------------------------------------------------------------------------------
/week18-18-06-02.md:
--------------------------------------------------------------------------------
1 | # Week 18
2 |
3 | ## News
4 |
5 | WWDC 18 is around the corner, lots of excitement for the upcoming news and with that in mind our communities are very active to gather us to watch it and enjoy and, of course, talk Vapor. A big shoutout to our Vapor communities in [Berlin](http://vapor.berlin/#/), [London](https://www.meetup.com/VaporLondon/) and [Tokyo](https://vapormeetuptokyo.connpass.com/event/88654/) for their plans. Please come and join us! It will be awesome!
6 |
7 | ## NIO
8 |
9 | ### Current version [1.7.1](https://github.com/apple/swift-nio/releases/tag/1.7.1)
10 |
11 | ## Community Contributions
12 |
13 | ### Add support for connecting to a Postgres database via Unix sockets
14 | Unix sockets have lower latency and higher throughput than TCP sockets. There are reports that indicate this to be particularly relevant when using Google Cloud SQL proxy.
15 |
16 | [vapor/postgresql#70](https://github.com/vapor/postgresql/pull/70)
17 |
18 | ### Add RSA encrypt and decrypt and adapt API
19 | Added encrypt and decrypt capabilities to the RSA class. Old APIs deprecated and new methods that take ```DigestAlgorithm``` as parameter.
20 |
21 | [vapor/crypto#64](https://github.com/vapor/crypto/pull/64)
22 |
23 | ### [Swift 4.2] ReflectionDecodable extension for CaseIterable enums
24 |
25 | [vapor/core#152](https://github.com/vapor/core/pull/152)
26 |
27 | ### Extended MySQLCapabilities with MariaDB specific capabilities
28 | Circumvented an assert in MySQLHandshakeV10.swift that failed with MariaDB 10.2 or later because of specific flags.
29 |
30 | [vapor/mysql#174](https://github.com/vapor/mysql/pull/174)
31 |
32 | ### Add support for loading and storing Decimal
33 | Add initializer to MySQLData for Decimal values and a MySQLDataConvertible extension on Decimal so it can be converted from and to string-form as expected by MYSQL_TYPE_{,NEW}DECIMAL.
34 |
35 | [vapor/mysql#171](https://github.com/vapor/mysql/pull/171)
36 |
37 | ### Support for Emoticons Unicode in MySQL
38 |
39 | [vapor/mysql#159](https://github.com/vapor/mysql/pull/159)
40 |
41 | ## Tagged releases
42 | ### Current Version [3.0.3](https://github.com/vapor/vapor/releases/tag/3.0.3)
43 |
44 | - [Crypto 3.2.0](https://github.com/vapor/crypto/releases/tag/3.2.0)
45 | - [Console 2.3.2](https://github.com/vapor/console/releases/tag/2.3.2)
46 | - [PostgreSQL 1.0.0 RC 2.2.3](https://github.com/vapor/postgresql/releases/tag/1.0.0-rc.2.2.3)
47 | - [Engine 2.2.5](https://github.com/vapor/http/releases/tag/2.2.5)
48 | - [HTTP 3.0.7](https://github.com/vapor/http/releases/tag/3.0.7)
49 | - [Core 3.2.2](https://github.com/vapor/core/releases/tag/3.2.2)
50 | - [JWT 3.0.0 RC 2.1.2](https://github.com/vapor/jwt/releases/tag/3.0.0-rc.2.1.2)
51 |
52 | ## Articles
53 |
54 | ### Write a CRUD API using JSON
55 |
56 | Brought to you by [@martinlasek](https://github.com/martinlasek)
57 |
58 | [Write a CRUD API using JSON](https://medium.com/@martinlasek/tutorial-write-a-crud-api-using-json-c1edb1439d8a)
59 |
60 | ### How to use JWT
61 |
62 | Brought to you by [@amlug](https://github.com/proggeramlug)
63 |
64 | [An example on how to use JWT](https://github.com/skelpo/JWTAuthExample)
65 |
66 | ### Leaf files syntax highlighting in Xcode
67 | Brought to you by [@ashokgelal](https://github.com/ashokgelal)
68 |
69 | [Automatically setting color scheme for .leaf files in Xcode](https://ashokgelal.com/2017/01/19/leaf_color_schemer_xcode/?ref=github)
70 |
71 |
72 | ## WWDC Special
73 |
74 | Our friends from [Vapor London](https://www.meetup.com/VaporLondon/) had created a Special Meetup to cover the WWDC. Come and join us! :D
75 |
76 | [Vapor WWDC Meetup](http://meetu.ps/e/Fk96f/zf1k9/a)
77 |
78 | ## Want to know more or get inspired?
79 |
80 | - Check out what we are working on now. You might see something you can collaborate with [Issues](https://github.com/search?q=org%3Avapor+is%3Aissue+is%3Aopen+)
81 | - Check out more Vapor awesomeness [Awesome Vapor](https://github.com/Cellane/awesome-vapor)
82 | - Some more Vapor learning material [Vapor School](https://github.com/vaporberlin/vaporschool)
83 | - Great resources from our community [Vapor Forum](https://www.vaporforums.io)
84 | - Vapor's Core team had published an early access book on Vapor through RW [here](https://store.raywenderlich.com/products/server-side-swift-with-vapor)
85 | - Paul Hudson had also updated his Server Side Swift with Vapor book [here](https://www.hackingwithswift.com/files/server-side-swift-vapor-edition-toc.pdf)
86 | - Also the RW's Vapor Video Course [Server Side Swift with Vapor - Video Course ](https://videos.raywenderlich.com/courses/115-server-side-swift-with-vapor/lessons/1)
87 | - Vapor Forum [Vapor Forum](http://vaporforums.io/)
88 | - Vapor Forum @swift.org [Vapor@swift.org](https://forums.swift.org/c/related-projects/vapor)
89 |
90 | ## Take action
91 |
92 | There are many ways you can contribute with Vapor
93 |
94 | - [Star the project in GitHub](https://github.com/vapor/vapor)
95 | - [Follow us on Twitter](https://twitter.com/codevapor)
96 | - [Follow us on Medium](https://medium.com/@codevapor)
97 | - [Become a backer](https://opencollective.com/vapor#backer)
98 | - [Become a sponsor](https://opencollective.com/vapor#sponsor)
99 | - [Come and talk to us](https://vapor.team)
100 |
101 | ## Vapor communities around the world
102 |
103 | [Vapor Berlin](http://vapor.berlin/#/)
104 |
105 | [Vapor London](https://www.meetup.com/VaporLondon/)
106 |
107 | [Vapor Boston](https://www.meetup.com/VaporBoston/)
108 |
109 | [Vapor Tokyo](https://vapormeetuptokyo.connpass.com/event/88654/)
110 |
111 | ## Writing Credits
112 |
113 | [@frivas](https://github.com/frivas)
114 |
115 | [@twof](https://github.com/twof)
116 |
--------------------------------------------------------------------------------
/week19-18-06-08.md:
--------------------------------------------------------------------------------
1 | # Week 19
2 |
3 | ## News
4 |
5 | Great week!. Interesting WWDC, it brought a bunch of updates, features, applications and more *mojis. Great attendance to the Vapor Meetup, over 200 people, thanks to everyone!. An update to [RW's Vapor book](https://www.raywenderlich.com/195807/server-side-swift-with-vapor-5-new-chapters-available) and more.
6 |
7 | ## NIO
8 |
9 | ### Current version [1.8.0](https://github.com/apple/swift-nio/releases/tag/1.8.0)
10 |
11 | Great news! Network.framework is now available for Apple platforms. NIO on top of it is being tested now and below you can find a great video from WWDC 18:
12 |
13 | [Introducing Network.framework](https://developer.apple.com/videos/play/wwdc2018/715/)
14 |
15 | ## Tagged releases
16 | ### Current Version [3.0.4](https://github.com/vapor/vapor/releases/tag/3.0.4)
17 |
18 | - [Vapor 3.0.4](https://github.com/vapor/vapor/releases/tag/3.0.4)
19 |
20 | ## Articles
21 |
22 | ### Mastering a Multi-Stage CI of Vapor Apps to a Kubernetes Cluster
23 |
24 | Brought to you by [@Cellane](https://github.com/Cellane)
25 |
26 | [Mastering a Multi-Stage CI of Vapor Apps to a Kubernetes Cluster](https://www.milanvit.net/post/how-to-master-a-multi-stage-continuous-delivery-of-vapor-apps-to-a-kubernetes-cluster)
27 |
28 | ### Getting started with Leaf
29 |
30 | Brought to you by [@anapaix](https://github.com/JoeyBodnar)
31 |
32 | [Getting started with Leaf](https://www.vaporforums.io/viewThread/46)
33 |
34 | ### How to add a PostgreSQL DB
35 |
36 | Brought to you by [@anapaix](https://github.com/JoeyBodnar)
37 |
38 | [How to add a PostgreSQL DB](https://www.youtube.com/watch?v=QGxJQ2NMCq8&t=2s)
39 |
40 | ## Want to know more or get inspired?
41 |
42 | - Check out what we are working on now. You might see something you can collaborate with [Issues](https://github.com/search?q=org%3Avapor+is%3Aissue+is%3Aopen+)
43 | - Check out more Vapor awesomeness [Awesome Vapor](https://github.com/Cellane/awesome-vapor)
44 | - Some more Vapor learning material [Vapor School](https://github.com/vaporberlin/vaporschool)
45 | - Great resources from our community [Vapor Forum](https://www.vaporforums.io)
46 | - Vapor's Core team had published an early access book on Vapor through RW [here](https://store.raywenderlich.com/products/server-side-swift-with-vapor)
47 | - Paul Hudson had also updated his Server Side Swift with Vapor book [here](https://www.hackingwithswift.com/files/server-side-swift-vapor-edition-toc.pdf)
48 | - Also the RW's Vapor Video Course [Server Side Swift with Vapor - Video Course ](https://videos.raywenderlich.com/courses/115-server-side-swift-with-vapor/lessons/1)
49 | - Vapor Forum [Vapor Forum](http://vaporforums.io/)
50 | - Vapor Forum @swift.org [Vapor@swift.org](https://forums.swift.org/c/related-projects/vapor)
51 |
52 | ## Take action
53 |
54 | There are many ways you can contribute with Vapor
55 |
56 | - [Star the project in GitHub](https://github.com/vapor/vapor)
57 | - [Follow us on Twitter](https://twitter.com/codevapor)
58 | - [Follow us on Medium](https://medium.com/@codevapor)
59 | - [Become a backer](https://opencollective.com/vapor#backer)
60 | - [Become a sponsor](https://opencollective.com/vapor#sponsor)
61 | - [Come and talk to us](https://vapor.team)
62 |
63 | ## Vapor communities around the world
64 |
65 | [Vapor Berlin](http://vapor.berlin/#/)
66 |
67 | [Vapor London](https://www.meetup.com/VaporLondon/)
68 |
69 | [Vapor Boston](https://www.meetup.com/VaporBoston/)
70 |
71 | [Vapor Tokyo](https://vapormeetuptokyo.connpass.com/event/88654/)
72 |
73 | ## Writing Credits
74 |
75 | [@frivas](https://github.com/frivas)
76 |
77 | [@twof](https://github.com/twof)
78 |
--------------------------------------------------------------------------------
/week2-18-02-05.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | ---
4 | # Week 2
5 |
6 | [Follow Vapor Nation on Twitter](https://twitter.com/VaporNationNews) 😲
7 |
8 | It's a big week for Vapor! With the finalization of tagged beta releases on February 9th, you can finally update without worrying (too much) about it breaking your project. In addition to everything in this week's Vapor Nation, there were loads of bug fixes and minor improvements behind the scenes, so if you were holding off because of a blocking bug before, now would be a good time to update your projects and give it another shot. Without further ado, let's get into it!
9 |
10 | ## Discussions
11 |
12 | ### `map` and `flatmap` Explicit Return Type
13 | Should `map` and `flatmap` require an explicit return type when their input is the same type as their output?
14 |
15 | [https://github.com/vapor/async/pull/51](https://github.com/vapor/async/pull/51)
16 |
17 | ### `catchMap` Naming and Behavior
18 | Should there be a way to catch specific errors in promise chains? What should it be called?
19 |
20 | [https://github.com/vapor/async/issues/65](https://github.com/vapor/async/issues/65)
21 |
22 | ## New Features
23 |
24 | ### Next Tick
25 | Adds `eventLoop.onNextTick { ... }`, `promise.complete(..., onNextTick: ...)`, and `worker.doBlockingWork { ... }`, which should prevent stack overflows in some cases.
26 |
27 | [https://github.com/vapor/async/pull/67](https://github.com/vapor/async/pull/67)
28 |
29 | ## Community Contributions
30 |
31 | ### Massive overhaul of mismanaged memory in Engine
32 | [@gwynne](https://github.com/gwynne) submitted a pretty huge PR that fixes several bugs, including:
33 | - Several dozen instances of undefined behavior when working with raw pointers in `Engine`
34 | - Not allocating enough memory when parsing HTTP headers
35 | - Incorrect handling of the trailing `\r\n` when serializing HTTP requests
36 | - Not allocating enough space for query parameters in a URI when serializing HTTP requests
37 | - Several minor memory leaks
38 |
39 | The PR also adds handling of the `version` field on `Request`, allowing `Client`s to send HTTP/1.0 requests. (300 LoC)
40 |
41 | [https://github.com/vapor/engine/pull/220](https://github.com/vapor/engine/pull/220)
42 |
43 | ### Add header names and use constants where possible
44 | [@siemensikkema](https://github.com/siemensikkema) noticed a few missing HTTP headers, so they added them in. They also increased safety by replacing string literals with constants where possible. (9 LoC)
45 |
46 | [https://github.com/vapor/engine/pull/215](https://github.com/vapor/engine/pull/215)
47 |
48 | ### Code Cleanup
49 | [@siemensikkema](https://github.com/siemensikkema) was busy this week! They went through and updated comments and removed blank lines where possible, greatly improving code cleanliness. (50 LoC)
50 |
51 | [https://github.com/vapor/vapor/pull/1475](https://github.com/vapor/vapor/pull/1475)
52 |
53 | ### Teapot
54 | **_Very_** important PR that adds a missing HTTP code. (1 LoC)
55 |
56 | [https://github.com/vapor/engine/pull/219](https://github.com/vapor/engine/pull/219)
57 |
58 | ### Fixed Exclusive Access to Memory
59 | Swift 4.1 introduced the requirement that [exclusive memory access be enforced on a per-line basis](https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/MemorySafety.html#//apple_ref/doc/uid/TP40014097-CH46-ID567). Most people felt this was overall a good change, but there were a few places in the Vapor codebase that the rule wasn't being followed, preventing compilation with the latest 4.1 toolchains. [@SandorDobi](https://github.com/SandorDobi) fixed that. (20 LoC)
60 |
61 | [https://github.com/vapor/vapor/pull/1489](https://github.com/vapor/vapor/pull/1489)
62 |
63 | ### Switched to Tagged Dependencies for JWT and Leaf
64 | With the deadline for tagging being this week, there was a lot of work to do. [@tanner0101](https://github.com/tanner0101) did most of it for the core Vapor repos, but [@Cellane](https://github.com/Cellane) came through with the cleanup.
65 |
66 | [https://github.com/vapor/jwt/pull/82](https://github.com/vapor/jwt/pull/82)
67 |
68 | ## Tutorials
69 |
70 | ### Joannis' explanation on SO
71 | [@Joannis](https://github.com/Joannis) gave a short overview of Vapor 3 in response to a question on Stack Overflow.
72 |
73 | [https://stackoverflow.com/questions/48589415/vapor-3-beta-example-endpoint-request/48597407#48597407](https://stackoverflow.com/questions/48589415/vapor-3-beta-example-endpoint-request/48597407#48597407)
74 |
75 | ## Talks
76 |
77 | ### Vapor Meetup Tokyo
78 | As Vapor ramps up, I'm expecting to see more and more talks, and the first Vapor 3 talks come to us out of Tokyo! At the meetup, [@tanner0101](https://github.com/tanner0101) gave us an introduction to Vapor and the benefits of Swift on the server (English), [@Joannis](https://github.com/Joannis) talks about what makes Vapor fast and efficient (English), [@noppoMan](https://github.com/noppoMan) talked about their experience with serverless Swift (Japanese), [@Casperhr](https://github.com/Casperhr) talks about running Vapor in production (English), and [@hiragram](https://github.com/hiragram) led us through the path he took making the backend for his cryptocurrency app with Vapor (Japanese).
79 |
80 | [https://www.youtube.com/watch?v=CbyoXkdTfM8](https://www.youtube.com/watch?v=CbyoXkdTfM8)
81 |
82 | ## Made With Vapor
83 |
84 | ### serversideswift.racing
85 | Vapor is about a week away from passing Perfect in the number of Github stars! While this isn't the most important metric, it will make Vapor the most popular server-side Swift framework on Github. You can track the momentous occasion using [http://serversideswift.racing/](http://serversideswift.racing/) made by [@MartinLasek](https://github.com/MartinLasek)! Check it out 😊
86 |
87 | [http://serversideswift.racing/](http://serversideswift.racing/)
88 |
89 | ## Microtutorial
90 | Vapor's Futures encourage a style of coding that's all about data transformation. You take in a request, turn that request into an ID, use that ID to search the database for a row, turn that row into an object, make some change to that object, turn that object into a response, and return that response. Every input gets sent down a pipeline until you end up with the data you want. The `map(to:)` function is the building block of all transformations. So what does that look like?
91 |
92 | ```swift
93 | router.get("user", UUID.parameter) { (req) -> Future in // Take in a request
94 | let userID = try req.parameter(UUID.self) // Turn that request into an ID
95 |
96 | return try User
97 | .find(userID, on: req) // Use that ID to search the database for a row, turn that row into an (optional) object
98 | .map(to: User.self) { (user) in // Unwrap the object
99 | guard let user = user else {throw Abort(.notFound, reason: "User Not Found")}
100 | return user
101 | }.map(to: User.self) { (user) in // Make some change to the object
102 | user.name = "Jamie"
103 | return user
104 | }.encode(for: req) // Turn that object into a response, and return that response
105 | }
106 | ```
107 | ***
108 |
109 | ## Credits
110 | [@gwynne](https://github.com/gwynne)
111 | [@twof](https://github.com/twof)
112 |
--------------------------------------------------------------------------------
/week20-18-06-15.md:
--------------------------------------------------------------------------------
1 | # Week 20
2 |
3 | ## News
4 |
5 | Hello Vapor-heads of the world!. The final Fluent 3 RCs were released this week and it comes with very interesting changes and improvements. Big steps towards code sharing, first tests of using Fluent ORM with the internal SQLite DB on iOS ✅
6 |
7 | ## New Features
8 |
9 | ### Add CaseIterable protocol for Swift 4.1
10 |
11 | This will allow Fluent to take advantage of CaseIterable when it comes in Swift 4.2.
12 |
13 | [vapor/core#157](https://github.com/vapor/core/pull/157)
14 |
15 | ### Fluent 1.0.0 GM + Add Decoders + SQL Updates
16 |
17 | [vapor/postgresql#72](https://github.com/vapor/postgresql/pull/72)
18 |
19 | ## NIO
20 |
21 | ### Current version [1.8.0](https://github.com/apple/swift-nio/releases/tag/1.8.0)
22 |
23 | ### Updated http_parser
24 | **Motivation:**
25 |
26 | Our copy of ```http_parser``` has become almost a year old now, and there are
27 | both some bugfixes that improve correctness and some performance
28 | improvements in ```http_parser``` that we should pick up.
29 |
30 | **Modifications:**
31 |
32 | - Updated http_parser
33 | - Added tests to confirm we don't suffer from [nodejs/http-parser#432](https://github.com/nodejs/http-parser/pull/432)
34 | - Added tests that we didn't get broken by SOURCE verb addition.
35 |
36 | **Result:**
37 |
38 | Shiny new http_parser!
39 |
40 | ## Community Contributions
41 |
42 | ### Created Worker.future() method
43 |
44 | Adds a .future() method to the Worker protocol that creates a new, succeeded, future with a Void value.
45 |
46 | ```let success: Future = request.future()```
47 |
48 | [vapor/core#156](https://github.com/vapor/core/pull/156)
49 |
50 | ### Added helper method to initialize connection from connection string
51 |
52 | ```swift
53 | let databaseURL = "mysql://username:password@hostname.com:3306/database"
54 | let config = try MySQLDatabaseConfig(url: databaseURL)
55 | ```
56 |
57 | [vapor/mysql#177](https://github.com/vapor/mysql/pull/177)
58 |
59 | ### Added PostgreSQLStringModel
60 |
61 | [vapor/fluent-postgresql#45](https://github.com/vapor/fluent-postgresql/pull/45)
62 |
63 | ### Make FluentSQLite usable on iOS
64 |
65 | The two most popular options for persistence on iOS (Realm and Core Data), both rely heavily on Objective-C, however, SQLite is available.
66 |
67 | **Concept:**
68 |
69 | ```swift
70 | // Shared models package, imported by both client and server
71 | class User: Codable {
72 | let id: Int?
73 | let name: String
74 | let age: Int
75 | }
76 |
77 | // Client
78 | extension User: SQLiteModel, Migration {}
79 |
80 | // Server
81 | extension User: PostgresModel, Migration {}
82 | ```
83 | [vapor/fluent-sqlite#7](https://github.com/vapor/fluent-sqlite/issues/7#issuecomment-397487900)
84 |
85 | ## Tagged releases
86 | ### Current Version [3.0.4](https://github.com/vapor/vapor/releases/tag/3.0.4)
87 |
88 | - [Core 3.3.0](https://github.com/vapor/core/releases/tag/3.3.0)
89 | - [DatabaseKit 1.1.0](https://github.com/vapor/database-kit/releases/tag/1.1.0)
90 | - [SQLite 3.0.0 RC 3](https://github.com/vapor/sqlite/releases/tag/3.0.0-rc.3)
91 | - [MySQL 3.0.0 RC 3](https://github.com/vapor/mysql/releases/tag/3.0.0-rc.3)
92 | - [PostgreSQL 1.0.0 RC 3.0.1](https://github.com/vapor/postgresql/releases/tag/1.0.0-rc.3.0.1)
93 | - [Fluent 3.0.0 RC 3.0.1](https://github.com/vapor/fluent/releases/tag/3.0.0-rc.3.0.1)
94 | - [Fluent SQLite 3.0.0 RC 3](https://github.com/vapor/fluent-sqlite/releases/tag/3.0.0-rc.3)
95 | - [Fluent MySQL 3.0.0 RC 3](https://github.com/vapor/fluent-mysql/releases/tag/3.0.0-rc.3)
96 | - [Fluent PostgreSQL 1.0.0 RC 3.0.1](https://github.com/vapor/fluent-postgresql/releases/tag/1.0.0-rc.3.0.1)
97 | - [Redis 3.0.0 RC 3](https://github.com/vapor/redis/releases/tag/3.0.0-rc.3)
98 | - [Auth 2.0.0 RC 5](https://github.com/vapor/auth/releases/tag/2.0.0-rc.5)
99 |
100 | ## Articles
101 |
102 | ### How to build Web Auth with Session
103 |
104 | Brought to you by [@martinlasek](https://github.com/martinlasek)
105 |
106 | [How to build Web Auth with Session](https://medium.com/@martinlasek/tutorial-how-to-build-web-auth-with-session-f9f64ba49830)
107 |
108 | ### Fluent Migrations: Adding/Deleting columns from a Database
109 |
110 | Brought to you by [@anapaix](https://github.com/JoeyBodnar)
111 |
112 | [Fluent Migrations: Adding/Deleting columns from a Database](https://www.youtube.com/watch?v=LBbq89LXDNk)
113 |
114 | ## Want to know more or get inspired?
115 |
116 | - Check out what we are working on now. You might see something you can collaborate with [Issues](https://github.com/search?q=org%3Avapor+is%3Aissue+is%3Aopen+)
117 | - Check out more Vapor awesomeness [Awesome Vapor](https://github.com/Cellane/awesome-vapor)
118 | - Some more Vapor learning material [Vapor School](https://github.com/vaporberlin/vaporschool)
119 | - Great resources from our community [Vapor Forum](https://www.vaporforums.io)
120 | - Vapor's Core team had published an early access book on Vapor through RW [here](https://store.raywenderlich.com/products/server-side-swift-with-vapor)
121 | - Paul Hudson had also updated his Server Side Swift with Vapor book [here](https://www.hackingwithswift.com/files/server-side-swift-vapor-edition-toc.pdf)
122 | - Also the RW's Vapor Video Course [Server Side Swift with Vapor - Video Course ](https://videos.raywenderlich.com/courses/115-server-side-swift-with-vapor/lessons/1)
123 | - Vapor Forum [Vapor Forum](http://vaporforums.io/)
124 | - Vapor Forum @swift.org [Vapor@swift.org](https://forums.swift.org/c/related-projects/vapor)
125 |
126 | ## Take action
127 |
128 | There are many ways you can contribute with Vapor
129 |
130 | - [Star the project in GitHub](https://github.com/vapor/vapor)
131 | - [Follow us on Twitter](https://twitter.com/codevapor)
132 | - [Follow us on Medium](https://medium.com/@codevapor)
133 | - [Become a backer](https://opencollective.com/vapor#backer)
134 | - [Become a sponsor](https://opencollective.com/vapor#sponsor)
135 | - [Come and talk to us](https://vapor.team)
136 |
137 | ## Vapor communities around the world
138 |
139 | [Vapor Berlin](http://vapor.berlin/#/)
140 |
141 | [Vapor London](https://www.meetup.com/VaporLondon/)
142 |
143 | [Vapor Boston](https://www.meetup.com/VaporBoston/)
144 |
145 | [Vapor Tokyo](https://vapormeetuptokyo.connpass.com/event/88654/)
146 |
147 | ## Writing Credits
148 |
149 | [@frivas](https://github.com/frivas)
150 |
151 | [@twof](https://github.com/twof)
152 |
--------------------------------------------------------------------------------
/week21-18-06-22.md:
--------------------------------------------------------------------------------
1 | # Week 21
2 |
3 | ## News
4 |
5 | Hello friends, [Vapor 3.0.5](https://github.com/vapor/vapor/releases/tag/3.0.5) has been tagged. Quite a few improvements and new features. Fluent just keeps getting better and better.
6 |
7 | ## New Features
8 |
9 | ### Add DatabaseQueryable protocol
10 |
11 | Adds a new protocol ```DatabaseQueryable``` which represents an object capable of executing a generic query.
12 |
13 | [vapor/database-kit#39](https://github.com/vapor/database-kit/pull/39)
14 |
15 | ### Add `AlterTable` to PostgreSQLQuery
16 |
17 | Adds support for ```ALTER TABLE``` query to ```PostgreSQLQuery```.
18 |
19 | [vapor/postgresql#77](https://github.com/vapor/postgresql/pull/77)
20 |
21 | ### Serialize migrations + convenience methods
22 |
23 | - SchemaSupporting CRUD methods now use conn.fluentOperation to ensure they run serialized.
24 | - MigrationConfig now exposes methods for running the migrations.
25 |
26 | [vapor/fluent#507](https://github.com/vapor/fluent/pull/507)
27 |
28 | ### Add CREATE and DROP INDEX queries
29 |
30 | Adds ```SQLCreateIndex``` and ```SQLDropIndex``` protocols (and subprotocols). Related to [vapor/sql#16](https://github.com/vapor/sql/pull/16) and [vapor/fluent#515](https://github.com/vapor/fluent/issues/515)
31 |
32 | [vapor/sqlite#43](https://github.com/vapor/sqlite/pull/43)
33 |
34 | [vapor/postgresql#84](https://github.com/vapor/postgresql/pull/84)
35 |
36 | [vapor/mysql#192](https://github.com/vapor/mysql/pull/192)
37 |
38 | ### Deletes MigrationLog migration when reverting all
39 |
40 | - Running revert all migrations now deletes the fluent (MigrationLog) entity as well.
41 | - Builder.filter(custom:) is the new name for the generic filter accepting overload to prevent ambiguity
42 | - Fixes [vapor/fluent-mysql#107](https://github.com/vapor/fluent-mysql/issues/107)
43 | - Fixes [vapor/fluent-mysql#120](https://github.com/vapor/fluent-mysql/issues/120)
44 |
45 | [vapor/fluent#527](https://github.com/vapor/fluent/pull/527)
46 |
47 | ### Allow positioning of columns during ALTER TABLE
48 |
49 | Allows ```ALTER TABLE `listings` ADD `client_id` INT NULL DEFAULT NULL AFTER `object_no`;```. Implements [vapor/fluent-mysql#41](https://github.com/vapor/fluent-mysql/issues/41)
50 |
51 | [vapor/fluent-mysql#121](https://github.com/vapor/fluent-mysql/pull/121)
52 |
53 | [vapor/mysql#184](https://github.com/vapor/mysql/pull/184)
54 |
55 | ### Data Type improvements
56 |
57 | Adds conveniences for creating instances of MySQLDataType. Fixes some serialization bugs.
58 |
59 | Fixes [vapor/mysql#185](https://github.com/vapor/mysql/issues/185) and [vapor/mysql#186](https://github.com/vapor/mysql/issues/186)
60 |
61 | [vapor/mysql#188](https://github.com/vapor/mysql/pull/188)
62 |
63 | ### SQL protocols 2.0
64 |
65 | Add ```groupBy``` support
66 |
67 | [vapor/fluent#521](https://github.com/vapor/fluent/pull/521)
68 |
69 | ## NIO
70 |
71 | ### Current version [1.8.0](https://github.com/apple/swift-nio/releases/tag/1.8.0)
72 |
73 | ## Community Contributions
74 |
75 | ### Ability to set custom createdAt/updatedAt on create
76 |
77 | Set ```createdAt``` / ```updatedAt``` fields with custom values when seeding a DB.
78 |
79 | [vapor/fluent#520](https://github.com/vapor/fluent/pull/520)
80 |
81 | ### Added PostgreSQLStringModel
82 |
83 | [vapor/fluent-postgresql#45](https://github.com/vapor/fluent-postgresql/pull/45)
84 |
85 | ### Conform Decimal to ReflectionDecodable
86 |
87 | [vapor/core#158](https://github.com/vapor/core/pull/158)
88 |
89 | ## Tagged releases
90 |
91 | ### Current Version [3.0.5](https://github.com/vapor/vapor/releases/tag/3.0.5)
92 |
93 | - [DatabaseKit 1.2.0](https://github.com/vapor/database-kit/releases/tag/1.2.0)
94 | - [SQLite 3.0.0 RC 4.1](https://github.com/vapor/sqlite/releases/tag/3.0.0-rc.4.1)
95 | - [MySQL 3.0.0 RC 4.3](https://github.com/vapor/mysql/releases/tag/3.0.0-rc.4.3)
96 | - [PostgreSQL 1.0.0 RC 4.2](https://github.com/vapor/postgresql/releases/tag/1.0.0-rc.4.2)
97 | - [Fluent 3.0.0 RC 4](https://github.com/vapor/fluent/releases/tag/3.0.0-rc.4)
98 | - [Fluent SQLite 3.0.0 RC 4](https://github.com/vapor/fluent-sqlite/releases/tag/3.0.0-rc.4)
99 | - [Fluent MySQL 3.0.0 RC 4](https://github.com/vapor/fluent-mysql/releases/tag/3.0.0-rc.4)
100 | - [Fluent PostgreSQL 1.0.0 RC 4](https://github.com/vapor/fluent-postgresql/releases/tag/1.0.0-rc.4)
101 | - [Core 3.4.1](https://github.com/vapor/core/releases/tag/3.4.1)
102 | - [SQL 2.0.0 Beta 3](https://github.com/vapor/sql/releases/tag/2.0.0-beta.3)
103 |
104 | ## Articles
105 |
106 | ### Deploying a Vapor App to Heroku
107 |
108 | Brought to you by [@anapaix](https://github.com/JoeyBodnar)
109 |
110 | [Deploying a Vapor App to Heroku](https://www.vaporforums.io/viewThread/49)
111 |
112 | ### Awesome Vapor: Enhanced
113 |
114 | Brought to you by [@Cellane](https://github.com/Cellane)
115 |
116 | [Awesome Vapor](https://github.com/Cellane/awesome-vapor/tree/filtered)
117 |
118 | ## Want to know more or get inspired?
119 |
120 | - Check out what we are working on now. You might see something you can collaborate with [Issues](https://github.com/search?q=org%3Avapor+is%3Aissue+is%3Aopen+)
121 | - Check out more Vapor awesomeness [Awesome Vapor](https://github.com/Cellane/awesome-vapor)
122 | - Some more Vapor learning material [Vapor School](https://github.com/vaporberlin/vaporschool)
123 | - Great resources from our community [Vapor Forum](https://www.vaporforums.io)
124 | - Vapor's Core team had published an early access book on Vapor through RW [here](https://store.raywenderlich.com/products/server-side-swift-with-vapor)
125 | - Paul Hudson had also updated his Server Side Swift with Vapor book [here](https://www.hackingwithswift.com/files/server-side-swift-vapor-edition-toc.pdf)
126 | - Also the RW's Vapor Video Course [Server Side Swift with Vapor - Video Course ](https://videos.raywenderlich.com/courses/115-server-side-swift-with-vapor/lessons/1)
127 | - Vapor Forum [Vapor Forum](http://vaporforums.io/)
128 | - Vapor Forum @swift.org [Vapor@swift.org](https://forums.swift.org/c/related-projects/vapor)
129 | - Mohammad Azam's course on Udemy ["Mastering Server Side Swift Using Vapor 3"](https://www.udemy.com/mastering-server-side-swift-using-vapor-3/?couponCode=VAPOR3CHAT)
130 | - Mihaela Mihaljevic's [Vapor 3 Tutorials](https://mihaelamj.github.io/Vapor%20%203%20Tutorial/)
131 | - Martin Lasek's [Vapor Short Tutorials](https://medium.com/@martinlasek)
132 |
133 | ## Take action
134 |
135 | There are many ways you can contribute with Vapor
136 |
137 | - [Star the project in GitHub](https://github.com/vapor/vapor)
138 | - [Follow us on Twitter](https://twitter.com/codevapor)
139 | - [Follow us on Medium](https://medium.com/@codevapor)
140 | - [Become a backer](https://opencollective.com/vapor#backer)
141 | - [Become a sponsor](https://opencollective.com/vapor#sponsor)
142 | - [Come and talk to us](https://vapor.team)
143 |
144 | ## Vapor communities around the world
145 |
146 | [Vapor Berlin](http://vapor.berlin/#/)
147 |
148 | [Vapor London](https://www.meetup.com/VaporLondon/)
149 |
150 | [Vapor Boston](https://www.meetup.com/VaporBoston/)
151 |
152 | [Vapor Tokyo](https://vapormeetuptokyo.connpass.com/event/88654/)
153 |
154 | ## Writing Credits
155 |
156 | [@frivas](https://github.com/frivas)
157 |
158 | [@twof](https://github.com/twof)
159 |
--------------------------------------------------------------------------------
/week22-18-06-29.md:
--------------------------------------------------------------------------------
1 | # Week 22
2 |
3 | ## News
4 |
5 | Hello friends, we have included a new section called "Showcase", yes, like the Discord channel, we thought that it would be good to let everyone know what Vapor is being used for around the globe and gladly share the news of production ready Vapor-based projects. We hope you find it interesting and useful and moreover if you find a project particularly interesting feel free to contribute. Also, if you have not done it already, check out the latest updates of the [RW's Vapor book](https://store.raywenderlich.com/products/server-side-swift-with-vapor) and [@azam](https://github.com/azamsharp) has updated his course.
6 |
7 | ## NIO
8 |
9 | ### Current version [1.8.0](https://github.com/apple/swift-nio/releases/tag/1.8.0)
10 |
11 | ## Community Contributions
12 |
13 | ## Add ```.check```column constraint convenience
14 |
15 | ```builder.field(for: .pointsPerMonth, type: .doublePrecision, .check(.pointsPerMonth > 0.0))```
16 |
17 | Solves [vapor/sql#17](https://github.com/vapor/sql/issues/17)
18 |
19 | [vapor/sql#18](https://github.com/vapor/sql/pull/18)
20 |
21 | ## Tagged releases
22 |
23 | ### Current Version [3.0.5](https://github.com/vapor/vapor/releases/tag/3.0.5)
24 |
25 | - [PostgreSQL 1.0.0 RC 4.2.1](https://github.com/vapor/postgresql/releases/tag/1.0.0-rc.4.2.1)
26 |
27 |
28 | ## Articles
29 |
30 | ### Swift-ly becoming a Vapor 3 web developer on Windows
31 |
32 | Brought to you by [@antonyharfield](https://github.com/antonyharfield)
33 |
34 | [Swift-ly becoming a Vapor 3 web developer on Windows](https://medium.com/@antonyharfield/swift-ly-becoming-a-vapor-3-web-developer-on-windows-68b149a8f038)
35 |
36 | ### Vapor Security XSS and CSRF
37 |
38 | Brought to you by [@cakinney](https://github.com/nilvalues)
39 |
40 | [XSS](https://github.com/cakinney/VaporSecurity/blob/master/articles/001-VaporSecurity-XSS.md)
41 | [CSRF](https://github.com/cakinney/VaporSecurity/blob/master/articles/002-VaporSecurity-CSRF.md)
42 |
43 | ## Showcase
44 |
45 | ### Vapor Scraper
46 |
47 | Brought to you by [@Eric_WVGG](https://gitlab.com/Eric_WVGG)
48 |
49 | [Vapor Scraper](https://gitlab.com/Eric_WVGG/vapor-scraper)
50 |
51 | ### ButterBot
52 | Butterbot is a blazingly dumb bot written in Swift 4.1 with Vapor 3.
53 |
54 | Brought top you by [NoRespect](https://github.com/NoRespect)
55 |
56 | [ButterBot](https://github.com/NoRespect/ButterBot)
57 |
58 | ### BotBot
59 |
60 | BotBot is an open-source Slackbot for Marvel - a design collaboration platform that brings ideas to life.
61 |
62 | Brought to you by [@MarvelApp](https://github.com/marvelapp)
63 |
64 | [BotBot](https://github.com/marvelapp/BotBot/)
65 |
66 | ### Researcher
67 |
68 | Researcher - a simple mobile app and a website that allows academics to read and track the latest relevant papers that have been published in all the top scientific journals.
69 |
70 | [Researcher ](https://t.co/5sx3ynJvri)
71 |
72 | ## Want to know more or get inspired?
73 |
74 | - Check out what we are working on now. You might see something you can collaborate with [Issues](https://github.com/search?q=org%3Avapor+is%3Aissue+is%3Aopen+)
75 | - Check out more Vapor awesomeness [Awesome Vapor](https://github.com/Cellane/awesome-vapor)
76 | - Some more Vapor learning material [Vapor School](https://github.com/vaporberlin/vaporschool)
77 | - Great resources from our community [Vapor Forum](https://www.vaporforums.io)
78 | - Vapor's Core team had published an early access book on Vapor through RW [here](https://store.raywenderlich.com/products/server-side-swift-with-vapor)
79 | - Paul Hudson had also updated his Server Side Swift with Vapor book [here](https://www.hackingwithswift.com/files/server-side-swift-vapor-edition-toc.pdf)
80 | - Also the RW's Vapor Video Course [Server Side Swift with Vapor - Video Course ](https://videos.raywenderlich.com/courses/115-server-side-swift-with-vapor/lessons/1)
81 | - Vapor Forum [Vapor Forum](http://vaporforums.io/)
82 | - Vapor Forum @swift.org [Vapor@swift.org](https://forums.swift.org/c/related-projects/vapor)
83 | - Mohammad Azam's course on Udemy ["Mastering Server Side Swift Using Vapor 3"](https://www.udemy.com/mastering-server-side-swift-using-vapor-3/?couponCode=VAPOR3CHAT)
84 | - Mihaela Mihaljevic's [Vapor 3 Tutorials](https://mihaelamj.github.io/Vapor%20%203%20Tutorial/)
85 | - Martin Lasek's [Vapor Short Tutorials](https://medium.com/@martinlasek)
86 |
87 | ## Take action
88 |
89 | There are many ways you can contribute with Vapor
90 |
91 | - [Star the project in GitHub](https://github.com/vapor/vapor)
92 | - [Follow us on Twitter](https://twitter.com/codevapor)
93 | - [Follow us on Medium](https://medium.com/@codevapor)
94 | - [Become a backer](https://opencollective.com/vapor#backer)
95 | - [Become a sponsor](https://opencollective.com/vapor#sponsor)
96 | - [Come and talk to us](https://vapor.team)
97 |
98 | ## Vapor communities around the world
99 |
100 | [Vapor Berlin](http://vapor.berlin/#/)
101 |
102 | [Vapor London](https://www.meetup.com/VaporLondon/)
103 |
104 | [Vapor Boston](https://www.meetup.com/VaporBoston/)
105 |
106 | [Vapor Tokyo](https://vapormeetuptokyo.connpass.com/event/88654/)
107 |
108 | ## Writing Credits
109 |
110 | [@frivas](https://github.com/frivas)
111 |
112 | [@twof](https://github.com/twof)
113 |
--------------------------------------------------------------------------------
/week23-18-07-06.md:
--------------------------------------------------------------------------------
1 | # Week 23
2 |
3 | ## News
4 |
5 | Hey droplets, new article and a production ready project this week. Our friends from Vapor Berlin are organizing a Meetup on July 12th so come and [join us](https://www.meetup.com/de-DE/VaporBerlin/events/252355255/). It is summer so short and sweet publication.
6 |
7 | ## New Features
8 |
9 | ### Add support for ALTER TABLE drop actions
10 |
11 | Added support for ```DROP COLUMN``` and ```DROP CONSTRAINT```
12 |
13 | [vapor/fluent-postgresql#77](https://github.com/vapor/fluent-postgresql/pull/77)
14 |
15 | [vapor/postgresql#88](https://github.com/vapor/postgresql/pull/88)
16 |
17 | ## NIO
18 |
19 | ### Current version [1.8.0](https://github.com/apple/swift-nio/releases/tag/1.8.0)
20 |
21 | ## Tagged releases
22 |
23 | ### Current Version [3.0.6](https://github.com/vapor/vapor/releases/tag/3.0.6)
24 |
25 | - [PostgreSQL 1.0.0 RC 4.3](https://github.com/vapor/postgresql/releases/tag/1.0.0-rc.4.3)
26 | - [Fluent PostgreSQL 1.0.0 RC 4.1](https://github.com/vapor/fluent-postgresql/releases/tag/1.0.0-rc.4.1)
27 |
28 | ## Articles
29 |
30 | ### One-to-Many relations in Vapor 3
31 |
32 | Brought to you by [@martinlasek](https://github.com/martinlasek)
33 |
34 | [One-to-Many Relationships in Vapor 3](https://medium.com/@martinlasek/tutorial-how-to-build-one-to-many-relations-84dd37e464a6)
35 |
36 | ## Showcase
37 |
38 | ### Transeo
39 | Transeo is a cloud-based educational solution that helps students and administrators track, report, and celebrate their community service learning experiences.
40 |
41 | Brought to you by [@mcdappdev](https://github.com/mcdappdev)
42 |
43 | [Transeo](https://gotranseo.com/)
44 |
45 | ## Want to know more or get inspired?
46 |
47 | - Check out what we are working on now. You might see something you can collaborate with [Issues](https://github.com/search?q=org%3Avapor+is%3Aissue+is%3Aopen+)
48 | - Check out more Vapor awesomeness [Awesome Vapor](https://github.com/Cellane/awesome-vapor)
49 | - Some more Vapor learning material [Vapor School](https://github.com/vaporberlin/vaporschool)
50 | - Great resources from our community [Vapor Forum](https://www.vaporforums.io)
51 | - Vapor's Core team had published an early access book on Vapor through RW [here](https://store.raywenderlich.com/products/server-side-swift-with-vapor)
52 | - Paul Hudson had also updated his Server Side Swift with Vapor book [here](https://www.hackingwithswift.com/files/server-side-swift-vapor-edition-toc.pdf)
53 | - Also the RW's Vapor Video Course [Server Side Swift with Vapor - Video Course ](https://videos.raywenderlich.com/courses/115-server-side-swift-with-vapor/lessons/1)
54 | - Vapor Forum [Vapor Forum](http://vaporforums.io/)
55 | - Vapor Forum @swift.org [Vapor@swift.org](https://forums.swift.org/c/related-projects/vapor)
56 | - Mohammad Azam's course on Udemy ["Mastering Server Side Swift Using Vapor 3"](https://www.udemy.com/mastering-server-side-swift-using-vapor-3/?couponCode=VAPOR3CHAT)
57 | - Mihaela Mihaljevic's [Vapor 3 Tutorials](https://mihaelamj.github.io/Vapor%20%203%20Tutorial/)
58 | - Martin Lasek's [Vapor Short Tutorials](https://medium.com/@martinlasek)
59 |
60 | ## Take action
61 |
62 | There are many ways you can contribute with Vapor
63 |
64 | - [Star the project in GitHub](https://github.com/vapor/vapor)
65 | - [Follow us on Twitter](https://twitter.com/codevapor)
66 | - [Follow us on Medium](https://medium.com/@codevapor)
67 | - [Become a backer](https://opencollective.com/vapor#backer)
68 | - [Become a sponsor](https://opencollective.com/vapor#sponsor)
69 | - [Come and talk to us](https://vapor.team)
70 |
71 | ## Vapor communities around the world
72 |
73 | [Vapor Berlin](http://vapor.berlin/#/)
74 |
75 | [Vapor London](https://www.meetup.com/VaporLondon/)
76 |
77 | [Vapor Boston](https://www.meetup.com/VaporBoston/)
78 |
79 | [Vapor Tokyo](https://vapormeetuptokyo.connpass.com/event/88654/)
80 |
81 | ## Writing Credits
82 |
83 | [@frivas](https://github.com/frivas)
84 |
85 | [@twof](https://github.com/twof)
86 |
--------------------------------------------------------------------------------
/week3-18-02-12.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | ---
4 | # Week 3
5 |
6 | ## News
7 | This week, Vapor passed Perfect and has earned the title of "Most Stars of Any Server-side Swift framework on Github"! 🎉🎉🎉🎉 Congrats to the team!
8 |
9 | ## New Features
10 |
11 | ### Helper Methods to Decode Content From Request Bodies
12 | It's very common to need to take the body of a request and decode it to an object. To cut down on this common boilerplate, new methods were introduced which take care of it automatically with any HTTP method that accepts a body:
13 |
14 | ```swift
15 | router.post(LoginRequest.self, at: "login") { req, loginRequest -> Response in
16 | print(loginRequest.email) // user@vapor.codes
17 | print(loginRequest.password) // don't look!
18 | return req.makeResponse()
19 | }
20 | ```
21 |
22 | [vapor/vapor#1448](https://github.com/vapor/vapor/pull/1448)
23 |
24 | ### Case Insensitive Routing
25 |
26 | While routing is still case-sensitive by default, it is now possible to choose case-insensitive routing instead:
27 | ```swift
28 | // configure.swift
29 | public func configure(
30 | _ config: inout Config,
31 | _ env: inout Environment,
32 | _ services: inout Services
33 | ) throws {
34 | // Register routes to the router
35 | let router = EngineRouter(caseInsensitive: true) // or false
36 | try routes(router)
37 | services.register(router, as: Router.self)
38 | }
39 |
40 | // routes.swift
41 | router.get("hello") { req -> HTTPStatus in
42 | return .ok
43 | }
44 | ```
45 |
46 | #### Case-sensitive
47 | `GET /hello -> 200 OK`
48 | `GET /Hello -> 404 Not Found`
49 |
50 | #### Case-insensitive
51 | `GET /hello -> 200 OK`
52 | `GET /Hello -> 200 OK`
53 |
54 | _Note: The `caseInsensitive` parameter to `EngineRouter()` is brand-new and will not be usable until Vapor beta 4._
55 |
56 | [vapor/engine#209](https://github.com/vapor/engine/pull/209)
57 |
58 | ### Value Models
59 |
60 | `struct`s can now be used as Fluent Models.
61 |
62 | [vapor/fluent#372](https://github.com/vapor/fluent/pull/372)
63 |
64 | ## Community Contributions
65 |
66 | ### Session Redirects
67 | [@0xTim](https://github.com/0xTim) introduced middleware to the Auth package that makes it easy to redirect users to another page if they aren't authenticated. For example, if a user attempts to visit a private page without logging in, you may want to redirect them to `/login` instead. This replicates the functionality of Vapor 2's `RedirectMiddleware`.
68 |
69 | [vapor/auth#19](https://github.com/vapor/auth/pull/19)
70 |
71 | ### Dependency Updates
72 | With the start of tagging, keeping `Package.swift` files up-to-date is an important but tedious task. If you're looking to pitch in, but don't know where to start, plenty of help is needed in this area. There are going to be a lot of these, so we're going to group them all together:
73 |
74 | [vapor/fluent-postgresql#13](https://github.com/vapor/fluent-postgresql/pull/13)
75 | [vapor/leaf#90](https://github.com/vapor/leaf/pull/90)
76 | [vapor/mysql#123](https://github.com/vapor/mysql/pull/123)
77 | [vapor/postgresql#16](https://github.com/vapor/postgresql/pull/16)
78 | [vapor/fluent-postgresql#14](https://github.com/vapor/fluent-postgresql/pull/14)
79 | [vapor/vapor#1498](https://github.com/vapor/vapor/pull/1498)
80 | [vapor/mysql#124](https://github.com/vapor/mysql/pull/124)
81 |
82 | ### Fixed DatabaseConnection Bug
83 | [@bensyverson](https://github.com/bensyverson) caught that `database-kit` was making a bad assert (`==` vs `!=`)
84 |
85 | [vapor/database-kit#6](https://github.com/vapor/database-kit/pull/6)
86 |
87 | ### Add Providers to OpenSSL
88 | Adding providers to the `ctls` package allows SPM to let users know when they're missing a dependency - [@Yasumoto](https://github.com/Yasumoto)
89 |
90 | [vapor/ctls#7](https://github.com/vapor/ctls/pull/7)
91 |
92 | ### Fix Issue Where Large Responses Hang
93 | With larger HTTP bodies, the `continueBuffer` state was not being handled correctly, causing the last chunk to not be sent and responses to hang. This bug existed in both Vapor 2 and 3. Thanks! [@kevinup7](https://github.com/kevinup7)
94 |
95 | [vapor/engine#222](https://github.com/vapor/engine/pull/222)
96 |
97 | ### Redundancy Cleanup
98 | [@Cellane](https://github.com/Cellane) was able to cut out a couple lines of redundant code. Any cleanup is always appreciated :)
99 |
100 | [vapor/engine#224](https://github.com/vapor/engine/pull/224)
101 |
102 | ### Allow Users of MultipartForm To Set Max Request Size
103 | The maximum request size used to be locked at 1,000,000 bytes, but [@bensyverson](https://github.com/bensyverson)'s PR allows users to increase this value if they need something larger.
104 |
105 | [vapor/vapor#1494](https://github.com/vapor/vapor/pull/1494)
106 |
107 | ### Fixes Packet Length and SequenceID
108 | This fix by [@SandorDobi](https://github.com/SandorDobi) should resolve a couple MySQL bugs.
109 |
110 | [vapor/mysql#122](https://github.com/vapor/mysql/pull/122)
111 |
112 | ### Add `delete(on:)` and `save(on:)` to `Future`
113 | [@twof](https://github.com/twof) merged in a couple of convenience extensions on `Future` that make saving and or deleting a model much cleaner. From
114 |
115 | ```swift
116 | return Reservation
117 | .query(on: databaseConnectable)
118 | .filter(\Reservation.user == userName)
119 | .first()
120 | .unwrap(or: Abort(.notFound, reason: "No reservations have been made"))
121 | .map(to: Reservation.self) { reservation in
122 | return reservation.delete(on: databaseConnectable).transform(to: reservation)
123 | }.map(to: HTTPStatus.self) { _ in
124 | return .ok
125 | }
126 | ```
127 | to
128 | ```swift
129 | return Reservation
130 | .query(on: databaseConnectable)
131 | .filter(\Reservation.user == userName)
132 | .first()
133 | .unwrap(or: Abort(.notFound, reason: "No reservations have been made"))
134 | .delete(on: databaseConnectable)
135 | .map(to: HTTPStatus.self) { _ in
136 | return .ok
137 | }
138 | ```
139 |
140 | [vapor/fluent#371](https://github.com/vapor/fluent/pull/371)
141 |
142 | ### Fatal Error Cleanup
143 | As Vapor gets closer to stability, fatal errors need to be removed so that servers aren't crashing in production. [@labradon](https://github.com/labradon) got the project well on its way by eliminating 29 fatal errors and replacing them with their proper thrown errors. (33 LoC)
144 |
145 | [vapor/postgresql#15](https://github.com/vapor/postgresql/pull/15)
146 |
147 | ### Update Vapor Toolbox For Most Recent Version of SPM
148 | There were a few deprecated options that made the toolbox unusable for a bit, but all is good again! - [@gwynne](https://github.com/gwynne)
149 |
150 | [vapor/toolbox#210](https://github.com/vapor/toolbox/pull/210)
151 |
152 | ### Improved Error Message
153 | [@gwynne](https://github.com/gwynne) updated error messages when hostname and port are misconfigured, which ought to make debugging a bit easier.
154 |
155 | [vapor/sockets#161](https://github.com/vapor/sockets/pull/161)
156 |
157 | ## Benchmarks
158 | ### 17k Queries Per Second Per Core Achieved With Fluent/MySQL
159 | That should scale infinitely with the number of cores too. Awesome!
160 |
161 | [https://twitter.com/JoannisOrlandos/status/964792631875244034](https://twitter.com/JoannisOrlandos/status/964792631875244034)
162 |
163 | ## Talks
164 |
165 | ### Joannis @ Swift Amsterdam
166 | In this talk [@Joannis](https://github.com/joannis) will cover the upcoming Vapor 3 release - a complete redesign aimed to be more configurable and performant with less boilerplate. He’ll also talk about dependency inversion, the reactive pattern, `Codable`, and how these all fit together.
167 |
168 | [https://swift.amsterdam/talks/serverside-joannis-orlandos.html](https://swift.amsterdam/talks/serverside-joannis-orlandos.html)
169 |
170 | ## Tutorials
171 |
172 | ### Ray Wenderlich Video Course and Upcoming Book by [@0xtim](https://github.com/0xtim)
173 | In this 30-video course, you’ll use Vapor, a server-side Swift web framework, to create a complex application that you can communicate with via an API and a website. The first 4 videos are available now!
174 |
175 | [https://www.raywenderlich.com/186386/new-course-server-side-swift-with-vapor](https://www.raywenderlich.com/186386/new-course-server-side-swift-with-vapor)
176 |
177 | Pre-orders also opened up for the Ray Wenderlich Vapor 3 book, written by the core Vapor team themselves! This book starts with the basics of web development and introduces the basics of Vapor; it then walks you through creating APIs and web backends, creating and configuring databases, deploying to Heroku, AWS, or Docker, testing your creations, and more!
178 |
179 | [https://store.raywenderlich.com/products/server-side-swift-with-vapor](https://store.raywenderlich.com/products/server-side-swift-with-vapor)
180 |
181 | ### How To Set Up a Vapor 3 Project
182 | In this tutorial [@martinlasek](https://github.com/martinlasek) takes you through all the steps needed to get you from installing Xcode to making requests to your Vapor server.
183 |
184 | [https://medium.com/@martinlasek/tutorial-how-to-set-up-a-vapor-3-project-75466394cf2e](https://medium.com/@martinlasek/tutorial-how-to-set-up-a-vapor-3-project-75466394cf2e)
185 |
186 | ## Microtutorial
187 | This week we're going to take a look at how to wrap up our `.map()`s to make promise chains a little more readable. We'll be continuing from last week's microtutorial:
188 |
189 | ```swift
190 | router.get("user", UUID.parameter) { (req) -> Future in // Take in a request
191 | let userID = try req.parameter(UUID.self) // Turn that request into an ID
192 |
193 | return try User
194 | .find(userID, on: req) // Use that ID to search the database for a row, turn that row into an (optional) object
195 | .map(to: User.self) { (user) in // Unwrap the object
196 | guard let user = user else {throw Abort(.notFound, reason: "User Not Found")}
197 | return user
198 | }.map(to: User.self) { (user) in // Make some change to the object
199 | user.name = "Jamie"
200 | return user
201 | }.encode(for: req) // Turn that object into a response, and return that response
202 | }
203 | ```
204 |
205 | Let's see how simple we can make this route! First we'll conform `User` to `Parameter` so we can eliminate the find step.
206 |
207 | ```swift
208 | extension User: Parameter {}
209 |
210 | router.get("user", User.parameter) { (req) -> Future in // Take in a request `/user/
211 | let user = try req.parameter(User.self) // User found with UUID. Aborts if no user is found
212 |
213 | return try user
214 | .map(to: User.self) { (user) in // Make some change to the object
215 | user.name = "Jamie"
216 | return user
217 | }.encode(for: req) // Turn that object into a response, and return that response
218 | }
219 |
220 | ```
221 |
222 | With an extension to `Future` we can remove that last `.map()`
223 |
224 | ```swift
225 | extension Future where T == User {
226 | public func changeName(to name: String) -> Future {
227 | return self.map(to: User.self) { (user) in
228 | user.name = name
229 | return user
230 | }
231 | }
232 | }
233 | ```
234 | And our final route is quite a bit more readable!
235 |
236 | ```swift
237 | router.get("user", User.parameter) { (req) -> Future in // Take in a request `/user/
238 | let user = try req.parameter(User.self) // User found with UUID. Aborts if no user is found
239 |
240 | return try user
241 | .changeName(to: "Jamie") // Make some change to the object
242 | .encode(for: req) // Turn that object into a response, and return that response
243 | }
244 | ```
245 |
246 | ***
247 |
248 | ## Credits
249 | [@twof](https://github.com/twof)
250 | [@calebkleveter](https://github.com/calebkleveter)
251 | [@Cellane](https://github.com/Cellane)
252 | [@tanner0101](https://github.com/tanner0101)
253 | [@gwynne](https://github.com/gwynne)
254 |
--------------------------------------------------------------------------------
/week4-18-02-19.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | ---
4 | # Week 4
5 |
6 | ## New Features
7 |
8 | ### Services Created With Reference Types Are Always Singletons
9 |
10 | In previous betas of Vapor 3, the service framework supported an `isSingleton` property for services which controlled their behavior when requested from different containers and/or from different requesting interfaces (the `for:` parameter of `Container.make()`). Singletons would in theory have only the single instance across all invocations. However, this only held true for services whose underlying implementations were `class`es; `struct`-based services were never singletons even when the flag was specified. In addition, the flag offered a manual control for a behavior already baked into Swift via the difference between value and reference types. Therefore, the singleton flag on service types was removed entirely. Now, to get the "singleton" behavior, use a `class` type to implement your service. `struct`-based services now receive the previously default "instanced" behavior (a new instance of the service per request).
11 |
12 | TL;DR: The redundant singleton flag on services was removed, and the behavior when requesting a given service more than once now corresponds to Swift's standard value vs. reference semantics.
13 |
14 | [vapor/service#14](https://github.com/vapor/service/pull/14)
15 |
16 | ### SQLite Models Are More Convenient
17 |
18 | Neither `typealias Database = ...` nor `static let idKey = ...` are required any longer. This is true for both `struct`- and `class`-based models.
19 |
20 | ```
21 | struct Foo: SQLiteModel {
22 | var id: Int?
23 | var name: String
24 | }
25 |
26 | final class Bar: SQLiteModel {
27 | var id: Int?
28 | var name: String
29 | }
30 | ```
31 |
32 | [vapor/fluent#380](https://github.com/vapor/fluent/pull/380)
33 |
34 | ### Debuggable
35 |
36 | `Debuggable` now conforms to Foundation's `LocalizedError` protocol, significantly improving debuggability across the board, especially including much improved log messages when an error is thrown from a unit test.
37 |
38 | [vapor/core#92](https://github.com/vapor/core/pull/92)
39 |
40 | ### Custom `URLSession`s for `FoundationClient`
41 |
42 | It is now possible to provide a pre-configured `URLSession` when using `FoundationClient`. This especially allows proxying via HTTPS, along with other parameters configurable via `URLSessionConfiguration`. (Vapor 2)
43 |
44 | [vapor/engine#237](https://github.com/vapor/engine/pull/237)
45 |
46 | ### Client Redirection
47 |
48 | `EngineClient` will now properly follow redirects, as indicated by various HTTP status codes in the 3xx series. Redirection can be configured by invoking `EngineClient`'s `respond(to:maxRedirects:)` method with the desired maxium redirection count (including zero).
49 |
50 | [vapor/vapor#1480](https://github.com/vapor/vapor/pull/1480)
51 |
52 | ## Under The Hood
53 |
54 | ### Lazy Middleware
55 |
56 | - Creates one set of middleware per event loop, preventing race conditions in middleware
57 | - Losslessly optimizes DateMiddleware to only calculate a new RFC1123 timestamp once per second
58 | - Adds a new `router.grouped(MiddlewareType.self)` overload for creating a route group around a middleware type that will be lazily initialized (on the event loop) when requested
59 |
60 | ```swift
61 | router.grouped(DateMiddleware.self).get("datetest") { req in
62 | return HTTPStatus.ok
63 | }
64 | ```
65 |
66 | In the above snippet, DateMiddleware won't be initialized until the first time that route is hit. It will subsequently be initialized for each event loop, until all event loops have one cached.
67 |
68 | - Adds application-wide timeout for requests whose runtime exceeds 30 seconds
69 |
70 | [vapor/vapor#1507](https://github.com/vapor/vapor/pull/1507)
71 |
72 | ## Help Wanted
73 |
74 | ### Leaf Syntax Highlighting For InteliJ
75 |
76 | Any new framework is nothing without good tools, and Vapor is no different. While Swift syntax highlighting is fairly easy to come by, Leaf is not.
77 |
78 | [vapor/leaf#76](https://github.com/vapor/leaf/issues/76)
79 |
80 | ## Community Contributions
81 |
82 | ### Fix an Xcode Crash In API Template
83 |
84 | Anyone who's used Vapor knows that Xcode tends to experience problems during Vapor development that you won't see when using Xcode only for iOS development. For example, if an error is raised to the top level in iOS, it gets caught by `AppDelegate`. However, Vapor apps don't have an `AppDelegate` equivalent, so instead, errors raised to to the top level crash Xcode (please file bug reports with Apple when you see this happen!). This tends to trip up newer users, so in their joint PR, [@twof](https://github.com/twof) and [@0xTim](https://github.com/0xTim) fixed Vapor 3's API template to catch top level errors, preventing these crashes.
85 |
86 | [vapor/api-template#45](https://github.com/vapor/api-template/pull/45)
87 |
88 | ### MySQL Fixes To More Closely Conform To Client-Server Protocol
89 |
90 | [@SandorDobi](https://github.com/SandorDobi) noticed a few places where Vapor's MySQL package wasn't quite conforming to MySQL's protocols and fixed them.
91 |
92 | [vapor/mysql#127](https://github.com/vapor/mysql/pull/127)
93 |
94 | ### Dependency Updates
95 |
96 | Same as last week. Tracking which dependencies need updates is hard!
97 |
98 | [vapor/auth#24](https://github.com/vapor/auth/pull/24)
99 |
100 | ### Updated RoutingGroups For Better Handling of Middleware
101 |
102 | After some [discussion](https://github.com/vapor/vapor/issues/1398), [@MaximBazarov](https://github.com/MaximBazarov) made updates to Vapor's routing groups.
103 |
104 | ```swift
105 | let users = router.group("user").using(SomeMiddleware())
106 | users.get("auth", use: userAuthHandler)
107 | ```
108 |
109 | [vapor/vapor#1388](https://github.com/vapor/vapor/pull/1388)
110 |
111 | ### Use Cached Connection For Parameter Lookup
112 |
113 | Fluent makes it easy to fetch a Model from its ID in a routing parameter (e.g. `GET /photos/87`). Just conform the Model to `Parameter`, and it can be used in the route and retrieved from the request:
114 |
115 | ```swift
116 | final class PhotoController: RouteCollection {
117 | func boot(router: Router) throws {
118 | router.get("photos", Photo.parameter, use: getPhoto)
119 | }
120 |
121 | func getPhoto(_ req: Request) throws -> Future {
122 | return try req.parameter(Photo.self)
123 | }
124 | }
125 | ```
126 |
127 | This PR ([vapor/fluent#385](https://github.com/vapor/fluent/pull/385/)) makes that lookup slightly more efficient by using an existing [cached](https://github.com/vapor/database-kit/blob/master/Sources/DatabaseKit/Service/Container%2BCachedConnection.swift) connection, or creating a new [pooled](https://github.com/vapor/database-kit/blob/master/Sources/DatabaseKit/Service/Container%2BConnectionPool.swift) connection.
128 |
129 | [vapor/fluent#385](https://github.com/vapor/fluent/pull/385)
130 |
131 | ## Built For Vapor
132 |
133 | This week we saw quite a few libraries spring up to ease Vapor 3 development. It's super exciting to see people building off the basic types that Vapor provides, and I can't wait to see what else people come up with!
134 |
135 | ### Terse
136 |
137 | Anyone who's done any asynchronous programming in the past 20 years knows all too much about callback hell. While Vapor 3 attempts to limit nested callbacks by encouraging the use of `Promise` chains, sometimes you just can't get around it. Terse, created by [@John-Connolly](https://github.com/John-Connolly) attempts to further alleviate callback hell by introducing functional programming-inspired custom infix operators.
138 |
139 | Syntax example:
140 |
141 | ```swift
142 | func get(with client: RedisClient, for data: RedisData) -> Future {
143 | return client.command("GET", [data])
144 | }
145 |
146 | private func terse(_ req: Request) throws -> Future {
147 | let client = try req.make(RedisClient.self)
148 | return get(with: client, for: "KEY")
149 | >>- curry(get)(client)
150 | >>- curry(get)(client)
151 | >>- curry(get)(client)
152 | <^> RedisResponse.init
153 | }
154 | ```
155 |
156 | [https://github.com/John-Connolly/terse](https://github.com/John-Connolly/terse)
157 |
158 | ### Awesome Vapor
159 |
160 | Speaking of things built for Vapor, this next entry should make you happy if you ever needed to complete a task and wondered for a while whether there wasn't an existing library that would help you reach your goal more easily. Well, wonder no more! The Awesome Vapor document aims to compile everything awesome that works out of the box with Vapor. Besides libraries, the catalogue also contains useful resources for learning more about Vapor and lists well-done open-source projects that might inspire you.
161 |
162 | As is the case with all existing “awesome-” listings for other software projects, Awesome Vapor focuses on quality of its entries, not quantity, so if you decide to follow the list's recommendation, you know you made the right choice.
163 |
164 | [https://github.com/Cellane/awesome-vapor](https://github.com/Cellane/awesome-vapor)
165 |
166 | ### Vapor-Community Extensions
167 |
168 | The community has been coming up with all sorts of useful extensions to core Vapor types, but not all of them belong in Vapor itself for one reason or another. [@gperdomor](https://github.com/gperdomor) has opened up extensions repos for a few packages to fill this void. By adding these to your project, you'll get access to a slew of helper methods! If you're looking to contribute, these are a good opportunity.
169 |
170 | [https://github.com/vapor-community/vapor-extensions](https://github.com/vapor-community/vapor-extensions)
171 | [https://github.com/vapor-community/engine-extensions](https://github.com/vapor-community/engine-extensions)
172 | [https://github.com/vapor-community/async-extensions](https://github.com/vapor-community/async-extensions)
173 | [https://github.com/vapor-community/fluent-extensions](https://github.com/vapor-community/fluent-extensions)
174 |
175 | ## Microtutorial
176 |
177 | Standard promise chains are perfectly fine if only one `Future` needs to complete before you can move onto the next step, but what if you need the results from two `Future`s? One of the problems run into here is that you often need to start embedding promise callbacks and all of a sudden you're back to callback hell.
178 |
179 | Let's say you have a route that creates a `User`. That user has some metadata that is connected to it, but you store it in a different database table to normalize your database. You need to create a `Pivot` so you can get the user's metadata. Because a pivot is based on the models ID's, both the models have to be saved in the database first. To make sure the models are saved before you create the pivot, you can use `Async`'s global `flatMap` method, which takes in a return type, and two or three futures. There is then a completion handler that passes in the results of the futures where you can create your pivot:
180 |
181 | ```swift
182 | let user = User(name: "Jamie", age: 30)
183 | let metadata = Metadata(dateCreated: Date())
184 |
185 | flatMap(to: User.self, user.save(on: request), metadata.save(on: request)) { user, metadata in
186 | return UserMetadata(user, metadata).save(on: request).transform(to: user)
187 | }
188 | ```
189 |
190 | ***
191 | ## Credits:
192 | [@twof](https://github.com/twof)
193 | [@Cellane](https://github.com/Cellane)
194 | [@bensyverson](https://github.com/bensyverson)
195 | [@gwynne](https://github.com/gwynne)
196 | [@calebkleveter](https://github.com/calebkleveter)
197 |
--------------------------------------------------------------------------------
/week5-18-02-26.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | ---
4 | # Week 5
5 |
6 | ## News
7 |
8 | ### Swift NIO
9 | This week, Apple released [Swift NIO](https://github.com/apple/swift-nio) at the [try! Swift](https://www.tryswift.co/events/2018/tokyo/en/) Conference in Tokyo. Apple describes NIO as "a cross-platform asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients." For all you droplets that have been following Vapor 3 development, that means NIO will be replacing a significant portion of the code supporting Vapor behind the scenes. To quote [Tanner](https://github.com/tanner0101),
10 |
11 | > Swift NIO directly replaces:
12 | > - vapor/async (except we will keep our conveniences here, since they are nicer IMO)
13 | > - vapor/sockets (we only supported TCP, they support TCP, UDP, Unix, way better!)
14 | > - vapor/tls (finally, 🙏)
15 | > - vapor/engine (except websockets and our multipart/form-url stuff. we will also port over our conveniences for header names, body, etc)
16 |
17 | Vapor will take a performance hit until NIO's HTTP parser can be optimized, but the long-term benefits greatly outweigh the short-term drawbacks. Having a dedicated team at Apple working on all of the low level code leaves the Vapor team free to make large user-facing improvements with all that time previously spent mucking around with libraries that are being deprecated!
18 |
19 | This raises the question as to whether or not Vapor Nation should cover updates to NIO. What do you think? Drop your opinion in [#vapor-nation](https://vapor.team/) on Slack, or [@VaporNationNews](https://twitter.com/VaporNationNews) on Twitter!
20 |
21 | [https://github.com/apple/swift-nio](https://github.com/apple/swift-nio)
22 |
23 | ### Swift By Sundell Featuring Tanner
24 | [Swift By Sundell](https://www.swiftbysundell.com/) is a Swift podcast hosted by [@JohnSundell](https://github.com/JohnSundell). This week's guest is [@tanner0101](https://github.com/tanner0101), founder of Vapor. John is accepting questions right now, so get them in soon!
25 |
26 | [https://twitter.com/johnsundell/status/970580124998434816](https://twitter.com/johnsundell/status/970580124998434816)
27 |
28 | ## New Features
29 |
30 | ### RSA Encription Implemented and Made Available To JWT
31 | ```swift
32 | // create public and private key (only public required for verification)
33 | let privateKey: Data = ...
34 | let publicKey: Data = ...
35 | let privateSigner = JWTSigner.rs256(key: .private2048(privateKey))
36 | let publicSigner = JWTSigner.rs256(key: .public2048(publicKey))
37 |
38 | // serialize jwt (requires private key)
39 | let payload: TestPayload = ...
40 | var jwt = JWT(payload: payload)
41 | _ = try jwt.sign(using: publicSigner) // throws, can't sign w/ public signer
42 | let data = try jwt.sign(using: privateSigner)
43 |
44 | // parse jwt (public and private key work)
45 | let parsed = try JWT(from: data, verifiedUsing: publicSigner)
46 | let parsed2 = try JWT(from: data, verifiedUsing: privateSigner) // also works
47 | print(parsed.payload)
48 | print(parsed2.payload)
49 | ```
50 |
51 | [vapor/jwt#83](https://github.com/vapor/jwt/pull/83)
52 | [vapor/crypto#39](https://github.com/vapor/crypto/pull/39)
53 |
54 | ### Support For `NULL` In MySQL
55 | Adds support for `NULL` values when fetching data.
56 |
57 | [vapor/mysql#133](https://github.com/vapor/mysql/pull/133)
58 |
59 | ### Added Support For Default Values In PostgreSQL
60 | You can now set default values to be saved to the database for optional properties. The defaults will be used when such properties are `nil` during saving.
61 |
62 |
63 | [vapor/fluent-postgresql#19](https://github.com/vapor/fluent-postgresql/pull/19)
64 |
65 | ### Foundation Client
66 | Adds a `FoundationClient` class which implements the `Client` protocol using `URLSession`. This provides a more configurable (but less performant) alternative to `EngineClient`.
67 |
68 | #### Create a single `FoundationClient`
69 | ```swift
70 | let client = try req.make(FoundationClient.self)
71 | ```
72 |
73 | #### Or prefer `FoundationClient` globally
74 | ```swift
75 | var config = Config.default()
76 | config.prefer(FoundationClient.self, for: Client.self)
77 | let app = try Application(config: config)
78 | let client = try app.make(Client.self)
79 | print(client is FoundationClient) // true
80 | ```
81 |
82 | #### Use just like `EngineClient`
83 | ```swift
84 | let res = try client.send(.get, to: "http://vapor.codes")
85 | debugPrint(res)
86 | ```
87 |
88 | [vapor/vapor#1529](https://github.com/vapor/vapor/pull/1529)
89 |
90 | ## Community Contributions
91 |
92 | ### Made `Router.on()` Public
93 | [@calebkleveter](https://github.com/calebkleveter) opened up the `Router.on(:at:use:)` method for public use, allowing the HTTP method for newly registered routes to be specified as a parameter for routes that automaticly decode the request's body, along with those that don't.
94 |
95 | [vapor/vapor#1528](https://github.com/vapor/vapor/pull/1528)
96 |
97 | ### Added Support For `BIT` and `TIMESTAMP` Types In MySQL
98 | [@PitchLabsAsh](https://github.com/PitchLabsAsh) added support to `vapor/mysql` for the `BIT` and `TIMESTAMP` types. Vapor already had support for `DATETIME`, which [differs slightly from `TIMESTAMP`](https://dev.mysql.com/doc/refman/5.5/en/datetime.html).
99 |
100 | [vapor/mysql#131](https://github.com/vapor/mysql/pull/131)
101 |
102 | ### Add Typealias For UserIDKey
103 | [@0xTim](https://github.com/0xTim) removed some boilerplate by `typealias`ing `WritableKeyPath` to `UserIDKey`
104 |
105 | [vapor/auth#25](https://github.com/vapor/auth/pull/25)
106 |
107 | ## Made For Vapor
108 |
109 | ### Vapor Test Tools
110 | [@rafiki270](https://github.com/rafiki270) says he has "long struggled with testing so I have decided to publish my library of testing helpers as an SPM framework"
111 |
112 | [https://github.com/LiveUI/VaporTestTools](https://github.com/LiveUI/VaporTestTools)
113 |
114 | ## Microtutorial
115 | HTTP requests have held the Internet together for tens of years, but they do have limitations. Some of those limitations have been addressed by [HTTP/2](https://en.wikipedia.org/wiki/HTTP/2), but not quite all. Among those limitations is that the a server must wait for a client to send a request before it can send data to that client. It makes sense that the protocol is designed in this way, and I'd hate to be getting spammed by random servers all day. However, there are many cases where the server wants to be able to push additional data to the client on-demand after a connection has been established, and plain HTTP can't do that. That means if you want to run a server for something like, say, an instant messaging chat, the client must to continuously poll the server to check for new messages. This places a heavy load on both client and server, wasting a lot of time and data.
116 |
117 | [Websockets](https://en.wikipedia.org/wiki/WebSocket) solve this problem by leaving established HTTP connections open and converting them to specially formatted binary data streams. This allows the server and client to exchange information as needed, an ideal solution for realtime applications such as chatting, videoconferencing, and more. The best news of all is, Vapor supports them out of the box!
118 |
119 | ```swift
120 | router.websocket("echo") { (req, ws) in
121 | ws.onString({ (ws, msg) in
122 | ws.send(string: msg)
123 | })
124 | }
125 | ```
126 |
127 | This example sets up a websocket route on `ws://localhost:8080/echo`. Any data sent to that connection will echoed right back.
128 |
129 | ****
130 |
131 | ## Credits
132 | [@twof](https://github.com/twof)
133 | [@gwynne](https://github.com/gwynne)
134 | [@calebkleveter](https://github.com/calebkleveter)
135 |
--------------------------------------------------------------------------------
/week6-18-03-05.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | ---
4 | # Week 6
5 | The Vapor team was very very busy steamrolling ahead with the NIO implementation this week, so no new features, but loads and loads of bugfixes are set to be merged in along with the NIO branches, potentially later this week. If you're getting antsy to see what's been happening though, check out the NIO branches of your favorite packages.
6 |
7 | ## Community Contributions
8 |
9 | ### `GROUP BY` Added To Database Kit
10 | [@rafiki270](https://github.com/rafiki270) implemented the ability to use the SQL `GROUP BY` clause. `GROUP BY` allows the use of advanced aggregate functions in SQL queries. A simple example would be "I want to know how many users signed up each day for the last month." The query for this might be written this way:
11 |
12 | ```sql
13 | SELECT
14 | DATE(signup_date) AS date, COUNT(userId)
15 | FROM Users
16 | WHERE
17 | signup_date BETWEEN DATE_SUB(NOW(), INTERVAL 1 MONTH) AND NOW()
18 | GROUP BY signup_date
19 | ```
20 |
21 | Now Fluent can produce a similar result, though there's no higher-level API for using it yet. Stay tuned!
22 |
23 | [vapor/database-kit#15](https://github.com/vapor/database-kit/pull/15)
24 |
25 | ### Peek
26 | [@pedantix](https://github.com/pedantix) added the ability to peek at data in byte buffers, improved error handling, and added a few other enhancements.
27 |
28 | [vapor/core#96](https://github.com/vapor/core/pull/96)
29 | [vapor/core#98](https://github.com/vapor/core/pull/98)
30 |
31 | ### Fixed Grouping Bug Replacing `AND` with `OR`
32 | [@MrMage](https://github.com/MrMage) fixed a bug where `AND` conditions in database queries would be serialized as `OR` conditions instead!
33 |
34 | [https://github.com/vapor/fluent/pull/399](https://github.com/vapor/fluent/pull/399)
35 |
36 | ### Fixed Typo That Made The Short Flag For `--verbose` = `-c`
37 | [@siemensikkema](https://github.com/siemensikkema) fixed it!
38 |
39 | [vapor/vapor#1535](https://github.com/vapor/vapor/pull/1535/files)
40 |
41 | ### Schema Generation
42 | [@SandorDobi](https://github.com/SandorDobi) added a check for the PostgreSQL server version so Fluent will not attempt to generate `IDENTITY COLUMN`s if the server doesn't support them.
43 |
44 | [vapor/fluent-postgresql#25](https://github.com/vapor/fluent-postgresql/pull/25)
45 |
46 | ## Tutorials
47 |
48 | ### How to use Leaf
49 | Martin Lasek is going through and updating all of his Vapor 2 tutorials for Vapor 3, so we should be seeing a lot from him for a few weeks to come! In this tutorial you'll learn how to use Leaf, Vapor's templating language, to create a web page and populate it with data from your server.
50 |
51 | [https://medium.com/@martinlasek/tutorial-how-to-use-leaf-70d796831ec5](https://medium.com/@martinlasek/tutorial-how-to-use-leaf-70d796831ec5)
52 |
53 | ### Diving into Vapor, Part 1: Up and Running with Vapor 3
54 | In this tutorial we will cover setting up an environment for building web apps with Swift, creating a Vapor project, examining the structure of a project, and creating a simple route. If you're just now getting started with Vapor, this is a great place to begin.
55 |
56 | [https://theswiftwebdeveloper.com/diving-into-vapor-part-1-up-and-running-with-vapor-3-edab3c79aab9](https://theswiftwebdeveloper.com/diving-into-vapor-part-1-up-and-running-with-vapor-3-edab3c79aab9)
57 |
58 | ## Talks
59 |
60 | ### NIO Announcement and Introduction At try! Swift Tokyo
61 | If you want to know more about [NIO](https://github.com/apple/swift-nio), the new asynchronous underpinnings of Vapor, check out this talk by Norman Maurer of Apple and [NETTY](https://netty.io/) fame! Norman goes over a comparison of async methodologies, the motivation behind NIO, and then a rundown of how it works and how he thinks it will be applied.
62 |
63 | [https://www.youtube.com/watch?v=QJ3WG9kRLMo](https://www.youtube.com/watch?v=QJ3WG9kRLMo)
64 |
65 | ## Microtutorial
66 | This week we'll be talking about how to set up your own services by creating a service you can use to send emails from your Vapor apps. You can find the repo for [`VaporMailgunService` here](https://github.com/twof/VaporMailgunService).
67 |
68 | If you've used `Leaf` or `EngineClient` before, you've already used a Service!
69 |
70 | ```swift
71 | // config
72 | try services.register(LeafProvider())
73 |
74 | // router
75 | let leaf = try req.make(LeafRenderer.self)
76 | ```
77 |
78 | First we set up the protocol that our service will be registered to.
79 | ```swift
80 | public protocol MailgunProvider: Service {
81 | var apiKey: String { get }
82 | var customURL: String { get }
83 | var numMailSent: Int { get set }
84 | mutating func sendMail(data content: MailgunFormData, on req: Request) throws -> Future
85 | }
86 | ```
87 |
88 | Then we conform to our protocol and implement our service. In this case, we'll be sending an email.
89 | ```swift
90 | // Singleton
91 | public class MailgunEngine: MailgunProvider {
92 | public var apiKey: String
93 | public var customURL: String
94 | public var numMailSent: Int = 0
95 |
96 | public init(apiKey: String, customURL: String) {
97 | self.apiKey = apiKey
98 | self.customURL = customURL
99 | }
100 |
101 | public func sendMail(data content: MailgunFormData, on req: Request) throws -> Future {
102 | // Send an email using the config from content
103 | numMailSent += 1
104 | }
105 | }
106 |
107 | // Non-singleton
108 | public struct MailgunStructEngine: Mailgun {
109 | public var apiKey: String
110 | public var customURL: String
111 | public var numMailSent: Int = 0
112 |
113 | public init(apiKey: String, customURL: String) {
114 | self.apiKey = apiKey
115 | self.customURL = customURL
116 | }
117 |
118 | public mutating func sendMail(data content: MailgunFormData, on req: Request) throws -> Future {
119 | // Send an email using the config from content
120 | numMailSent += 1
121 | }
122 | }
123 | ```
124 |
125 | Then we can configure our service for use.
126 | ```swift
127 | // configure.swift
128 | let mailgunEngine = MailgunEngine(apiKey: "", customURL: "mg.example.com")
129 | services.register(mailgunEngine, as: Mailgun.self)
130 | ```
131 |
132 | And finally use our service to send some email!
133 | ```swift
134 | // routes.swift
135 | var mailgunClient = try req.make(Mailgun.self)
136 | print(mailgunClient.numMailSent)
137 | return try mailgunClient.sendMail(data: content, on: req)
138 | ```
139 | Using the singleton version and sending mail three times will print
140 |
141 | ```
142 | 0
143 | 1
144 | 2
145 | ```
146 | but using the non singleton version will print
147 | ```
148 | 0
149 | 0
150 | 0
151 | ```
152 | because a new version is created with each request. In most cases, you'll want to create `Service` structs for your own use, because `Service` singletons are not guaranteed to be thread safe. To read more about `Service`s, check out the newly updated section of the docs.
153 |
154 | [https://github.com/twof/VaporMailgunService](https://github.com/twof/VaporMailgunService)
155 | [https://docs.vapor.codes/3.0/getting-started/services/](https://docs.vapor.codes/3.0/getting-started/services/)
156 |
157 |
158 | ***
159 | ## Credits
160 | [@twof](https://github.com/twof)
161 | [@gwynne](https://github.com/gwynne)
162 |
--------------------------------------------------------------------------------
/week7-18-03-12.md:
--------------------------------------------------------------------------------
1 | # Week 7 & 8
2 |
3 | ## News
4 | RC2 was tagged for all packages last week, and with it, NIO now handles all non-blocking async for Vapor! 🎉🎉🎉 If you want to know more about the impact of NIO, check out Tanner on Swift by Sundell and Week 5 of Vapor Nation. Many [API docs](https://api.vapor.codes) were also released this week. API docs are less like the tutorial style you'd find at [docs.vapor.codes](https://docs.vapor.codes) and more like traditional docs you'd find for other libraries and frameworks.
5 |
6 | ## New Features
7 |
8 | ### Adds Ability To Execute Shell Commands
9 | adds a new Process.execute method for executing shell commands.
10 |
11 | ```swift
12 | let result = try Process.execute("echo", "hi")
13 | print(result) /// "hi"
14 | ```
15 |
16 | [vapor/core#100](https://github.com/vapor/core/pull/100)
17 |
18 | ### Simplify The Services System
19 | Simplifies the service system and internal caching.
20 |
21 | [vapor/service#18](https://github.com/vapor/service/pull/18)
22 |
23 | ### Use foundation base64 + async deprecations
24 | * use foundation for base64 coding
25 | * adds escape/unescape methods for base64 strings and data
26 |
27 | [vapor/core#103](https://github.com/vapor/core/pull/103)
28 |
29 | ### MySQL Query Pipelining
30 | MySQL now supports multiple queries being enqueued when one is still running
31 |
32 | [vapor/mysql#145](https://github.com/vapor/mysql/pull/145)
33 | [vapor/fluent#411](https://github.com/vapor/fluent/issues/411)
34 | [vapor/fluent#413](https://github.com/vapor/fluent/pull/413)
35 |
36 | ### New SQL Query Operators
37 |
38 | [vapor/fluent#423](https://github.com/vapor/fluent/pull/423)
39 | [vapor/fluent#424](https://github.com/vapor/fluent/pull/424)
40 |
41 | ### Adds Command To Revert Migrations
42 |
43 | [vapor/fluent#421](https://github.com/vapor/fluent/pull/421)
44 |
45 | ### Use Environment For Command Line Arguments
46 | * move to using the `Environment.commandLine` property for accessing CLI arguments. An improvement over using a statically available property that could create issues for projects with multiple applications.
47 | * Adds `runningServer` property.
48 | * Adds `asyncBoot` and `asyncRun` methods to Application
49 |
50 | [vapor/vapor#1570](https://github.com/vapor/vapor/pull/1570)
51 |
52 | ### Services and Database Connections Are Now Extendable
53 | `Extendable` is a protocol which allows you to store data on instances of the protocol.
54 | `DatabaseConnection` and `Service` are now `Extendable`. This will allow higher-level libraries to store things on a connection without resorting to global caches which may leak memory.
55 |
56 | [vapor/service#19](https://github.com/vapor/service/pull/19)
57 | [vapor/database-kit#19](https://github.com/vapor/database-kit/pull/19)
58 |
59 | ### Decoding Errors Result In 400 Response
60 |
61 | [vapor/vapor#1563](https://github.com/vapor/vapor/pull/1563)
62 |
63 | ## NIO
64 |
65 | ### HTTP Pipelining
66 | [HTTP pipelining](https://en.wikipedia.org/wiki/HTTP_pipelining) is a relatively new technique that's only supported by a couple browsers at the present, but it has huge potential for performance gains. You can find the [benchmarks](https://github.com/apple/swift-nio/pull/62#issuecomment-372657330) yielding around 3x performance gains in a comment a ways down the thread.
67 |
68 | [apple/swift-nio#62](https://github.com/apple/swift-nio/pull/62)
69 |
70 | ### Discussion On Performance Improvements For HTTP
71 | Vapor lost some performance when it switched to NIO, but optimizing NIO's HTTP parser should improve that by a lot.
72 |
73 | [apple/swift-nio#141](https://github.com/apple/swift-nio/issues/141)
74 |
75 | ### Discussion On `flatMap` vs `then` For Future Interaction
76 | `flatMap` comes from the functional programming world and is more technically correct, but `then` is more consistent with other promise/future implementations. What do you think?
77 |
78 | [apple/swift-nio#213](https://github.com/apple/swift-nio/issues/213)
79 |
80 | ## Community Contributions
81 |
82 | ### Tests That A Date's Milliseconds Are Persisted
83 | [@MrMage](https://github.com/MrMage)
84 |
85 | [vapor/fluent-postgresql#27](https://github.com/vapor/fluent-postgresql/pull/27)
86 |
87 | ### Prevent Foreign Keys From Being Created Twice
88 | [@MrMage](https://github.com/MrMage)
89 |
90 | [vapor/database-kit#17](https://github.com/vapor/database-kit/pull/17)
91 |
92 | ### Adds Microsecond Support To MySQL and PostgreSQL
93 | [@MrMage](https://github.com/MrMage)
94 |
95 | [vapor/mysql#141](https://github.com/vapor/mysql/pull/141)
96 | [vapor/postgresql#29](https://github.com/vapor/postgresql/pull/29)
97 |
98 | ### Release The First Awaiter When A Promise Gets Fulfilled
99 | [@MrMage](https://github.com/MrMage)
100 |
101 | [vapor/async#79](https://github.com/vapor/async/pull/79)
102 |
103 | ### Console Can Now Parse Short Flags Properly
104 | [@siemensikkema](https://github.com/siemensikkema)
105 |
106 | [vapor/console#59](https://github.com/vapor/console/pull/59)
107 |
108 | ### Fix DateMiddleWare cached timestamp return logic
109 | [@grundoon](https://github.com/grundoon) noted that timestamps were being cached and never recalculated.
110 |
111 | [vapor/vapor#1554](https://github.com/vapor/vapor/pull/1554)
112 |
113 | ### Default Postgres Port to 5432 When Not Supplied
114 | [@0xTim](https://github.com/0xTim) simplified PSQL config by defaulting to the port most setups of PSQL will be using.
115 |
116 | [vapor/postgresql#34](https://github.com/vapor/postgresql/pull/34)
117 |
118 | ### Fix a memory leak in `PostgreSQLConnection`
119 | [@MrMage](https://github.com/MrMage) -
120 | >PostgreSQLTableNameCache holds a PostgreSQLConnection future. Once that future is fulfilled, it strongly holds a reference to PostgreSQLConnection. That connection in turn holds the table name cache, so we have a reference cycle. This causes the table name cache and its connection to never get released. This is relevant when testing, if the tests are set up such that each test creates a new Database.
121 |
122 | [vapor/postgresql#31](https://github.com/vapor/postgresql/pull/31)
123 |
124 | ### Avoid double encoding of query params when using FoundationClient [Vapor 2]
125 | [@steffendsommer](https://github.com/steffendsommer)
126 |
127 | [https://github.com/vapor/engine/pull/244](https://github.com/vapor/engine/pull/244)
128 |
129 | ### Remove an unused argument in PostgreSQLDatabase.init
130 | [@MrMage](https://github.com/MrMage) cleaned up `PostgreSQLDatabase.init`
131 |
132 | [vapor/postgresql#38](https://github.com/vapor/postgresql/pull/38)
133 |
134 | ### Close a `PostgreSQLConnection`'s channel on deinit
135 | [@MrMage](https://github.com/MrMage)
136 |
137 | [vapor/postgresql#36](https://github.com/vapor/postgresql/pull/36)
138 |
139 | ### Fixing join mapping
140 | [@rafiki270](https://github.com/rafiki270)
141 |
142 | [vapor/fluent#410](https://github.com/vapor/fluent/pull/410)
143 |
144 | ### Added connection string parsing for PostgreSQLDatabaseConfig
145 | [@pedantix](https://github.com/pedantix) enabled `PostgreSQLDatabaseConfig` to be initialized with a PSQL URL. This is typically the format you'll get your credentials in in you're using a service like Heroku
146 |
147 | [vapor/postgresql#25](https://github.com/vapor/postgresql/pull/25)
148 |
149 | ### Correctly fetch LAST_INSERT_ID() on model creation
150 | [@jseibert](https://github.com/jseibert) allows Fluent to handle MySQL's [LAST_INSERT_ID](https://dev.mysql.com/doc/refman/5.7/en/information-functions.html#function_last-insert-id)
151 |
152 | [vapor/fluent-mysql#85](https://github.com/vapor/fluent-mysql/pull/85)
153 |
154 | ### Make `BenchmarkTimestampable` care more about fractional-second parts
155 | [@MrMage](https://github.com/MrMage) made benchmarking more precise
156 |
157 | ```swift
158 | if tanner.createdAt?.isWithin(seconds: 0.1, of: Date()) != true {
159 | self.fail("timestamps should be current")
160 | }
161 | ```
162 |
163 | [vapor/fluent#406](https://github.com/vapor/fluent/pull/406)
164 |
165 | ### Use microsecond precision on new time and datetime columns
166 | [@MrMage](https://github.com/MrMage) made MySQL's time types more precise
167 |
168 | [vapor/fluent-mysql#84](https://github.com/vapor/fluent-mysql/pull/84)
169 |
170 | ### Made FluentError init method public
171 | [@calebkleveter](https://github.com/calebkleveter)
172 |
173 | ```swift
174 | guard let id = model.id else {
175 | throw FluentError(identifier: "noID", reason: "A model must have an ID to be connected to a pivot"
176 | }
177 | ```
178 |
179 | [vapor/fluent#408](https://github.com/vapor/fluent/pull/408)
180 |
181 | ### Created QueryBuilder.set method
182 | [@calebkleveter](https://github.com/calebkleveter)'s PR adds a .set(\_:to:) method to the QueryBuilder type, allowing you to run SET queries on a model.
183 |
184 | ```swift
185 | Player.query(on: request).filter(\.points == 10_000).set(\.rank, to: 10)
186 | ```
187 |
188 | [vapor/fluent#394](https://github.com/vapor/fluent/pull/394)
189 |
190 | ### Adapt To Updates In Crypto
191 | [@pedantix](https://github.com/pedantix) updated the JWT package to work with the most recent updates to Crypto
192 |
193 | [vapor/jwt#86](https://github.com/vapor/jwt/pull/86)
194 |
195 | ### Adding Group By
196 | [@rafiki270](https://github.com/rafiki270)
197 |
198 | [vapor/fluent#403](https://github.com/vapor/fluent/pull/403)
199 |
200 | ### Made `QueryBuilder.connection` Property Public
201 | [@calebkleveter](https://github.com/calebkleveter)
202 |
203 | [vapor/fluent#414](https://github.com/vapor/fluent/pull/414)
204 |
205 | ### Export Async To Avoid An Import When Conforming To Fluent Protocols
206 | [@rafiki270](https://github.com/rafiki270)
207 |
208 | [vapor/fluent#417](https://github.com/vapor/fluent/pull/417)
209 |
210 | ### Changes Default Connector In Name Of Pivot Table From ‘+’ To ‘_’
211 | [@abbasmousavi](https://github.com/abbasmousavi) addressed an issue where the `+` symbol was giving a few databases a hard time.
212 |
213 | [vapor/fluent#422](https://github.com/vapor/fluent/pull/422)
214 |
215 | ### Check to see if path is a directory as well
216 | [@rafiki270](https://github.com/rafiki270) fixed a bug where requests were being intercepted by `FileMiddleware`.
217 |
218 | [vapor/vapor#1560](https://github.com/vapor/vapor/pull/1560)
219 |
220 | ## Articles
221 |
222 | ### Caleb Kleveter On Moving From Vapor 2 -> Vapor 3 In Production At Skelpo
223 |
224 | [https://www.skelpo.com/blog/vapor2-to-vapor3/](https://www.skelpo.com/blog/vapor2-to-vapor3/)
225 |
226 | ### How To Perform Fluent Queries
227 | This tutorial is an introduction for how to perform simple filter/sort queries on a database using Vapor's ORM, Fluent.
228 |
229 | [https://www.vaporforums.io/thread/37](https://www.vaporforums.io/thread/37)
230 |
231 | ### How To Write Models Using Fluent
232 | This tutorial will show you how to implement a simple user model, store it to the database, get it back from the database and pass it to the view.
233 |
234 | [https://medium.com/@martinlasek/tutorial-how-to-write-models-using-fluent-e9482d335a5f](https://medium.com/@martinlasek/tutorial-how-to-write-models-using-fluent-e9482d335a5f)
235 |
236 | ### Persisting Data In Vapor 3
237 | In this tutorial, we will be covering how to connect to a relational database (both PostgreSQL and MySQL) and then storing data in it.
238 |
239 | [https://theswiftwebdeveloper.com/diving-into-vapor-part-2-persisting-data-in-vapor-3-c927638301e8](https://theswiftwebdeveloper.com/diving-into-vapor-part-2-persisting-data-in-vapor-3-c927638301e8)
240 |
241 | ## Talks
242 |
243 | ### Tanner Nelson On Swift by Sundell
244 | Tanner talks with John Sundell about NIO, where he sees the future of Vapor, his own background, the inspiration for Vapor 3, and more!
245 |
246 | [https://www.swiftbysundell.com/podcast/18](https://www.swiftbysundell.com/podcast/18)
247 |
248 | ## Writing Credits
249 | [@twof](https://github.com/twof)
250 | [@Yasumoto](https://github.com/Yasumoto)
251 |
--------------------------------------------------------------------------------