2017-05-08 85 views
1

我在探索graphql,而困擾着我的問題是如果我在定義我的graphql服務器時可以做某種類型的組合。GraphQL類型組合

我們假設我的收藏中有Person和Company。我有這樣的事情:

const Person = new GraphQLObjectType({ 
    name: 'Person', 
    fields: { 
    firstName: {type: GraphQLString}, 
    lastName: {type: GraphQLString} 
    } 
}); 

const Company = new GraphQLObjectType({ 
    name: 'Company', 
    fields: { 
    name: {type: GraphQLString}, 
    website: {type: GraphQLString} 
    } 
}); 

但無論單位和個人應該有這樣的字段:createdAtid。因此,假設我有:

const Entity = new GraphQLObjectType({ 
    name: 'Entity', 
    fields: { 
    id: {type: GraphQLString}, 
    createdAt: {type: GraphQLString} 
    } 
}); 

,所以我想是這樣的:

new GraphQLObjectType({ 
    ... 
    extends: [Entity] 
}); 

我知道有interfaces,但我認爲這不是我所期待的,因爲那時我需要實現接口無論如何,我想達到的目的是保留一些字段定義sepratly並重用其他類型。

任何想法?我在做什麼完全沒有意義的事情?

+0

看不到downvoting的原因。也許這樣做的人可以寫出什麼不清楚或爲什麼你認爲它沒有用?或者你聲稱我沒有做出研究工作?任何解釋? – jano

回答

0

如果我們看看GraphQL語言規範,有接口。接口用於描述兩種類型的常見行爲。如果您在同一個字段中返回兩個子類型,接口通常纔有意義。 GraphQL documentation就是一個很好的例子。我建議不要在你的情況下使用接口,除非你想在同一個字段中返回所有實體類型(例如在搜索中)。

您正在談論服務器實施級別。我不知道在GraphQL.js中擴展類似這樣的類型。你可以做的是創建一個包含兩個字段的JavaScript對象。然後,您可以重複使用此代碼,並將其插入到所有類型的,例如使用Object.assign

const standardFields = { 
    id: { 
     type: new GraphQLNonNull(GraphQLID), 
     description: 'Unique id for this entity' 
    }, 
    createdAt: { 
     type: new GraphQLNonNull(GraphQLString), 
     description: 'Datetime of this entity\'s creation' 
    } 
    } 

    const Company = new GraphQLObjectType({ 
    name: 'Company', 
    fields: Object.assign({}, standardFields, { 
     name: {type: GraphQLString}, 
     website: {type: GraphQLString} 
    } 
    }); 

也許導入從一個文件中的字段,並明確將其插入:

const { id, createdAt } = require('./standardFields'); 

    const Company = new GraphQLObjectType({ 
    name: 'Company', 
    fields: { 
     id, 
     createdAt, 
     name: {type: GraphQLString}, 
     website: {type: GraphQLString} 
    } 
    }); 

在這兩種情況下,我不從中看到很多收益。建立一個確保所有類型包含字段的測試可能會更有用。

+0

這正是我目前正在做的,但我不太喜歡這個解決方案,因爲在這種情況下'id'和'createdAt'不是自包含的。 – jano

+0

這可能是一個典型的「繼承或組合」問題。你在尋找什麼樣的模式,它在實際的API中沒有表現出來。所以我們不得不去問兩個問題。避免代碼重複?可測試性?爲什麼你在這裏尋找繼承,如果不僅僅是爲了它的緣故?我不會擔心它太多,在我們的應用程序中,我們實際上明確地重複了這些字段。這爲我們提供了一個易於理解的具有顯式依賴性的代碼。 – Herku

0

您可以從interface類型得到的字段是這樣的:

const carInterface = new GraphQLInterfaceType({ 
    name: 'car', 
    fields: { 
    _id: { type: GraphQLID }, 
    userId: { type: GraphQLID }, 
    carType: { type: new GraphQLNonNull(GraphQLString), description: 'نوع اعلان السيارة' }, 
    title: { type: new GraphQLNonNull(GraphQLString), description: 'عنوان الاعلان' }, 
    brand: { type: GraphQLString, description: 'الماركة-النوع' }, 
    model: { type: GraphQLString, description: 'الموديل' } 
    } 
}); 
console.log(carInterface._typeConfig.fields); 

您可以輕鬆地添加carInterface._typeConfig.fields任何GraphQLObject字段定義;