2017-06-06 40 views
0

在這種情況下,鍵入「X」是Application並且類型「Y」是類型「節點」 - 我可以看到爲什麼這正在發生,但我對Relay的理解還不足以理解如何解決它。由繼電器產生的查詢是片段不能在這裏傳播,因爲類型「X」的對象永遠不可能是「Y」類型

query { 
    node(id: $some_id) { 
     ...F0 
    } 
} 

fragment F0 on Application { 
    ... 
} 

我有一個模式,它看起來像

query { 
    application { 
     /* kind of a generic endpoint for fetching lists, etc */ 
     invites(token: $token) { 
      name 
     } 
    } 
    viewer { /* the current user */ } 
} 

我試圖獲取從會話之外的特定邀請(viewernull)。

我已經試過

const application = Relay.QL`query { application }` 
... 
<Route ... queries={{ application }}/> 
... 
Relay.createContainer(Component, { 
    initialValues: { token: null }, 
    fragments: { 
     application:() => { 
      fragment on Application { 
       invites(token: $token) { 
        ... 
       } 
      } 
     } 
    } 
}) 

它給我的錯誤

片段「F0」不能在這裏傳播類型的「節點」絕不是類型的「應用程序」對象 - 什麼爲此。

我有點困惑,因爲如果我寫了一個原始查詢,並通過GraphQL運行它直接

query { 
    application { 
     invites(token: "asdasdasd") { 
      edges { 
       node { 
        name 
       } 
      } 
     } 
    } 
} 

它給我什麼我正在尋找...

在在後端,我圖的定義如下

export const Application = new GraphQLObjectType({ 
    name: 'Application', 
    fields:() => ({ 
    id: { 
     type: GraphQLString, 
     resolve:() => 'APPLICATION_ID' 
    }, 
    invites: { 
     type: InviteConnectionType, 
     args: connectionArgs, 
     resolve: (application, args) => { 
      ... 
     } 
    } 
    }) 
}) 

export default new GraphQLSchema({ 
    query: new GraphQLObjectType({ 
    name: 'query', 
    fields: { 
    node: nodeField, 
    application: { 
     type: Application, 
     resolve: (root, args, ctx) => { 
     return Promise.resolve({}) 
     } 
    } 
    } 
}) 

我一直在尋找像this和一些​​的問題,但它不是我清楚我應該如何實現nodeInterface

編輯:短長目前nodeInterface代碼是

export const { 
    nodeInterface, 
    nodeField 
} = nodeDefinitions(
    (globalId) => { 
    const { type, id } = fromGlobalId(globalId) 
    return db[type].findById(id) 
    }, 
    (obj) => { 
    const name = obj.$modelOptions.name.singular 
    return types[name] 
    } 
) 

應用程序是不是一個DB模式,但是,只是一個通用的接口,通過獲取數據。我試着檢查type === 'Application',並返回null(雖然我明白了爲什麼不起作用),返回Application(GraphQLObject),但這不起作用......並不確定從那裏去哪裏。

回答

1
  • 您需要自動生成要重新訪問的GraphQL 類型的唯一全局ID。
  • nodeInterface您告訴GraphQL 如何將id映射到相應的GraphQL對象。
  • 由給定的服務器端對象nodeInterface標識GraphQL類型。

下面是簡化的示例是如何可能看起來像應用:

// nodeInterface. 
var {nodeInterface, nodeField} = nodeDefinitions(
    (globalId) => { 
    var {type, id} = fromGlobalId(globalId); 

    // The mapping from globalId to actual object id and type. 
    console.log('globalId:', id); 
    console.log('type:', type); 

    if (type === 'Application') { 
     // getApplication is your db method to retrieve Application object. 
     // With id you could also retrieve a specific db object. 
     return getApplication(); 
    } else { 
     return null; 
    } 
    }, 
    (obj) => { 
    // Note that instanceof does an identity check on the prototype object, so it can be easily fooled. 
    if (obj instanceof Application) { 
     return ApplicationType; 
    } else { 
     return null; 
    } 
    }, 
); 

// Application. 
export const ApplicationType = new GraphQLObjectType({ 
    name: 'Application', 
    fields:() => ({ 
    // Auto-generated, globally defined id. 
    id: globalIdField('Application'), 
    _id: { 
     type: GraphQLString, 
     resolve:() => 'APPLICATION_ID' 
    }, 
    invites: { 
     type: InviteConnectionType, 
     args: connectionArgs, 
     resolve: (application, args) => { 
      ... 
     } 
    } 
    }), 
    // Declaring nodeInterface. 
    interfaces: [nodeInterface] 
}); 

注意,在初始取nodeInterface甚至沒有執行,所以如果nodeInterface正在返回什麼都不會有在錯誤最初的抓取。如果這沒有意義,或者你還在掙扎,你可以發佈一個鏈接到回購,我會研究它。

+0

是的我覺得我需要實現'nodeInterface',但我真的不知道如何...檢查我的編輯。 –

+0

對不起,誤解了。在'nodeInterface'中,您基本上需要將全局定義的ID映射到數據對象,以便Relay能夠獲取對象。我認爲這個https://github.com/entria/graphql-dataloader-boilerplate/blob/8d661425538e7881f8eb12437929aba77d4cfbba/src/interface/NodeInterface.js完整的例子會很有幫助。 – Zero

+0

但是對於那些不是/技術上的/有邊緣和關係的對象,只是其他事物的接口 - 比如在這種情況下的應用程序。我已經嘗試過(或多或少)我認爲實現應用程序的nodeinterface的樣子。 –

0

爲了對此進行更新,我選擇了正確的道路。

目前nodeDefinitions我只是需要一點點額外的:

nodeDefinitions(
    (globalId) => { 
    const { type, id } = fromGlobalId(globalId) 

    if (type === 'Application') { 
     return Promise.resolve(Application) 
    } 

    return db[type].findById(id) 
    }, 
    (obj) => { 
    if (obj.$modelOptions) { 
     /* sequelize object */ 
     const name = obj.$modelOptions.name.singular 
     return types[name] 
    } else if (obj.name === 'Application') { 
     return Application 
    } 

    return null 
    } 
) 

我不知道這是否是做到這一點的最好辦法,但似乎這樣的伎倆。要點是,如果我想要返回的節點類型是Application,那麼我返回GraphQL對象 - { ... name: "Application" ... },我們將在下一步中使用name字段(第二次回調nodeDefinitions)返回Application。我認爲你可以返回一個「自定義」對象或其他東西 - 只要你返回一個獨特的東西,你可以定義一個到GraphQLObject類型的映射(第二個回調需要)就沒有關係。

相關問題