我正在创建一个从api接收数据的应用程序,我需要轻松访问该远程数据。目前,我的游戏计划是在用户需要数据时从端点下载json文件,但如果有人可以推荐使用远程URL作为GraphQL源的方法,我也很感激。
关于手头的问题:
我不确定如何构建schema.js文件。以下是我尝试使用的实际数据actual data
但这是一个粗略的轮廓,我把它放在一起。它或多或少地概述了我访问时遇到的所有嵌套字典和列表。如果有人可以提供一些如何获得这些嵌套的dicts,列表和值的示例,我将非常感激!
{
boxscore {
progames {
},
teams {
[
slots {
},
appliedStats : float,
appliedStats1: float,
team {
[
rank: int,
player {
},
watch: boolean,
trade: boolean,
currentProjStats {
},
proGameIds {
}
],
[
...
],
[
...
],
},
teamId: int,
appliedActive: int,
appliedProjActive: float,
],
[
]
}
}
}
这是我尝试过的一个例子
const {
GraphQLObjectType,
GraphQLString,
GraphQLInt,
GraphQLSchema,
GraphQLList,
GraphQLNonNull,
GraphQLBoolean,
GraphQLFloat
} = require('graphql');
const axios = require('axios');
const PlayerType = new GraphQLObjectType({
name: 'Player',
fields:() => ({
droppable: {type:GraphQLBoolean},
percentStarted: {type:GraphQLFloat},
jersey: {type:GraphQLString},
playerRatingSeason: {type:GraphQLFloat},
positionRank: {type:GraphQLInt},
isIREligible: {type:GraphQLBoolean},
draftRank: {type:GraphQLInt},
value: {type:GraphQLInt},
universeId: {type:GraphQLInt},
firstName: {type:GraphQLString},
elligibleSlotsCategoryIds: {type:elligibleSlotsCategoryIdsType},
gameStarterStatus: {type:GraphQLInt},
lastName: {type:GraphQLString},
sportsId: {type:GraphQLInt},
healthStatus: {type:GraphQLInt},
percentOwned: {type:GraphQLFloat},
proTeamId: {type:GraphQLInt},
tickerId: {type:GraphQLInt},
isActive: {type:GraphQLBoolean},
playerId: {type:GraphQLInt},
percentChange: {type:GraphQLFloat},
defaultPositionId: {type:GraphQLInt},
totalPoints: {type:GraphQLFloat}
})
});
const CurrentPeriodProjectedStatsType = new GraphQLObjectType({
name: 'CurrentPeriodProjectedStats',
fields: () => ({
appliedProjectedStatTotal: {type:GraphQLFloat},
})
});
const ProGameIdsType = new GraphQLObjectType({
name: 'ProGameIds',
fields: () => ({
id: {type:GraphQLInt},
})
});
const CurrentPeriodRealStatsType = new GraphQLObjectType({
name: 'CurrentPeriodRealStats',
fields: () => ({
appliedRealStatTotal: {type:GraphQLFloat},
})
});
const SlotsType = new GraphQLObjectType({
name: 'Slots',
fields:() => ({
// This might take type:GraphQLList, not sure though //
pvoRank: {type: GraphQLInt},
player: {type: PlayerType},
watchList: {type:GraphQLBoolean},
isKeeper: {type:GraphQLBoolean},
isTradeLocked: {type:GraphQLBoolean},
currentPeriodProjectedStats: {type: CurrentPeriodProjectedStats},
proGameIds: {type: ProGameIds},
opponentProTeamId: {type:GraphQLInt},
slotCategoryId: {type:GraphQLInt},
lockStatus: {type:GraphQLInt},
isQueuedWaiverLocked: {type:GraphQLBoolean},
currentPeriodRealStats: {type:CurrentPeriodRealStatsType}
})
});
/*
const ProgamesType = new GraphQLObjectType({
name: 'Progames',
field: () => ({
})
});
*/
const TeamsType = new GraphQLObjectType({
name: 'Teams',
fields: {
team1: {type:GraphQLList},
team2: {type:GraphQLList},
}
});
const BoxscoreType = new GraphQLObjectType({
name: 'Boxscore',
fields: () => ({
// progames: {type:ProgamesType},
teams: () => GraphQLList(TeamsType),
scoringPeriodId: {type:GraphQLInt},
matchupPeriodId: {type:GraphQLInt},
homeTeamBonus: {type:GraphQLInt}
})
});
const MetadataType = new GraphQLObjectType({
name: 'Metadata',
fields: () => ({
leagueId: {type:GraphQLString},
status: {type:GraphQLString},
seasonId: {type:GraphQLString}
})
});
const EspnQuery = new GraphQLObjectType({
name: 'EspnQueryType',
fields: {
boxscore: {type:BoxscoreType},
},
resolve(parentValue, args){
}
});
// Keep at the bottom //
module.exports = new GraphQLSchema({
query: EspnQuery
});

