Closed timzaak closed 6 years ago
先来看两个相关项目: graphql-backend-starter foodie
DI 注入 异常处理 用户登陆验证\权限验证 错误返回格式 更严格的数据接口返回量限制
性能瓶颈在哪里?
import { print } from 'graphql/language/printer';
export default function createNetworkInterface({ uri }) {
return {
query(request){
const token = reduxStore.getState().account.token
const textBody = JSON.stringify({
...request,
query:print(request.query),
})
const headers = {
Accept: '*/*',
'Content-Type': 'application/json',
}
if (token) {
headers.auth = token
}
return fetch(uri, {
method: 'POST',
body: textBody,
headers,
}).then(response => {
const json = response.json()
console.log(`request:${request.operationName} ${JSON.stringify(request.variables||{})} ${token} ==>${JSON.stringify(json)}`)
return json
})
},
}
}
import React from 'react'
import {
View
} from 'react-native'
import styled from 'styled-components/native'
import theme from '../../theme'
import Container from '../../component/container'
import moment from 'moment'
import myCommentQL from '../../graphql/comment/myComment'
import {
graphql,
} from 'react-apollo'
const FlatList = styled.FlatList`
flex:1
marginBottom:${theme.tab_bar_height}
`
const ItemContainer = styled.View`
paddingHorizontal:${theme.h_spacing_md}
borderBottomWidth:1
borderColor:${theme.border_color_base}
`
const Name = styled.Text`
marginTop:${theme.v_spacing_md}
fontSize:${theme.font_size_display_md}
color:${theme.SECOND_FONT}
`
const Content = styled.Text`
marginVertical:${theme.v_spacing_md}
fontSize:${theme.font_size_display_sm}
marginHorizontal:${theme.h_spacing_md}
color:${theme.FIRST_FONT}
`
const Time = styled.Text`
alignSelf:flex-end
fontSize:${theme.font_size_display_sm}
color:${theme.THIRD_FONT}
marginBottom:${theme.v_spacing_sm}
`
const NoContentTip = styled.Text`
marginTop:${theme.v_spacing_md}
fontSize:${theme.font_size_display_md}
color:${theme.color_text_disabled}
`
const Comment = React.createClass({
_renderItem({ item }){
const { content, fromId, time } = item;
const direction = fromId == 1 ? 'left' : 'right'
const timeString = moment(time).format("MM-DD HH:mm")
const name = fromId == 1 ? '作者' : '你';
return (
<ItemContainer>
<Name direction={direction}>{name}</Name>
<Content>{content}</Content>
<Time direction={direction}>{timeString}</Time>
</ItemContainer>
)
},
_keyExtractor(item, index){
return item.time + index
},
render(){
const { loading, comment, error } = this.props;
if (error) {
return (<View/>);
}
const data = loading ? [] : (comment ? (comment.myComments.list || []) : []);
if(!loading&& !data.length){
return (
<Container
style={{alignItems:'center'}}
>
<NoContentTip>还没有信息哟</NoContentTip>
</Container>)
}
return (
<Container>
<FlatList
data={data}
renderItem={this._renderItem}
keyExtractor={this._keyExtractor}
refreshing={loading}
/>
</Container>
);
},
});
const withData = graphql(myCommentQL, {
options: props => ({
variables: {
page: 1,
pageSize: 100,
},
fetchPolicy: 'network-only',
}),
props (result) {
const { data: { loading, comment, error } } = result
return {
loading,
comment,
error,
}
}
})
export default withData(Comment)
import {
gql,
} from 'react-apollo'
export default gql`
query myComment($pageSize:Int!,$page:Int!) {
comment {
myComments(pageSize:$pageSize,page:$page){
totalCount
list{
id
fromId
toId
content
time
}
}
}
}`
如上,编程范式会产生略微的变化
在 Schema 设计中,关联关系设计是比较麻烦的。通过 Connection(Node and Edge)统一抽象 pagination,可获得良好的API。
explaining-graphql-connections
GraphQL + Relay + React 算是一整套的 Facebook 前端Web生态。Relay 帮忙解决数据缓存,请求优化以及组件化数据等问题, 但其本身设计的过于复杂。导致 Apollo Client 的出现,另外,其功能也和 Redux 部分重复甚至冲突。目前社区在等待 Relay 的简易版本出现。
对框架整体API的设计,个人特别特服气。作者也是一个特别 nice 的人。可以说一己之力推动了 graphQL 在 scala 生态下的落地。
基于Sangrid + Akka + MariaDB 为 JS 开发者 做的一套一站式开发工具。通过写Schema 和 Resolve 去处理请求。
强烈推荐阅读源码。
最近看到 Apollo 2.0 出来了。感觉资源的统一管理有戏。对 GraphQL 的前景充满信心。
最近有个比较极端的想法: 前端在提交给测试前的3个小时,不允许对接后端接口。 前后交互协议通过 GraphQL 来做。 GraphQL 自带全接口 schema 检查,测试数据自动生成。简直完美!
分页
由于 GraphQL 不支持 interface 泛型,无法做到一个好的分页抽象、节约代码。不过可以参考官方标准来做批量查找API设计: http://graphql.org/learn/pagination
批量表关联
主要通过
Fetch
DeferredResolverAPI
解决关联表批处理问题,DeferredValue
可解决 重复查询