了解 Rails Params + Graphql Mutation 交互

Understanding Rails Params + Graphql Mutation interaction

我有两个 rails 应用程序,一个是 graphql API 另一个也是 REST API 应用程序。 我们调用 graphql 应用 graphi 和 REST 应用 resti.

  1. graphi向resti发送数据

  2. resti 然后与外部 API 对话,从外部 API 获得响应,并返回给 graphi 一个很好的响应。

好的,所以 graphi 有一个名为 vendor 的突变。看起来像这样:

mutation {
  createVendor(
    input: {
      vendorId: 2,
      quoteType: "renter",
      renterData: {
        firstName: "Tony",
        lastName: "Stark",
        email: "tony@starkindustries",
        phoneType: "mobile",
        phone: "6504881234",
        requestType: "renter",
        address1: "123 Main Street",
        addressCity: "Palo Alto",
        addressState: "CA",
        addressZip: "94301",
        dob: "1990-07-22"
      }
    }
  ) 
}

然后我在 create_vendor.rb (mutation file):

上像这样通过 httparty 发送这些数据
class CreateVendor < Mutations::BaseMutation
    description 'Create a vendor'
    argument :vendor_id, ID, required: false
    argument :quote_type, String, required: true
    argument :renter_data, Types::RenterVendorType, required: false
    field :vendor, Types::VendorType, null: false


    def resolve(args)
          response = HTTParty.post(
            'http://localhost:3001/api/v2/vendor', <-- this sends data to resti
            body: JSON.parse(args.to_json),
            headers: AUTHORIZATION_HEADERS
          )
         if response.success?
           puts "Cool, I was successfull"
         else
           puts "I wasn't successful"
         end
    end
end

一旦 graphi 将数据发送到 resti,resti 服务器将如下所示:

Processing by Api::V2::VendorController#create as */*
  Parameters: {"vendor_id"=>"2", "quote_type"=>"renter", "renter_data"=>{"first_name"=>"Tony", "last_name"=>"Stark", "email"=>"tony@starkindustries", "phone_type"=>"mobile", "phone"=>"6504881234", "request_type"=>"renter", "address1"=>"123 Main Street", "address_city"=>"Palo Alto", "address_state"=>"CA", "address_zip"=>"94301", "dob"=>"1990-07-22"}}

现在,这不再是 graphql 的东西了,它变成了带有一个嵌套参数的散列。

在 resti 的控制器上,我想 permit vendor params

def create_vendor_params
    params.require(:vendor).permit(
      :vendor_id, :quote_type, renter_data: %i[first_name last_name email phone_type phone request_type address1 address_city address_state address_zip DOB]
    )
  end

问题

当我执行此流程时,我在 resti 服务器上收到此问题:

ActionController::ParameterMissing (param is missing or the value is empty: vendor
Did you mean?  vendor_id
               renter_data
               action
               quote_type):

当我使用这个数据结构在 Postman 上测试完全相同的东西时:

{   "vendor": {
        "vendor_id": 2,
        "quote_type": "renter",
        "renter_data": {
            "first_name":"Tony",
            "last_name":"Stark",
            "email":"tony@starkindustries.com",
            "phone_type":"mobile",
            "phone":"6504881234",
            "request_type":"renter",
            "address1":"123 Main Street",
            "address_city":"Palo Alto",
            "address_state":"CA",
            "address_zip":"94301",
            "DOB":"1990-07-22"
        }
    }
}

我收到以下信息:

#<ActionController::Parameters {"vendor"=>#<ActionController::Parameters (#<ActionController::Parameters this  piece of code is ruining everything,) {"_id"=>2, "quote_type"=>"renter", "renter_data"=>{"first_name"=>"Tony", "last_name"=>"Stark", "email"=>"tony@starkindustries.com", "phone_type"=>"mobile", "phone"=>"6504881234", "request_type"=>"renter", "address1"=>"123 Main Street", "address_city"=>"Palo Alto", "address_state"=>"CA", "address_zip"=>"94301", "DOB"=>"1990-07-22"}} permitted: false>, "controller"=>"api/v2/vendor", "action"=>"create"} permitted: false>

现在有些事情我不明白为什么会这样。当我 byebug 在这段代码上:

def create_vendor_params
    params.require(:vendor).permit(
      :vendor_id, :quote_type, renter_data: %i[first_name last_name email phone_type phone request_type address1 address_city address_state address_zip DOB]
    )
    byebug
  end

我手动执行此操作:

(byebug) params.require(:vendor).permit(
:vendor_id, :quote_type, renter_data: %i[first_name last_name email phone_type phone request_type address1 address_city address_state address_zip DOB]
)

它打印出这个:

#<ActionController::Parameters {"vendor_id"=>2, "quote_type"=>"renter", "renter_data"=>#<ActionController::Parameters {"first_name"=>"Tony", "last_name"=>"Stark", "email"=>"tony@starkindustries.com", "phone_type"=>"mobile", "phone"=>"6504881234", "request_type"=>"renter", "address1"=>"123 Main Street", "address_city"=>"Palo Alto", "address_state"=>"CA", "address_zip"=>"94301", "DOB"=>"1990-07-22"} permitted: true>} permitted: true>

这是允许的!!

为什么会这样? graphql 是如何构造数据的?非常感谢您的帮助!

您发送给 resti 的参数格式不正确。如果您仔细观察,这些参数并没有像您通过 Postman 发送它们时那样嵌套在 vendor 下。

您的突变应具有以下结构 突变

  createVendor(
    input: {
      vendor: {
        vendorId: 2,
        quoteType: "renter",
        renterData: {
          firstName: "Tony",
          lastName: "Stark",
          email: "tony@starkindustries",
          phoneType: "mobile",
          phone: "6504881234",
          requestType: "renter",
          address1: "123 Main Street",
          addressCity: "Palo Alto",
          addressState: "CA",
          addressZip: "94301",
          dob: "1990-07-22"
        }
      }
    }
  )