答案 0 :(得分:1)
我在您的代码中看到的最大问题是您正在尝试为Query(EspnQuery)添加解析器。即使它被定义为GraphQLObjectType
,因为它位于根,它的解析器永远不会被调用。您要做的是将现有数据结构包装在EspnQuery
的某种字段中:
const BoxscoreDataType = new GraphQLObjectType({
name: 'BoxscoreData',
fields: {
boxscore: {type:BoxscoreType},
metadata: {type:MetadataType},
},
});
const EspnQuery = new GraphQLObjectType({
name: 'EspnQuery',
fields: {
getBoxscore: {
type: BoxscoreDataType,
resolve: () => {} // We'll come back to this in a minute
},
},
});
出于测试目的,您可以将示例JSON数据放在单独的文件中,只需require
:
const testData = require('./testData.json')
这将返回一个对象,您可以在解析器内返回getBoxscore
查询。
resolve: () => testData
但是我们想要从API调用返回数据,所以让我们这样做:
resolve: () => {
const url = 'http://games.espn.com/ffl/api/v2/boxscore?leagueId=1150587&seasonId=2017&teamId=5&scoringPeriodId=7'
return axios(url)
}
Axios返回一个Promise,这很棒,因为我们的解析器可以返回一个值,或者一个将在该值中解析的Promise。请确保您不要忘记return
!
您还可以为任何字段定义参数,然后可以在解析程序中使用。所以getBoxscore
看起来像这样:
getBoxscore: {
type: BoxscoreDataType,
args: {
leagueId: {
name: 'leagueId',
type: new GraphQLNonNull(GraphQLInt)
},
seasonId: {
name: 'seasonId',
type: new GraphQLNonNull(GraphQLInt)
},
teamId: {
name: 'teamId',
type: new GraphQLNonNull(GraphQLInt)
},
scoringPeriodId: {
name: 'scoringPeriodId',
type: new GraphQLNonNull(GraphQLInt)
}
}
resolve: (obj, { leagueId, seasonId, teamId, scoringPeriodId }) => {
const url = `http://games.espn.com/ffl/api/v2/boxscore?leagueId=${leageId}&seasonId=${seasonId}&teamId=${teamId}&scoringPeriodId=${scoringPeriodId}`
return axios(url)
}
}
另外,不要忘记使GraphQL如此强大的部分原因是能够在字段级别操纵数据的返回方式。因此,对于任何字段,您可以在将父对象返回到客户端之前轻松地操作它们返回的数据。
一个愚蠢的例子可能是在您的PlayerType中的firstName上附加一个解析器:
resolve: ({ firstName }) => {
return firstName.toUpperCase()
}
更有趣的用途可能是对不同的API端点进行额外调用。例如,对于SlotsType上的player
字段,您可以附加如下解析器:
resolve: ({ player: { playerId } }) => {
const url = `some url that uses that ${playerId}`
return axios(url)
}
当然,如果您这样做,您可能还会修改PlayerType
以反映该通话返回的数据。
有很多值得探索的可能性。祝你好运!