GraphQL还是通过Http的GET和POST的形式返回数据,只是GET的长度限度导致可能的查问会出问题。所以个别都能够用POST来获取、批改数据。这就是说GraphQL在客户端App来说能够和平时申请API的形式齐全一样。在根本应用上,有没有第三方graphql client的库的帮忙都没什么区别。
GraphQL是啥
在正式开始之前,略微介绍一下GraphQL。如果你的我的项目稍有规模,那么你肯定禁受过一种折磨。一个很久之前的API返回了巨多务必的数据,是能够齐全服务当初的需要。然而显著数据过多在要求性能的时候,在后端数据是查出来的,有缓存也得拜访了缓存能力返回并不是没有代价。在前端占了带宽返回就慢。而后从一大堆数据里拿出你想要的也要代价。前面的保护对于前后端都是可能产生辣手的问题。之所以FB要提出GraphQL的规范也是因为FB自身反对的产品太多遇到了这样的问题。
如果客户端这边说有了什么需要,就获取这个需要的必要数据,那么根本就要新开发API。GraphQL就是一个你要啥就返回啥的微小API。能够查问你指定的数据,也能够批改后端的数据。查问就是Query
,批改操作叫做Mutation
。
查问:
query { todos { id title } }
这是一个查问。要查问的是todos(能够临时了解为一个表),要查问的是id
和title
两个字段。这个查问只会返回id
和title
两个字段对应的数据。
也能够是带条件的查问:
query ($from: Int!, $limit: Int!) { todos (from: $from, limit: $limit) { id title } }
新增、批改
mutation CreateReviewForEpisode($ep: Episode!, $review: ReviewInput!) { createReview(episode: $ep, review: $review) { stars commentary }}
返回
{ "data": { "createReview": { "stars": 5, "commentary": "This is a great movie!" } }}
根本介绍就到这里。具体能够参考官网文档。
为啥不是Relay
官网的库专职负责劝退有没有领会过。GraphQL是Facebook提出来的一个规范,留神这是一个规范而不是实现。服务端的状况不熟不多做介绍,然而在客户端FB或者当初叫Meta了,给出了一个实现并且曾经倒退了很多年。这个库叫做Relay。
它凭借弱小的性能和Meta(当年FB)背书,很快倒退了起来。不过这个工具显然曾经有点后劲不足了。从当初TypeScript我的项目倒退的状况来看,它显然不足对TypeScript的反对。比方它的一个配套babel插件没有对TypeScript的反对。当然也是一个小问题,只须要在本人的我的项目里增加一个index.d.ts文件并增加类型就能够。
而后是它的模式。在你依照官网文档的Step by step一步一步走完的话,你还是不能做开发。因为你在增加另外一个文件的和查问的时候就会发现,这个须要的查问并不会主动生成。要么是悄没声的没有报错也没有生成对应的文件,要么是报一些莫名其妙的错。因为你须要依据你的文件名来命名查问(或者任何的操作)。也就是它的模式能够认为是强侵入的,尽管会比其余的形式少写一些固定代码,尽管也不肯定。笔者程度无限,只好先弃了。
URQL怎么样
首先,urql在github有6.5K的star。并且设计也足够沉闷。最初被后还有个公司反对。不能说不是KPI我的项目,然而KPI我的项目也有个益处,至多有为了KPI的人在保护代码。
另外,这个库是用TypeScript开发的。也就是说它必定是TypeScript敌对的,你的我的项目如果用了TypeScript,在类型上不必放心过期、不残缺等问题。
并不是其余的库不适合,更多能够抉择的库在GraphQL官网里有列出来。
用一下现成的GraphQL服务:Github
Github很久以前就提供了GraphQL API。咱们就在APP里调用github的GraphQL API。用来查问某个owner(比方facebook)上面的公开代码库。
要应用github的GraphQL服务须要用到token,所以须要一个输出token的界面。在用户输出token后能够长久化存储这个token。还须要有一个界面能够删掉这个token,让用户有机会能够输出新的token。尤其用户批改了权限之后,那么就必须要有一个更新token的中央。
导航
用户在进入APP之后,在点击Repo选项之后,!如果不存在这么一个Token,则会进入token页面。在用户输出token之后能力持续前面的性能。
用户在输出Token页输出token后跳转到列表页。在Settings页能够删掉Token,而后主动跳转到Token页。
在用户胜利输出token,进入repo列表页能够看到repo列表。当初只显示facebook上面的公开repo。前面退出search bar能够输出owner,这样就能够管制要搜寻的是哪些repo了。
URQL根本配置
urql的配置分两局部。第一是provider的配置。应用provider能够让所有调用graphql api的中央都很不便的拿到申请的endpoint和须要的auth token。当然不是明文的读取而是能够间接调用查问。
配置Provider
在App.tsx能够看到:
<Provider value={client}> <NavigationContainer> <Stack.Navigator initialRouteName="Token"> <Stack.Screen name="Tabs" component={Tabs} options={{ headerShown: false }} /> </Stack.Navigator> </NavigationContainer> </Provider>
这个Provider和react-redux的provider的作用一样。这里urql的provider提供的是一个client。
Exchange
Exchange是urql的一个中间件机制。这个机制也和Redux的中间件机制相似。
这里咱们须要给官网提供的authExchange
填空,把获取和应用token的逻辑加进去。
首先须要装置authExchange
:
yarn add @urql/exchange-auth
而后在门路:src/data/graphqlClient.ts下能够看到给authExchange
填空的代码。在这里须要增加的除了上文说的获取token,应用token之外还有错误处理的内容。之类为了简略,错误处理的局部先疏忽。有须要的同学能够钻研官网实例。
获取token的办法是getAuth
。咱们的token是在Github配置生成,而后用户残缺增加并存储在APP的里。所以不须要额定的API调用获取token。
getAuth: async ({ authState }): Promise<AuthState | null> => { try { if (!authState) { const token = await AsyncStorage.getItem(GITHUB_TOKEN_KEY); return { token } as AuthState; // * } return null; } catch (e) { return null; } },
在加星这一步能够看到,token是作为authState
对象的一个属性返回了。
应用token是通过办法addAuthToOperation
实现的。在这里最初会返回一个新建的operation。外面就寄存了从getAuth
拿到的token:
addAuthToOperation: ({ authState, operation }) => { // ...略 return makeOperation(operation.kind, operation, { ...operation.context, fetchOptions: { ...fetchOptions, headers: { ...fetchOptions.headers, Authorization: `Bearer ${authState.token}`, // * }, }, }); },
在加*这一步应用了token,从authState
里读出了token放在header的认证里随着api申请发送到了后端。
填充urql的client
通过Exchange配置好了token之后,要害的一步就实现了。接下来就须要把配置号的exchange和graphql的endpoint都增加到client里供graphql的查问应用。
const getGraphqlClient = () => { const client = createClient({ url: 'https://api.github.com/graphql', // 1 exchanges: [ dedupExchange, cacheExchange, authExchange({ // 2 ...authConfig, }), fetchExchange, ], }); return client;};export { getGraphqlClient }; // 3
- 在url属性增加github的graphql的endpoint:
https://api.github.com/graphql
。 - 把auth exchange增加到exchange数组里。在这里配置的时候须要留神同步操作的exchange要放在异步操作的exchange后面。所以,
authExchange
要放在第三位。
实现一个查问
实现了下面的配置之后,咱们能够开始实现一个简略的查问了。
在src/GithubScreen.tsx文件里能够看到具体的查问和执行后的成果。
首先来筹备咱们的查问语句。
import { gql, useQuery } from 'urql'; // 1const REPO_QUERY = gql` // 2 query searchRepos($query: String!) { search(query: $query, type: REPOSITORY, first: 50) { repositoryCount pageInfo { endCursor startCursor } edges { node { ... on Repository { name } } } } }`;
- 引入urql到工具办法gql和useQuery。useQuery前面会用到
- 编写查问语句。
这个查问语句看起来会让初学者手足无措。下面的例子咱们也只是提到了query,metation之类少数几个关键字。那么这么长的(还不算长)查问语句如何能写进去呢。github专门提供了一个graphql api的explorer。点击这里到explorer。事实上,在很多语言对GraphQL的实现里都有这样一个explorer,至多是在开发阶段能够享受到这个服务。
- 首先在这个页面登录你的github账号。
- 在GraphiQL里就能够测试各种各样的查问语句了。
- 如果你有schema不分明的能够看最右面的Doc文档
- 左下角的Query Variable能够输出查问的变量。这里就是query,对应的是repo的owner和repo的license类型。
- 两头一列就是查问的后果。
在两头看到查问后果之后,就能够判断你的查问语句是否适合。在本例中就是咱们须要的查问语句了,间接复制到咱们的代码里应用。
或者,如果你对于schema的定义略有理解的话,比方咱们这次要查问的是repository。也能够应用查问语句编辑器外面的智能提醒。整个来说,编写查问、批改语句是十分不便的。
一个简略的查问
下面说到如何编写一个查问语句,当初来应用这个语句查问repo列表。
urql也提供了这样的一个hook给react应用。
import { gql, useQuery } from 'urql'; // 1const REPO_QUERY = gql `query searchRepos(...) { ... }`;const GithubScreen = () => { const [result] = useQuery({ // 2 query: REPO_QUERY, variables: { query: 'user:facebook' }, }); const { data, fetching, error } = result; // 3 // ...略...}
很简略一个简略的查问就能够搞定了。
- 只须要请
useQuery
出场。 - 应用useQuery。这个hook还会返回一个从新执行查问的办法,次要使给刷新时应用。
- 网络申请三状态,data是数据,fetching示意申请中,error是查问呈现谬误。
前面的代码能够依据呈现的作出不同解决。
最初在FlatList中显示user是facebook的所有公开repo。
最初
一个简略的查问在这个app里就曾经实现了。然而显然还有一些工作须要做。比方,loading和error解决都显得比拟简陋。咱们在后面的系列里提到了redux-toolkit。是否能够有一个slice来让这些逻辑的解决和redux联合在一起。
咱们在依赖里也曾经增加了react-native-paper
组件库。这个库能够在native和web上通用。我还没有把web断的截图放上来,次要因为有点惨不忍赌。UI也能够在前面稍作丑化。
最次要的工作是如何在理论的开发中应用graphql。它的后劲绝不只是看起来很新鲜这么简略看,而是能够实实在在的解决问题的。前端的同学会遇到一个最大的阻力就是来自于后端同学是否接管这一不太新的新事物。
在youtube上有一个30分钟搞定graphql的视屏,点这里能够看。理论后端要整合graphql必定不会像视屏里的那么容易,而且他自身也仅仅演示了查问操作的解决。不过也不会像设想的那么难。GraphQL是一个规范,在实现上也是由从内部查问语句到外部获取数据之间的转换,也就是视频里的resolver,和schema定义。它仍然依赖于底层的“DAO”层,或者是rest api的http申请。在GraphQL实现之后的收益就十分的不言而喻,数据生产端(各种App)对于后端批改的需要会大幅度缩小。摆弄query语句就能够何必后端新增API呢?