-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #20 from twof/draft
Week 4 (WIP)
- Loading branch information
Showing
15 changed files
with
596 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<browserconfig> | ||
<msapplication> | ||
<tile> | ||
<square150x150logo src="/mstile-150x150.png"/> | ||
<TileColor>#da532c</TileColor> | ||
</tile> | ||
</msapplication> | ||
</browserconfig> |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
{ | ||
"name": "", | ||
"short_name": "", | ||
"icons": [ | ||
{ | ||
"src": "/android-chrome-192x192.png", | ||
"sizes": "192x192", | ||
"type": "image/png" | ||
}, | ||
{ | ||
"src": "/android-chrome-384x384.png", | ||
"sizes": "384x384", | ||
"type": "image/png" | ||
} | ||
], | ||
"theme_color": "#ffffff", | ||
"background_color": "#ffffff", | ||
"display": "standalone" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,165 @@ | ||
# Week 4 | ||
|
||
## New Features | ||
|
||
### Services Created With Reference Types Are Always Singletons | ||
<!--- | ||
HELP NEEDED: | ||
only leaving this one in without a description right now because it's important to know. A description should be written | ||
---> | ||
|
||
[vapor/service#14](https://github.com/vapor/service/pull/14) | ||
|
||
### Both `struct` and `class` SQLite Models No Longer Require `init` Methods To Be Defined | ||
``` | ||
struct Foo: SQLiteModel { | ||
var id: Int? | ||
var name: String | ||
} | ||
final class Bar: SQLiteModel { | ||
var id: Int? | ||
var name: String | ||
} | ||
``` | ||
|
||
[vapor/fluent#380](https://github.com/vapor/fluent/pull/380) | ||
|
||
### Debuggable | ||
Adds some additional functionality to assist with debugging. | ||
<!--- What functionality? How would a user access it? ---> | ||
|
||
[vapor/core#92](https://github.com/vapor/core/pull/92) | ||
|
||
<!--- | ||
I don't understand what this one is doing. If you'd like to write a description and uncomment, that'd be awesome | ||
### Allow Session To Be Passed In | ||
#### HELP NEEDED: Write description | ||
[vapor/engine#237](https://github.com/vapor/engine/pull/237) | ||
---> | ||
|
||
### Client Redirection | ||
`EngineClient` will now follow redirects as indicated by a few of the HTTP status codes in the 300 range. | ||
|
||
[vapor/vapor#1480](https://github.com/vapor/vapor/pull/1480) | ||
|
||
## Under The Hood | ||
|
||
### Lazy Middleware | ||
- creates one set of middleware per event loop, preventing race conditions in middleware | ||
- losslessly optimizes DateMiddleware to only calculate a new RFC1123 timestamp every second | ||
- 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. | ||
|
||
```swift | ||
router.grouped(DateMiddleware.self).get("datetest") { req in | ||
return HTTPStatus.ok | ||
} | ||
``` | ||
|
||
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. | ||
|
||
- adds application-wide timeout for requests taking longer than 30 seconds | ||
|
||
[vapor/vapor#1507](https://github.com/vapor/vapor/pull/1507) | ||
|
||
## Help Wanted | ||
|
||
### Leaf Syntax Highlighting For Intelijay | ||
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. | ||
|
||
[vapor/leaf#76](https://github.com/vapor/leaf/issues/76) | ||
|
||
## Community Contributions | ||
|
||
### Fix an Xcode Crash In API Template | ||
Anyone who's used Vapor knows that Xcode tends to experience problems during Vapor development that you wont have seen if you've only used Xcode for iOS. For example, if an error is raised to the top level in iOS, it gets caught by `AppDelegate`, but Vapor apps don't have an `AppDelegate` equivalent, so instead errors raised to to the top level crash Xcode. That 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 and prevent Xcode from crashing. | ||
|
||
[vapor/api-template#45](https://github.com/vapor/api-template/pull/45) | ||
|
||
### MySQL Fixes To More Closely Conform To Client-Server Protocol | ||
[@SandorDobi](https://github.com/SandorDobi) noticed a few places where Vapor's MySQL package wasn't quite conforming to MySQL's protocols, and fixed that. | ||
|
||
[vapor/mysql#127](https://github.com/vapor/mysql/pull/127) | ||
|
||
### Dependency Updates | ||
Same as last week. Tracking which dependencies need updates is hard! | ||
|
||
[vapor/auth#24](https://github.com/vapor/auth/pull/24) | ||
|
||
### Updated RoutingGroups For Better Handling of Middleware | ||
After some [discussion](https://github.com/vapor/vapor/issues/1398), [@MaximBazarov](https://github.com/MaximBazarov) made updates to Vapor's routing groups. | ||
```swift | ||
let users = router.group("user").using(SomeMiddleware()) | ||
users.get("auth", use: userAuthHandler) | ||
``` | ||
|
||
[vapor/vapor#1388](https://github.com/vapor/vapor/pull/1388) | ||
|
||
### Use Cached Connection For Parameter Lookup | ||
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: | ||
|
||
```swift | ||
final class PhotoController: RouteCollection { | ||
func boot(router: Router) throws { | ||
router.get("photos", Photo.parameter, use: getPhoto) | ||
} | ||
|
||
func getPhoto(_ req: Request) throws -> Future<Photo> { | ||
return try req.parameter(Photo.self) | ||
} | ||
} | ||
``` | ||
|
||
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. | ||
|
||
[vapor/fluent#385](https://github.com/vapor/fluent/pull/385) | ||
|
||
## Built For Vapor | ||
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! | ||
|
||
### Terse | ||
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. | ||
|
||
Syntax example: | ||
|
||
```swift | ||
func get(with client: RedisClient, for data: RedisData) -> Future<RedisData> { | ||
return client.command("GET", [data]) | ||
} | ||
|
||
private func terse(_ req: Request) throws -> Future<RedisResponse> { | ||
let client = try req.make(RedisClient.self) | ||
return get(with: client, for: "KEY") | ||
>>- curry(get)(client) | ||
>>- curry(get)(client) | ||
>>- curry(get)(client) | ||
<^> RedisResponse.init | ||
} | ||
``` | ||
|
||
[https://github.com/John-Connolly/terse](https://github.com/John-Connolly/terse) | ||
|
||
### Awesome Vapor | ||
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 isn't an existing library that would help you reach your goal easier. Well, wonder no more as 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. | ||
|
||
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. | ||
|
||
[https://github.com/Cellane/awesome-vapor](https://github.com/Cellane/awesome-vapor) | ||
|
||
### Vapor-Community Extensions | ||
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. For those, [@gperdomor](https://github.com/gperdomor) opened up extensions repos for a few packages. 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. | ||
|
||
[https://github.com/vapor-community/vapor-extensions](https://github.com/vapor-community/vapor-extensions) | ||
[https://github.com/vapor-community/engine-extensions](https://github.com/vapor-community/engine-extensions) | ||
[https://github.com/vapor-community/async-extensions](https://github.com/vapor-community/async-extensions) | ||
[https://github.com/vapor-community/fluent-extensions](https://github.com/vapor-community/fluent-extensions) | ||
|
||
## Microtutorial | ||
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. | ||
|
||
*** | ||
## Credits: | ||
[@twof](https://github.com/twof) | ||
[@Cellane](https://github.com/Cellane) | ||
[@bensyverson](https://github.com/bensyverson) |