在 GraphQL 中编辑类时的正确工作流程

Posted

技术标签:

【中文标题】在 GraphQL 中编辑类时的正确工作流程【英文标题】:The right workflow when editing class in GraphQL 【发布时间】:2020-08-01 03:48:15 【问题描述】:

我使用的是 xcode 11.4 和 swift4,我目前正在使用 AWS GraphQL 并学习正确的工作流程。我的amplify.xyz 配置设置为

push=true
modelgen=true
profile=default
envName=amplify

以便模型在创建/编辑时生成。在schema.graphql我定义用户:

type User @model 
    id: ID!
    firstName  : String!
    lastName   : String!
    handle     : String!
    email      : String!

并构建/运行应用程序,并能够按预期创建/读取user 的实例。然后假设我添加了一个简单的新字段User @model,这样我就有了:

type User @model 
    id: ID!
    firstName  : String!
    lastName   : String!
    handle     : String!
    email      : String!
    blank      : String!

然后清理构建文件夹,并重新构建应用程序。然后我得到莫名其妙的错误

No such module 'Amplify' HomeController.swift

即使更改 Model 类和 Amplify 似乎无关。如果我删除blank,然后清理并重建,一切都会恢复正常。这种行为的原因是什么?

作为参考,这是我的 podfile:

# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'

target 'alpha' do
  # Comment the next line if you don't want to use dynamic frameworks
  use_frameworks!

  # Pods for alpha
    pod 'amplify-tools'

    pod 'Amplify'
    pod 'AWSPluginsCore'
    pod 'AmplifyPlugins/AWSAPIPlugin'

    pod 'AWSMobileClient', '~> 2.13.0'      # Required dependency
    pod 'AWSUserPoolsSignIn', '~> 2.13.0'

    pod 'AWSAppSync', '~> 3.1.0'
    pod 'AWSMobileClient', '~> 2.13.0'
    pod 'AWSAuthUI', '~> 2.13.0'
    pod 'AWSUserPoolsSignIn', '~> 2.13.0'

end

______________________ 更新 ___________________

按照 Julien S 的建议,我是 amplify push,并确保 amplify/generated/models 中的所有文件都移动到每个 (https://aws-amplify.github.io/docs/ios/start?ref=amplify-iOS-btn) 的***目录中。现在这个问题No such module 'Amplify' HomeController.swift 解决了。但是,我再也找不到模型更新之前保存的数据。作为参考,当用户创建帐户时,我会访问用户的令牌并将其与用户的电子邮件一起保存。然后下次用户打开应用程序时,我再次获取令牌并通过令牌查询用户数据库。相关代码:

class CognitoPoolProvider : AWSCognitoUserPoolsAuthProviderAsync 

    func getLatestAuthToken(_ callback: @escaping (String?, Error?) -> Void) 

        AWSMobileClient.default().getTokens  (token, error) in
            if let error = error 
                callback(nil,error)
            
            callback(token?.accessToken?.tokenString, error)
        
    

在 MainController.swift 中:

override func viewDidLoad() 
    super.viewDidLoad()

    // get user token
    let pool = CognitoPoolProvider();

    pool.getLatestAuthToken  (token, error) in

        if let error = error 

            print("error: \(error)")

         else 
            self.getUserData(token: token!)
        
    


func getUserData(token:String)

    print("token >>>> \(token)")

   // this is successful. you got all the user stuff
   // when you change the user model, you can no longer query the user
   let _ = Amplify.API.query(from: User.self, byId: token)  (event) in
        switch event 
            case .completed(let result):
                switch result 
                    case .success(let note):
                        guard let note = note else 
                            print("API Query completed but missing user")
                            return
                        
                        print("API Query successful, got user: \(note)")
                case .failure(let error):
                    print("Completed with error: \(error.errorDescription)")
                    
            case .failed(let error):
                print("Failed with error \(error.errorDescription)")
            default:
                print("Unexpected event")
        
    


【问题讨论】:

不要使用访问令牌作为标识符。它一直在变化。 @Don 好的,很高兴知道!所以问题是如何在给定函数AWSMobileClient.default().getTokens 中的令牌的情况下加载用户的其余信息我相信令牌与每个登录会话相关联正确吗? 【参考方案1】:

我假设您正在通过 Amplify CLI 配置所有内容?您使用的是适用于 Amazon 的新版还是旧版 iOS 开发工具包?我的工作流程通常是在调整我的 schema.graphql 文件以运行放大推送命令以实际将这些更改传播到后端并确保它生成 API.swift 文件时。您的 graphql 操作是否通过自动生成的 api.swift 文件运行?您也可以运行 amplify codegen 来重新创建 api.swift 文件。

【讨论】:

所以我做了amplify run 并移动了amplify/generate/models/*** 中的新文件,现在它构建并运行了。但是现在即使数据仍然存在,我也无法在后端找到用户。因为 User 模型是新的,所以这很有意义,但它会产生一个问题,因为我将在应用程序投入生产很久之后编辑 User 模型。如何确保更新后的 Model 类在 db 中找到正确的数据? @Juilen S 只是为了添加到之前的评论中,当我创建一个新用户并将其数据保存在带有 blank 字段的修改后的 User 模型下时,我现在可以使用查询新用户数据Amplify.API.query(from: User.self 。我只是不能再在旧模型下访问用户数据。这会给生产中的用户带来问题,因为我会不断更新User 模型。 嗯。您的放大命令和设置与我习惯的不同。也许是一个新版本?但是,可能存在问题的一件事是您定义了blank : String!,但数据库中的旧用户没有空白,但您已根据需要声明了它。如果删除“!”从空白或直接在 DynamoDB 中为该属性添加一些内容,也许它会在查询时返回它?

以上是关于在 GraphQL 中编辑类时的正确工作流程的主要内容,如果未能解决你的问题,请参考以下文章

GraphQL 查询工作,现在返回 null;

GraphQL 编辑条目添加新条目

graphQL 查询中的字符串插值

“余弦”度量在 sklearn 聚类算法中如何工作?

石墨烯突变返回 400 - 不会正确传递 id 字段

如何正确使用 mat-autocomplete 和远程 graphQL 数据?