它会产生什么问题?当我们的程序越来越庞大、越来越臃肿时,各个业务之间的数据和前端接口的耦合度可能会非常高,这不仅会降低维护成本,而且开发成本会飙升,而且可能会有更多的重复性工作要做。由此,我们认为可以提取一些常见的东西。针对这个问题,前端领域衍生出很多优秀的框架,其中react和vue应用最为广泛,通过组件化实现代码复用和相互独立。Graphql是针对后端的。前端决定请求的数据格式,后端返回一个固定的数据模型,就像前端发送SQL查询语句一样。这样既解决了程序中不同业务之间的数据依赖,又可以实现数据复用。完了,是时候展示真正的技术了。实现一个基于graphql的serviceschema模式应该算是整个graphql的核心内容。用于描述服务器返回的数据类型和结构,客户端请求时,必须保证请求内容与服务器要求的格式一致,例如。当我们的请求体看起来像这样{article(id:"1"){title}}那么返回的数据结构就是{"data":{"article":{"title":"GraphqlPreliminaryStudy"}}}它这里有必要说明一下,GraphQL查询请求称为查询文档(querydocument),即GraphQL服务能够解析、验证并执行的一串请求字符串。...?query={article(id:"1"){title}}让我们生成一个稍微复杂的schemaimport{GraphQLObjectType,GraphQLSchema,GraphQLList,GraphQLString}from'graphql'import{getArticles}from'../model/文章'constarticleType=newGraphQLObjectType({name:'Article',fields:{ctime:{type:GraphQLString},title:{type:GraphQLString},}})exportconstschema=newGraphQLSchema({query:newGraphQLObjectType({name:'Query',fields:{articleList:{type:newGraphQLList(articleType),resolve:async(_,args)=>{returnawaitgetArticles()}}}})})此代码创建一个模式实例,它返回一个可能包含多个对象的数组,在对象中定义了title和ctime字段。返回的数据必须指定类型,graphql中定义了各种类型:GraphQLInt:integer,对应JavaScript的NumberGraphQLFloat:浮点数,对应JavaScript的NumberGraphQLString:string,对应JavaScript的StringGraphQLBoolean:Boolean,对应JavaScript的BooleanGraphQLID:IDValue是一个序列化后具有唯一值的字符串,可以看作是对应ES2015新的SymbolGraphQLList:ArrayGraphQLObjectType:ObjectGraphQLNonNull:强制类型的值不能为null,请求失败会报错。它可用于必须确保值不能为空的字段。GraphQLUnionType:联合类型用于描述一个字段可以支持的所有返回类型,即可能返回多种类型时。constPetType=newGraphQLUnionType({name:'Pet',types:[Type1,Type2],resolveType(value){if(valueinstanceofA){returnType1;}if(valueinstanceofB){返回Type2}}})因为GraphQL不是面向图数据库的查询语言,而是一个数据抽象层,包括对数据格式、数据关联、查询方法定义和实现等的封装。所以我们最终不得不调用一个查询数据库的服务来获取真正的数据,也就是下面的代码resolve:async(_,args)=>{returnawaitgetArticles()}toconnecttheschema显然我们需要连接服务器的架构将它们连接起来。//server.jsimportexpressfrom'express'import{schema}from'./schema'importgraphqlHTTPfrom'express-graphql'importbodyParserfrom'body-parserletapp=express()letPORT=3000//解析帖子内容为textapp.use(bodyParser.text({type:'application/graphql'}))app.get('/articles',graphqlHTTP({schema}))letserver=app.listen(PORT,function(){让主机=server.address().addressletport=server.address().portconsole.log('GraphQLlisteningathttp://%s:%s',host,port)})这里推荐使用express-graphql它会先解析我们body或query中的参数,如果没有,就会解析header中的参数。可以通过访问这个地址http://localhost:3000/articles?query={articleList{ctime,title}}mutation来验证除了查询操作,我们还有一个常见的更新操作。对于这样的操作,显然query是满足No的,所以涉及到mutation(变异,即修改数据)letschema=newGraphQLSchema({query:...mutation:newGraphQLObjectType({name:'RootMutationType',fields:{updateCount:{type:GraphQLInt,description:'Updatethecount',resolve:function(){count+=1returncount}}}})})至此我们完成了一个graphql服务,但是还有一定要多参与实际项目,据说relay和graphql比较适合react项目。在relay+graphql模型中,每个组件指定自己需要的数据。Relay调用数据,当数据更新时,将最新的数据提供给组件并缓存在客户端。当app需要更新数据时,在Action中创建一个graphqlchange,类似Redux。下次试试relay+graphql。
