gol*_*und 2 reactjs graphql react-apollo
我正在开发一个允许用户上传大型数据集的应用程序。上传者有一个“草稿”版本,他们可以在 UI 中编辑该版本,然后他们发布草稿的快照,所有用户都可以看到。仅当上传者登录时才应查询草稿文件。
虽然非编辑权限用户看不到草稿,但该应用程序仍会查询其整个文件集,这使得获取数据集页面非常缓慢。
该查询具有“草稿”数据的片段,包括有条件不想要的文件。如果我省略片段中的文件,则该组件适用于所有用户……但是上传者无法获取他们的草稿文件。所以这该死的,如果我这样做,该死的如果我不犹豫,我对 graphql 和 apollo 缺乏经验在这里真的很闪耀。
这是查询和随附的钩子:
export const getDatasetPage = gql`
query dataset($datasetId: ID!) {
dataset(id: $datasetId) {
id
created
public
following
starred
...DatasetDraft
...DatasetPermissions
...DatasetSnapshots
...DatasetIssues
...DatasetMetadata
...DatasetComments
uploader {
id
name
email
}
analytics {
downloads
views
}
onBrainlife
}
}
${DatasetQueryFragments.DRAFT_FRAGMENT}
${DatasetQueryFragments.PERMISSION_FRAGMENT}
${DatasetQueryFragments.DATASET_SNAPSHOTS}
${DatasetQueryFragments.DATASET_ISSUES}
${DatasetQueryFragments.DATASET_METADATA}
${DATASET_COMMENTS}
`
export const DatasetQueryHook = ({ datasetId }) => {
const {
data: { dataset },
loading,
error,
} = useQuery(getDatasetPage, {
variables: { datasetId },
})
if (loading) {
return <Spinner text="Loading Dataset" active />
} else {
if (error) Sentry.captureException(error)
return (
<ErrorBoundary error={error} subject={'error in dataset page'}>
<DatasetQueryContext.Provider
value={{
datasetId,
}}>
<DatasetPage dataset={dataset} />
</DatasetQueryContext.Provider>
</ErrorBoundary>
)
}
}
Run Code Online (Sandbox Code Playgroud)
这是片段:
export const DRAFT_FRAGMENT = gql`
fragment DatasetDraft on Dataset {
id
draft {
id
modified
readme
partial
description {
Name
Authors
DatasetDOI
License
Acknowledgements
HowToAcknowledge
Funding
ReferencesAndLinks
}
files { //when this is removed, it works...except for users with edit privileges
id
filename
size
}
summary {
modalities
sessions
subjects
subjectMetadata {
participantId
age
sex
group
}
tasks
size
totalFiles
dataProcessed
}
}
}
`
Run Code Online (Sandbox Code Playgroud)
长话短说:如果用户没有编辑权限,查询应该省略草稿文件。我知道 hasEdit 的逻辑,但我不知道如何使用指令来实现它。我什至可以@skip在片段上使用,即使可以,我可以有条件地传递它的变量吗?我在文档中找不到任何关于此的内容,并且对解决方案感到茫然。
是的,指令可以在片段内使用,是的,您可以为此使用变量。
下面是一个使用 SWAPI API的简单示例:
query MyQuery ($showDate: Boolean!){
allFilms {
films {
...FilmFields
}
}
}
fragment FilmFields on Film {
id
title
releaseDate @include(if: $showDate)
}
Run Code Online (Sandbox Code Playgroud)
这里要注意的一件事是变量仍然被定义为操作的一部分。这意味着如果您将片段放在单独的文件中,然后将它们导入到查询中,则需要确保 A) 操作实际定义了变量,并且 B) 变量的名称是正确的。
另外值得注意的是,有实验支持将变量定义为片段的一部分。这必须在服务器端显式启用。如果您使用的是 graphql-tag,则还必须在那里显式启用它。如果您使用的是makeExecutableSchemaApollo Server,则可以传入一个parseOptions参数来启用此功能服务器端:
makeExecutableSchema({
typeDefs,
resolvers,
parseOptions: {
experimentalFragmentVariables: true,
},
})
Run Code Online (Sandbox Code Playgroud)
然后你可以创建片段,如:
fragment FilmFields on Film ($showDate: Boolean!) {
id
title
releaseDate @include(if: $showDate)
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1757 次 |
| 最近记录: |