我正在使用Vapor,第一件事就是使用 get 方法,如下所示:
drop.get("hello") { request in
return "Hello, world!"
}
Run Code Online (Sandbox Code Playgroud)
现在我的理解是闭包就像类型函数的变量。正确的?get在这里我看到我们在名为 drop 的类实例上调用一个方法Droplet并传入一个字符串。
在 get 方法体内调用/传递闭包是怎么回事?我怎么读这个?
我有一个路由处理程序,它为我的登录页面返回一个 Future,定义如下:
func boot(router: Router) throws {
let authSessionRoutes = router.grouped(User.authSessionsMiddleware())
authSessionRoutes.get("/login", use: loginHandler)
}
func loginHandler(_ req: Request) throws -> Future<View> {
return try req.view().render("loginPage")
}
Run Code Online (Sandbox Code Playgroud)
当用户未连接时,这很有效,但我想添加逻辑,以便任何尝试访问此页面的经过身份验证的用户都将被重定向到他们的主页。
这是我尝试过的:
func loginHandler(_ req: Request) throws -> Future<View> {
if let _ = try req.authenticated(User.self) {
return req.redirect(to: "/") <<< Cannot convert return expression of type 'Response' to return type 'EventLoopFuture<View>'
}
return try req.view().render("loginPage")
}
Run Code Online (Sandbox Code Playgroud)
这告诉我,由于我的 loginHandler 应该返回 a Future<View>,因此返回 aResponse不符合方法的定义。
处理这种情况的最佳方法是什么?
编辑 :
谢谢你的回答 !我的最终代码如下所示:
func loginHandler(_ …Run Code Online (Sandbox Code Playgroud) 我正在使用 Vapor 开发一个简单的 Web API。为了提供更多背景信息,我是后端开发的新手。
API 的使用者将是一个 iOS 应用程序。目前,我不需要用户注册即可使用该应用程序。我想保持这种状态。
另一方面,我希望进行一些身份验证,以避免任何人都可以使用我正在开发的 API。
寻找信息我发现了如何实施身份验证。但是我所看到的示例是基于在后端为应用程序的每个用户创建用户。我不想做的事。当我们使用第三方 api 时,我想像往常一样使用 api 密钥。
我怎么能用 Vapor 进行“api-key 认证”?
或者,我应该创建一个唯一的用户/密码,它由 iOS 应用程序的所有用户(使用 API)共享,然后使用基本或令牌身份验证?
非常感谢!
卡洛斯
我正在试验一个独立的脚本,该脚本将使用 Vapor 和 Fluent 查询 Postgres 数据库。在普通的 Vapor API 应用程序中,这只需通过以下方式完成:
router.get("products") { request in
return Product.query(on: request).all()
}
Run Code Online (Sandbox Code Playgroud)
然而,在一个独立的脚本中,由于没有“请求”,我陷入了用什么来替换“请求”的问题DatabaseConnectable上。这是我陷入困境的地方:
import Fluent
import FluentPostgreSQL
let databaseConfig = PostgreSQLDatabaseConfig(hostname: "localhost",
username: "test",
database: "test",
password: nil)
let database = PostgreSQLDatabase(config: databaseConfig)
let foo = Product.query(on: <??WhatDoIPutHere??>)
Run Code Online (Sandbox Code Playgroud)
我尝试创建一个符合 的对象DatabaseConnectable,但无法弄清楚如何正确地使该对象符合 。
配置:
蒸气 4 | 更新测试版和软件包 | macOS Catalina v.10.15.3 | XCode 11.4 测试版 2 | 引导 CDN 4.4.1
我无法切换导航栏按钮。我不确定这是否是 Leaf 中的错误。我已经按照正确的顺序实现了 Bootstrap 和 CSS。尝试运行此代码。不要忘记将浏览器窗口的大小调整为移动或平板电脑视图以显示导航栏切换按钮。这是我的叶子代码:
// 基.叶
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1.0"/>
<meta name="apple-mobile-web-app-capable" content="yes" />
<!-- <link rel="stylesheet" href="/styles/bootstrap.min.css"/>-->
<link rel="stylesheet" href="/fonts/fa/css/all.min.css"/>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<link rel="stylesheet" href="/styles/main.css"/>
<link rel="stylesheet" href="/styles/header.css"/>
<link rel="stylesheet" href="/styles/footer.css"/>
<title>#(metaContent.title)</title>
<meta name="description" content="#(metaContent.description)"/>
</head>
<body>
<header>
<nav class="navbar navbar-expand-md navbar-dark fixed-top bg-dark">
<a class="navbar-brand" href="#">Carousel</a>
<button …Run Code Online (Sandbox Code Playgroud) 在全新安装的 Vapor(来自homebrew)中,我调用:
vapor new Bridge -> 成功vapor xcode -> 成功y (询问是否要在 Xcode 中打开项目)-> 打开 Xcode 项目vapor --version -> 3.1.10vapor build -> 失败我得到的错误是:
[1/3] Compiling App configure.swift
/Users/josh/Applications/Xcode/Projects/Bridge/Sources/App/configure.swift:31:49: error: reference to member 'sqlite' cannot be resolved without a contextual type
migrations.add(model: Todo.self, database: .sqlite)
~^~~~~~
[2/3] Compiling App app.swift
Run Code Online (Sandbox Code Playgroud)
版本号:
10.15.3 (19D76)11.4 (11E146)3.1.105.2任何帮助找出如何解决此错误表示赞赏!如果我能提供更多信息,请告诉我。谢谢!
我们正在使用 Vapor 将我们的 Laravel 应用程序部署到 AWS Lambda。
小改动后(引入了 10 行),通过 GitHub 操作的部署过程失败并显示以下消息:
Message: Your application exceeds the maximum size allowed by AWS Lambda.
Run Code Online (Sandbox Code Playgroud)
现在我们不能部署到这个环境(开发)。所有其他分支(暂存、生产)都很好,我们可以使用它们。
在上次部署之间没有引入新的库或任何大的变化。
通过 Vapor CLI 部署也失败并显示相同的消息。
我们可以在哪里搜索问题根源的任何想法?
所以我有模特的名字Organization,User和App。应用程序和用户都属于组织。
final class Organization: Model, Content {
static let schema = "organizations"
@ID(key: .id)
var id: UUID?
@Field(key: "name")
var name: String
@Children(for: \.$organization)
var users: [User]
}
final class App: Model, Content {
static let schema = "apps"
@ID(key: .id)
var id: UUID?
@Field(key: "name")
var name: String
@Parent(key: "organization_id")
var organization: Organization
}
final class User: Model, Content {
static let schema = "users"
@ID(key: .id)
var id: UUID?
@Field(key: "email")
var …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用 Repository 模式将一些代码从 Vapor 3 迁移到 Vapor 4。我已经阅读了 Vapor 4文档中有关此特定模式的文档,我想我对它的大部分了解。
然而,我没有得到的一件事是在Application扩展中设置存储库工厂的方式。文档中的示例显示了这一点:
extension Application {
private struct UserRepositoryKey: StorageKey {
typealias Value = UserRepositoryFactory
}
var users: UserRepositoryFactory {
get {
self.storage[UserRepositoryKey.self] ?? .init()
}
set {
self.storage[UserRepositoryKey.self] = newValue
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果我正确阅读了 getter 方法(我可能不是 - 我离 Swift 专家还很远),UserRepositoryFactory将创建一个新的结构实例并在app.users引用时返回。但是,当时似乎没有self.storage[UserRepositoryKey.self]以任何方式更改的内容。因此,如果我碰巧app.users连续访问两次,我会得到 2 个不同的实例返回给我,并且self.storage[UserRepositoryKey.self]将保持设置为nil.
按照文档中的其余示例代码,它似乎定义make了工厂在配置应用程序时将使用的函数,如下所示:
app.users.use { req in
DatabaseUserRepository(database: req.db)
}
Run Code Online (Sandbox Code Playgroud)
这里似乎 …
我运行一个处理大文件(上传和下载)的网站。目前我正在将网站从 Perfect 过渡到 Vapor。在 Perfect 中,将文件流式传输给用户,然后在文件完成后执行一些操作相对简单。
我试图在 Vapor 中做同样的事情,但我似乎无法弄清楚如何在流完成时设置回调,以及当它完成时,它是否完全被用户下载或有中断。
有谁知道如何做到这一点?这是我尝试过的一些事情。
这是基本结构
func downloadFile(request: Request) -> EventLoopFuture<Response> {
//do some authentication stuff here
let promise = request.eventLoop.makePromise(of: Response.self)
let response = request.fileio.streamFile(at: "somePath")
promise.succeed(response)
let future = promise.futureResult
return future
}
Run Code Online (Sandbox Code Playgroud)
第一次修改
func downloadFile(request: Request) -> EventLoopFuture<Response> {
//do some authentication stuff here
let promise = request.eventLoop.makePromise(of: Response.self)
let response = request.fileio.streamFile(at: "somePath")
promise.succeed(response)
let future = promise.futureResult
future.eventLoop.next().execute {
//run some post-download processing here.
//ideally I would like to know …Run Code Online (Sandbox Code Playgroud)