񻵋
1.°ÑGraphQLºÍReact·ÅÔÚÒ»Æð¾ÍÈçͬÇÉ¿ËÁ¦Å仨Éú½´£¬Î¶µÀºÃ¼«ÁË¡£
2.GraphQL¿ÉÒÔ°ïÄã±àд³öÇ¿±í´ïÐԵIJéѯÀ´´ÓAPI¾«È·ÀÈ¡Êý¾Ý¡£
3.GraphQLÀàÐÍϵͳÊǷdz£Ç¿´óµÄ£¬¿ÉÒÔΪAPI½øÐÐÑéÖ¤²¢¼¯³ÉÁé»îµÄ²éѯ¡£
4.ÓÐʱÄã¿ÉÄÜÈÔÈ»ÐèÒªREST£¬Ã»¹ØÏµ£¬ËüÃÇÊÇ¿ÉÒÔºÍÆ½¹²´¦µÄ¡£
5.GraphQL¿ÉÒÔÔÚÈκκó¶ËÈí¼þÖÐʵÏÖ£¬ÄÇôҪÈçºÎ½«GraphQL¼¯³Éµ½ºó¶Ë·þÎñÖÐÄØ£¿
ÔÚ²¨Ê¿¶ÙµÄÒ»¼ä°ì¹«ÊÒÀÎÒ¡¢PacManŮʿ»¹ÓÐ×øÔÚÎÒ¶ÔÃæµÄ¿Í»§GregÕýΧ×ÅÆ¹ÅÒÇò×ÀºÈÆ¡¾Æ¡£GregÔÚÏà¹ØÒµÎñÉϽþÒùÒѾã¬ÊǸöÁîÈËÇÕÅåµÄ¿ª·¢Õß¡£ËûÖ±½ØÁ˵±µØÎÊÎÒ£º¡°GraphQLÓÐûÓÐΪÉú²ú»·¾³×öºÃ×¼±¸£¿¡±
ÕâôÎÊÒ²ºÜºÏÀí£¬ÒòΪËû´ÓÀ´Ã»ÓùýGraphQL¡£¶øÊÂʵÉÏ£¬GraphQLÔÚ2015Äê²Å¿ªÔ´£¬2016Äê²ÅÕæÕý×÷Ϊ±ê׼ʵʩ¡£³ýÁËFacebook£¬»¹ÓÐûÓÐÈËÕæÕýÔÚʹÓÃGraphQLÄØ£¿GregºÍËûµÄÍŶӶ¼·Ç³£ÊìϤREST£¬ËûÃÇÔÚ¹ýÈ¥¼¸ÄêÀïÓÃREST¹¹½¨¹ýºÃ¼¸¸öÓ¦Óá£ËûÃÇ»¹Ê¹ÓÃSwaggerÀ´½øÐÐÑéÖ¤ºÍÎĵµÉú³É£¬¶øÇÒÒ²ÓõĺÜ˳ÊÖ¡£ËùÒÔ£¬Ëû²Å»áÖÊÒÉGraphQLÊÇ·ñÕæµÄÊÇ×îºÃµÄÓ¦ÓóÌÐòͨÐŹܵÀ¡£
¿ªÃżûɽ£¬GraphQLÊÇʲô£¿
GraphQLÄÚº·á¸»£¬ËüÊÇÒ»¸öÁ÷Ðдʡ£¿áСº¢ÃÇÓÃËü£¬ËùÒÔÓÐÈËÈÏΪËüÖ»ÊÇê¼»¨Ò»ÏÖ£¬¾ÍÏñ½ñÌìµÄtechno
babel¡¢shiny¡¢new hotnessµÈµÈ¿á¿áµÄÐÎÈÝ´Ê¡£µ«ÊÇÎÒ±£Ö¤¾ø·ÇÈç´Ë¡£
Ê×ÏÈ£¬GraphQL²»ÊÇʲô£¿
ÔÚ¼ÌÐøÖ®Ç°£¬ÏÈÀ´Ïû³ýһЩ¹ØÓÚGraphQLµÄ³£¼ûÎó½â¡£
1.Îó½â£º¿Í»§¶Ë¿ÉÒÔÈκη½Ê½ÇëÇóÈκÎÊý¾Ý¡£ÀýÈçijһ¿Í»§¶ËÏëÒªËùÓеÄÓû§ºÍËûÃÇ×î°®µÄ±ùä¿ÁÜÀàÐÍ¡£Ö»Òª·þÎñÆ÷¶ËµÄģʽ¶¨ÒåÁËÕâ¸ö¹ØÏµÊǾÍÄÜʵÏÖ¡£
ÕæÏࣺ¿Í»§¶Ë½«ÊÜÏÞÓÚGraphQL·þÎñÆ÷¶Ë¶¨ÒåµÄÊý¾Ý¹ØÏµ¡£
2.Îó½â£ºGraaphQLÊÇ·ñ¼æÈÝMS SQL£¿²»¼æÈÝ£¬ËüÒ²²»¼æÈÝMongoDB¡¢Oracle¡¢MySQL¡¢PostgreSQL¡¢Redis¡¢CouchDBºÍElasticsearch¡£
ÕæÏࣺGraphQL²¢²»Ö±½Ó¶Ô½ÓÊý¾Ý¿â¡£Ëü½ÓÊÕÀ´×Ô¿Í»§¶ËµÄÇëÇó£¬È»ºóÓɺó¶ËÈí¼þͨ¹ýÇëÇóÊý¾ÝÀ´²éѯÊý¾Ý´æ´¢£¬²¢·µ»ØÓëGraphQLģʽ¸ñʽÏàÈݵÄÊý¾Ý¡£
3.Îó½â£ºGraphQLºÍRESTÄã±ØÐë¶þѡһ¡£ºú˵¡£
ÕæÏࣺ¿ÉÒÔÇáËɵØÔÚ·þÎñÆ÷¶ËͬʱÌṩËüÃÇ¡£
GraphQLÊÇÒ»ÖÖÇ¿ÀàÐÍÓïÑÔ
ËµÕæµÄ£¬GraphQLÊÇÒ»ÖÖÓïÑÔ£¿Äǵ±È»£¡ÏÈÀ´¿´¿´ÏÂÃæÕâЩ¼òµ¥µÄ¶¨Ò壬ÕâÊÇÒ»¸öËõÂÔͼµÄ¶¨Òå¡£
type
Thumbnail {
# ͼƬµÄURL£¬!±íʾ±ØÐè
uri: String!
# ¿í¶È£¨ÏñËØ£©
width: Int
# ¸ß¶È£¨ÏñËØ£©
height: Int
# ×÷ΪͼƬtitle±êÇ©µÄ×Ö·û´®
title: String
} |
ÈçÄãËù¼û£¬ÒÔÉ϶¨ÒåÁËÒ»¸öÃûΪThumbnailµÄÀàÐÍ»ò¶ÔÏó¡£Õâ¸ö¶ÔÏóÓм¸¸öÊôÐÔ£¬ÆäÖÐurlÊÇÒ»¸östring£¬widthºÍheightÊÇÕûÊý£¬titleÒ²ÊÇÒ»¸östring¡£
ÕâÀïÓÐÒ»¸öºÜ°ôµÄGraphQLÓïÑԲο¼Êֲᡣ
GraphQLÊǹØÓÚ¹ØÏµµÄ
GraphQLµÄÇ¿´óÖ®´¦²»Ö»ÔÚÓÚÆä¶¨ÒåµÄÀàÐÍ£¬»¹Éæ¼°ÕâЩÀàÐÍÊÇÈçºÎ¹ØÁªµÄ¡£À´¿´Ò»¸öPersonÀàÐÍ£¬ÎÒÃÇ¿ÉÒÔ½«Ëü¹ØÁªµ½ÁíÒ»¸öÀàÐÍ¡ª¡ªAddress¡£Õâ¸ö¹ØÁªÓɶ¨Ò彨Á¢£¬ÏÖÔÚ¿Í»§¶Ë¿ÉÒÔÇëÇóÒ»¸öperson²¢ÊÓÇé¿öÀ´½ÓÊÕËûÃǵĵØÖ·ÁÐ±í¡£
type
Address {
street: String
city: String
state: String
zip: String
country: String
}
type Person {
# Ãû
fname: String!
# ÐÕ
lname: String
# ÄêÁä
age: Int
# µØÖ·Áбí
addresses: [Address]
} |
GraphQLÊÇÒ»ÖÖ²éѯÓïÑÔ
GraphQLÕⲿ·Ö·ûºÏ´ó¶àÊý¿ª·¢ÕßµÄÀí½â¡ª¡ªÒ»ÖÖ²éѯÓïÑÔ£¬×÷ΪRESTµÄÒ»¸öÌæ´úÆ·¡£ÄÇôÊÇʲôÈÃËü±ÈREST¸üºÃ£¿
¿ÉÒÔÕâôÈÏΪ£¬RESTÊǶþάµÄ£¬¶øGraphQLÊÇÈýάµÄ¡£
ÔÚ×ÊÔ´½»»¥Ê±RESTÑÏÖØÒÀÀµURL£¬¶øGraphQLÈ´¿ÉÒÔ·½±ãµØÓë¶à¼¶×ÊÔ´½øÐн»»¥¡£ÀýÈ磬һ¸öGraphQL¿Í»§¶Ë¿ÉÒÔͨ¹ýIDÇëÇóÒ»¸öPerson£¬²¢ÔÚ½«Õâ¸öPersonµÄFriendÁÐ±í£¨Ò»¸öPersonÊý×飩ǶÌ×ÔÚÏìÓ¦ÖС£ÔÚÿ¸öFriendÖÐÓÖ¿ÉÒÔÇëÇóËûÃǵĵØÖ·£¨Ò»¸öAddressÊý×飩¡£ÏÂÃæÊÇÒ»¸öǶÌײéѯµÄÀý×Ó¡£
query
{
person(id: 123) {
id
friends {
id
addresses: {
street
city
state
zip
}
}
}
} |
RESTÓëHTTP״̬´úÂë¸ß¶ÈñîºÏ£¬Èç200ºÍ404¡£¶øGraphQL²»Ê¹ÓÃHTTP״̬´úÂ룬¶øÊÇÔÚÏìÓ¦ÖÐʹÓÃÒ»¸ö´íÎóÊý×é¡£
ÔÚΪ¶à¼¶×ÊÔ´ÖÆ¶¨IDʱ£¬±ÈÈç post > comment > author >
email£¬RESTÖеÄGET»á±äµÃºÜ±¿ÖØ¡£¶øGraphQL¿ÉÒÔÇáÒ×µØÀûÓÃÀàÐͶ¨ÒåºÍ¹ØÏµÀ´´¦Àí¡£
GraphQL×Ô¶¯ÑéÖ¤ÊäÈëÊý¾Ý¡£ÀýÈ磬Èç϶¨ÒåÁËÒ»¸öinput¡£Èç¹û¿Í»§¶ËÌá½»ÁËÒ»¸östring×÷Ϊage£¬GraphQL»áÅ׳öÒ»¸ö´íÎó£»Èç¹ûfnameΪ¿Õ£¬ËüÒ²»áÅ׳öÒ»¸ö´íÎó¡£
input
Person {
# Ãû
fname: String!
# ÐÕ
lname: String
# ÄêÁä
age: Int
} |
ÔÚAPI·µ»ØÊý¾Ýʱ£¬Ò²»á½øÐÐÑéÖ¤ºÍ¸ñʽ»¯À´Æ¥Å䶨ÒåµÄģʽ¡£µ±Äã´ÓÊý¾Ý¿â²éѯһ¸öperson¼Ç¼£¬¶øËüÈ´ÒâÍ⽫password×Ö¶ÎÒ²·¢Ë͸ø¿Í»§¶Ëʱ£¬Õâ¾ÍºÜÈÝÒ×´¦Àí¡£
ÓÉÓÚGraphQLµÄ¶¨ÒåÖÐûÓÐpassword£¬Ëü»áĬĬµØ°Ñpassword´ÓÏìÓ¦ÖÐɾµô¡£
GraphQLÊÇ¿ÉÀ©Õ¹µÄ
¼ÙÉèÄ㿪ʼ±àд×Ô¼ºµÄGraphQLģʽ£¬²¢ÇÒ´òËã¸Ä±äÈÕÆÚ´¦ÀíµÄ·½Ê½¡£±ÈÈçÄã¿ÉÄܸüϲ»¶ÒÔʱ¼ä´ÁµÄÐÎʽ·µ»Ø¸ø¿Í»§¶Ë£¬¶ø²»ÊÇISO×Ö·û´®¡£Äã¿ÉÒÔ¶¨ÒåÒ»¸ö×Ô¼ºµÄScalarÀàÐͽ»¸øGraphQL£¬È»ºóÖ»ÐèÒª¶¨ÒåÕâ¸öScslarÈçºÎ½âÎöºÍÐòÁл¯Êý¾Ý¡£ÏÂÃæÊÇÒ»¸ö×Ô¶¨ÒåµÄData
scalar£¬Ëü·µ»ØÕûÊýÐÎʽµÄÈÕÆÚ¡£Äã»á×¢Òâµ½ÓÐÒ»¸ö´¦ÀíÀ´×Ô¿Í»§¶ËÊý¾ÝµÄparseValueº¯Êý£¬»¹ÓÐÒ»¸öÔÚ·¢Ë͸ø¿Í»§¶Ë֮ǰ´¦ÀíÊý¾ÝµÄserializeº¯Êý¡£
const
{ GraphQLScalarType } = require('graphql')
const { Kind } = require('graphql/language')
exports.Date = new GraphQLScalarType({
name: 'Date',
description: 'Date custom scalar type',
parseValue (value) {
return new Date(value) // À´×Ô¿Í»§¶ËµÄÖµ
},
serialize (value) {
if (typeof value === 'object') {
return value.getTime() // ·¢Ë͸ø¿Í»§¶ËµÄÖµ
}
return value
},
parseLiteral (ast) {
if (ast.kind === Kind.INT) {
return parseInt(ast.value, 10) // ast value
is always in string format
}
return null
}
}) |
µ±È»£¬GraphQLÔÚ2015Äê²Å±»Facebook¿ªÔ´£¬2016Äê²Å¿ªÊ¼³ÉΪ±ê×¼¡£ËüºÜÄêÇᣬµ«Ò²ÓÐÓÅÊÆ¡£
1.·õ»¯ÀúÊ·³¤£ºFacebookÊDzÅ2015Äê²Å½«Ëü¿ªÔ´£¬µ«ÊÇÆäʵÔÚ2012Äê¾ÍÒѾ¿ª·¢³öÀ´£¬¶øÇÒÔÚ¹«²¼Ö®Ç°ÒѾÔÚÄÚ²¿¹ã·ºÊ¹Óá£ÒªÖªµÀÊÀ½çÉÏ×î´óµÄ¿Æ¼¼¹«Ë¾Ö®Ò»ÒѾ°ÑËü·ÅÔÚÁËÓ¦ÓõĺËÐÄλÖá£
2.¹¤¾ß£ººóÃæ»á¿´µ½£¬Î§ÈÆGraphQLµÄ¹¤¾ß·¢Õ¹Ñ¸ÃÍ£¬GraphQLÒѾӵÓÐÁËÐí¶à³ÉÊìµÄ¹¤¾ßºÍ¿â¡£Ïê¼û
GraphQL×ÊÔ´¿â¡£
3.±ê×¼»¯£ºÐí¶à¹«Ë¾¶¼»á·¢²¼¿ªÔ´Èí¼þ£¬µ«ÊÇGraphQLÒѾ¸ü½øÒ»²½³ÉΪһÏî±ê×¼£¨²Ý°¸½×¶Î£©¡£¿ÉÒÔÉîÈëÔĶÁϱê×¼¡£
³ÉΪ±ê×¼¸ü¿ÉÄܻᱻÆäËû¹«Ë¾»òÕßÕû¸öÐÐÒµËù²ÉÄÉ¡£
ÎÒÈ·ÐÅGraphQLÒѾΪÉú²ú»·¾³×öºÃÁË×¼±¸¡£ÄÇôÏÂÃæ×öÊ²Ã´ÄØ£¿
ÏÖÔÚÎÒÃÇÒѾ¶ÔGraphQLµÄ¹¹³ÉÓÐÁËÒ»µãÈÏʶ£¬¶ÔÓÚËüÎªÖØ¶ÈÉú²ú»·¾³ÖÐʹÓÃËù×öµÄ×¼±¸Ò²ÓÐÁ˸üºÃµÄÁ˽⡣ÏÂÃæÈÃÎÒÃÇÀ´¹¹½¨Ò»¸öReact/Node.jsÓ¦ÓÃÀ´Êµ¼ÊÔËÓÃGraphQL¡£
²»ÐèÒªÌØÊâÎäÆ÷
ÏÈ˵Çå³þ£¬ÔÚ¿Í»§¶ËÄãÍêÈ«²»ÐèÒªÌØ±ðµÄ¿âÀ´·¢ËÍGraphQLÇëÇó¡£GraphQL²»¹ý¾ÍÊǽ«Ò»¸öÌØ¶¨µÄJSON¶ÔÏóPOSTµ½Öն˲¢½ÓÊÜ·µ»ØµÄJSON¡£ÈçÏÂGraphQL»áPOSTµ½Öն˵ÄʾÀý¡£
{
"query": "query tag($id:ID) {
tag(id:$id) { id title }}",
"variables": {
"id": "6d726d65-fb99-4fa7-9463-b79bad7f16a7"
}
} |
¿ÉÒÔ¿´µ½Á½ÌõÊôÐÔ¡£
1.query£ºÒ»¸ö±íʾGraphQL²éѯµÄ×Ö·û´®¡£
2.variables£ºÒ»¸öGraphQLËùÐè±äÁ¿µÄJSON¶ÔÏó¡£×¢ÒâÔÚ²éѯ×Ö·û´®ÖÐËüÃÇҪǰ׺һ¸ö$£¨Èç$id£©¡£
¾ÍÕâÑù£¬Ëü½«°´ÕÕqueryÖеÄÇëÇóÀ´Éú³ÉÏìÓ¦¡£
ÐÝ˹¶Ù£¬ÕâÀïÊǰ¢²¨ÂÞ£¬ÕâÀïûÓÐÎÊÌâ¡£
½éÉÜÏÂÎÒ×îϲ»¶µÄGraphQL¹¤¾ßÌ×¼þ¡ª¡ªApollo¡£
ApolloµÄ¿ª·¢ÕßÃÇ´´½¨ÁËÒ»Ì×ÉñÆæµÄ¹¤¾ß£¬¿ÉÒÔÓÃËü¹¹½¨Reactǰ¶ËºÍNode.jsºó¶Ë¡£ÊÂʵÉÏ£¬ËûÃDz»Ö»ÌṩReactºÍNode.jsµÄGraphQL¹¤¾ß£¬Angular¡¢Vanilla
JS¡¢Swift£¨iOS£©ºÍAndroidÒ²¶¼ÓС£
½ñÌìÎÒÃÇ»áÔÚÓõ½µÄ¼¸¸öApollo¹¤¾ß£º
1.react-apollo£ºÎªReactÓ¦Óü¯³ÉGraphQLµÄ¹¤¾ß
2.graphql-server-express£ºÒ»¸öΪGraphQL·þÎñÆ÷´¦ÀíÇëÇóºÍÏìÓ¦µÄNode.js/ExpressJSÖмä¼þ
3.graphql-tools:ÓÃÀ´½«GraphQLģʽÓïÑÔת»»ÎªExpressJS·þÎñÆ÷¿ÉÀí½âµÄº¯ÊýµÄ¹¤¾ß¿â
App·¢Éäµ¹¼ÆÊ±
²»ÀË·Ñʱ¼ä£¬ÈÃÎÒÃǹ¹½¨Ò»¸ö¼òµ¥µÄÓ¦ÓÃÀ´ÑÝʾReact¡¢Node.jsºÍGraphQL¡£ÏÖÔÚ£¬´´½¨Ò»¸ö¼òµ¥µÄͨѶ¼ӦÓã¬Ëü¿ÉÒÔÌí¼ÓÁªÏµÈ˲¢ÁгöËùÓÐÁªÏµÈË¡£
Ê×ÏÈ
ÔÚ¿ª¶¯Ö®Ç°ÒªÏÈÐй滮£¬ÎÒÃÇͨ¹ý´´½¨GraphQLģʽÀ´ÊµÏÖ¡£Õ⽫¶¨ÒåGraphQL·þÎñÆ÷½ÓÊÜÇëÇóºÍ·µ»ØÏìÓ¦µÄÐÎʽ¡£ÏÂÃæÊÇPersonµÄGraphQLģʽ¡£
type
Person {
# personµÄÄÚ²¿£¬±ØÐè
id: ID!
# Ãû£¬±ØÐè
firstName: String!
# ÐÕ£¬±ØÐè
lastName: String!
# ÄêÁä
age: Int
# personµÄµç»°ºÅÂë
phone: String
# µç»°ºÅÂëÊÇ·ñÊÖ»úºÅ
isMobile: Boolean
# personµÄºÃÓÑ
bestFriend: Person
} |
ÕâÊÇΪpersonÉ趨µÄÒ»¸ö¼òµ¥Ä£Ê½£¬ÎÒÃÇ¿ÉÒÔÓÃËüÀ´¼Ç¼һ¸öÅóÓѵÄÁªÏµÐÅÏ¢¡£ÏÖÔÚGraphQLģʽ»¹ÐèÒª¶¨ÒåÁíÍâÁ½ÏÓÃÀ´´´½¨»ò¸üÐÂpersonµÄinputºÍ¿Í»§¶Ëµ÷ÓõIJÙ×÷¡£ÏÈÀ´¿´ÏÂPersonµÄinput¡£
input
PersonInput {
# personµÄÄÚ²¿ID
id: ID
# Ãû£¬±ØÐè
firstName: String!
# ÐÕ£¬±ØÐè
lastName: String!
# ÄêÁä
age: Int
# personµÄµç»°ºÅÂë
phone: String
# µç»°ºÅÂëÊÇ·ñÊÖ»úºÅ
isMobile: Boolean
# personµÄºÃÓѵÄID
bestFriend: ID
} |
ºÙ£¬µ½µ×·¢ÉúÁËʲô£¿
¿´ÆðÀ´Ö»ÊǰÑPerson ÀàÐÍÓÃÔÚÁËinputÖУ¬Ã»´í¡£GraphQL½«ÊäÈëºÍÊä³ö×öÁËÒ»Ð©Çø±ð¶Ô´ý¡£ÀýÈçid£¬¶ÔÓÚÀàÐͺÍÊä³ö¾ÍÐèÒªËü£¬¶øÊäÈëÔò²»ÐèÒª¡£Ë¼¿¼Ï£¬µ±´´½¨Ò»¸öÐÂpersonʱ£¬²¢²»ÖªµÀÊý¾Ý¿â»áÖ¸ÅɸøËüÄĸöID¡£Èç¹û¸ø³öÁËÒ»¸öid£¬ÄǾÍÓ¦¸ÃÖªµÀÕâ²»ÊÇн¨£¬¶øÊǸüС£ÁíÍ⣬bestFriendÖ»ÊÇÊäÈëµÄÒ»¸öID£¬µ«ÊÇÀàÐͺÍÏìÓ¦µÄÈ´ÊÇÒ»¸öÍêÕûµÄPersonÀàÐÍ¡£
×îºóÒªÔÚģʽÖж¨ÒåµÄÊǿͻ§¶Ëµ÷ÓõÄʵ¼Ê·½·¨ºÍ²Ù×÷£¬ÓÃÀ´´´½¨¡¢¸üкÍÁгöÁªÏµÈË¡£
type
Query {
# ͨ¹ýid»ñÈ¡µ¥¶ÀµÄPerson
person (id: ID): Person
# »ñÈ¡ËùÓеÄPerson
people: [Person!]!
}
type Mutation {
# ´´½¨»ò¸üÐÂÒ»¸öPerson
person (input: PersonInput): Person
}
schema {
query: Query
mutation: Mutation
} |
´Ó¶¨ÒåÖпÉÒÔ¿´µ½ÓÐÁ½¸ö²éѯ²Ù×÷ºÍÒ»¸ö±ä¸ü²Ù×÷¡£Á½¸ö²éѯ£¬personºÍpeople·Ö±ðÓÃÀ´»ñÈ¡µ¥¶ÀµÄpersonºÍÒ»¸öpersonÊý×é¡£±ä¸ü²Ù×÷ÔòÓÃÀ´´´½¨»ò¸üÐÂÒ»¸öperson¡£
ÏÖÔÚ½«ÕâÈý¸öģʽ¶¨Òå±£´æÔÚÒ»¸öÃûΪ¡°schema.gql¡±µÄÎļþÖС£Ëæºó½«ÔÚÉèÖ÷þÎñʱµ¼ÈëËü¡£
ÎÈ¹ÌµÄÆ½Ì¨
ÏÖÔÚÒѾ¶¨ÒåÁËÎÒÃǵÄģʽ£¬µ½ÁËÉèÖÃNode.js/Express·þÎñµÄʱºò¡£Ö®Ç°Ìá¹ýApolloÌṩһ¸öʵÓõÄÖмä¼þÀ´ÅäºÏExpress£¬²»¹ýÄÇÖ»ÊÇ×î¼òµ¥µÄ²¿·Ö¡£ÔÚÉèÖÃÓ¦ÓÃ֮ǰ£¬ÐèÒªÏÈÀ´ÌÖÂÛApollo
GraphQLµÄÒ»¸öÖØÒª¸ÅÄî¡£
½âÎöÆ÷
ʲôÊǽâÎöÆ÷£¿»¹¼ÇµÃ֮ǰÌá¹ýGraphQL²¢²»ÖªµÀÈçºÎ¸úÊý¾Ý¿â¶Ô»°°É£¿È·ÊµÈç´Ë¡£Ã¿¸ö²éѯ¡¢±ä¸üºÍÀàÐͶ¼ÐèÒªÖªµÀÈçºÎ½«GraphQLÇëÇó½âÎö³ÉΪһ¸ö¿É½ÓÊܵÄÏìÓ¦¡£Îª´Ë£¬ApolloÐèÒª´´½¨Ò»¸öÁ˽âÈçºÎ·µ»ØÊý¾ÝÇëÇóµÄ¶ÔÏó¡£
À´¿´¿´ÎÒÃÇģʽµÄ½âÎöÆ÷ÊÇʲôÑùµÄ¡£
¼òµ¥Æð¼û£¬°ÑÊý¾Ý±£´æÔÚÄÚ´æÖеÄÒ»¸ö¡®people¡¯Êý×éÖС£²»¹ý¶ÔÓÚʵ¼ÊµÄÓ¦Óã¬ÄãÐèÒªÓÃijÖÖÀàÐ͵ÄÊý¾Ý´æ´¢¡£
//
½«¾Íһϣ¬ÓÃÄÚ´æÀïµÄÊý×é×÷ΪÊý¾Ý¿â
const people = [ ];
const resolvers = {
Query: {
// »ñȡһ¸öperson
person (_, { id }) {
return people[id];
},
// »ñÈ¡ËùÓеÄperson
people () {
return people;
}
},
Mutation: {
person (_, { input }) {
// Èç¹û¸ÃpersonÒÑ´æÔÚÔò½øÐиüÐÂ
if (input.id in people) {
people[input.id] = input;
return input;
}
// ĬÈÏÌí¼Ó£¨»ò´´½¨£©¸Ãperson
// ½«idÉèΪ¼Ç¼µÄË÷Òý
input.id = people.length
people.push(input)
return input
},
},
Person: {
// ½«ºÃÓÑId½âÎö³ÉÒ»Ìõperson¼Ç¼
bestFriend (person) {
return people[person.bestFriend];
}
}
};
module.exports = resolvers; |
¿´ÆðÀ´ºÜÊìϤ°É¡£Æäʵ½âÎöÆ÷¾ÍÊÇÒ»¸öJavaScript¶ÔÏó£¬ËüµÄ¹Ø¼ü×ÖÓëÎÒÃǵÄģʽÏàÆ¥Åä¡£ÓÉÓÚÖ»ÓÃÁËÒ»¸ö¼òµ¥µÄJavaScriptÊý¾Ý×÷ΪÊý¾Ý´æ´¢£¬ÎÒÃǾÍÓÃË÷ÒýÀ´×÷ΪpersonµÄid¡£
Apollo½«¶¨ÒåµÄ½âÎöÆ÷ÓëÎÒÃǵÄģʽÏàÆ¥Åä¡£ÏÖÔÚËü¾ÍÖªµÀÈçºÎ´¦Àíÿ¸öÀàÐ͵ÄÇëÇóÁË¡£ËäÈ»Ö»Éæ¼°Æ¤Ã«£¬Ò²×ã¹»ÄãÁ˽â²éѯ¡¢±ä¸ü¡¢½âÎöÆ÷ºÍÀàÐ͵Ť×÷·½Ê½¡£
Çë×¢ÒâPersonµÄ½âÎöÆ÷¡£Ä¬ÈÏÇé¿öÏ£¬ApolloÖ»»áÔÑù·µ»Ø¶ÔÏóµÄÊôÐÔ£¬µ«ÓÐʱÐèÒª×öһЩ¸Ä±ä¡£À´¿´bestFriend½âÎöÆ÷£¬ÓÉÓÚËüÒª·µ»ØÒ»¸öPersonÀàÐÍ£¬ÎÒÃÇʹÓÃbestFriendµÄidÔÚpeopleÊý×éÖвéÕÒ²¢·µ»ØÕû¸öperson¡£
¼Çס£¬Èç¹û¿Í»§¶ËÖ»ÇëÇóÁËbestFriendÊôÐÔ£¬ÄÇôApollo½«Ö»´¥·¢bestFriendº¯Êý¡£
¼¯ºÏʱ¼ä
ÏÖÔÚÒѾÔÚschema.gqlÖж¨ÒåÁËģʽ£¬²¢ÔÚresolvers.jsÖж¨ÒåÁ˽âÎöÆ÷£¬È»ºó¾ÍÐèÒª°ÑÒ»Çж¼¼¯ºÏÔÚÒ»ÆðÆô¶¯GraphQL¡£ÕâÀﶨÒåÁËÒ»¸ö¼òµ¥µÄExpressÓ¦Ó㬿ÉÒÔ·ÅÔÚ³ÌÐòµÄindex.jsÖС£
const
fs = require('fs');
const path = require('path');
const express = require('express');
const bodyParser = require('body-parser');
const { graphqlExpress, graphiqlExpress } =
require('graphql-server-express');
const { makeExecutableSchema } = require('graphql-tools');
const typeDefs = fs.readFileSync(path.join(__dirname,
'./schema.gql'), 'utf8')
const resolvers = require('./resolvers');
const myGraphQLSchema = makeExecutableSchema({
typeDefs,
resolvers
});
var app = express();
// POSTÐèÒªÓõ½bodyParser
app.use('/graphql',
bodyParser.json(),
graphqlExpress({ schema: myGraphQLSchema })
);
app.use('/graphiql',
graphiqlExpress({ endpointUrl: '/graphql'})
);
app.listen(3000); |
±íÃæÉÏ¿´ÆðÀ´Í¦¸´ÔÓ£¬ÆäʵֻÊÇÕûºÏÁËģʽ¶¨Ò壨typeDefs£©£¬ÓÃmakeExecutableSchemaÈÃËüÓë½âÎöÆ÷ÏàÅ䣬×îºó½«GraphQLÌí¼Óµ½URL·¾¶/graphql¡£¿ÉÒÔÓÃÒÔÏÂÃüÁîÆô¶¯·þÎñ;
node index.js
Espress·þÎñ½«±»Æô¶¯²¢ÔÚhttp://localhost:3000/graphql¼àÌýGraphQL
POST¡£
ÁíÍ⻹µ¼ÈëÁËGraphiQL£¬¿ÉÒÔÔÚhttp://localhost:3000/graphiql²é¿´GraphiQLä¯ÀÀÆ÷ºÍÎĵµ¡£
ÏÖÔÚAPI·þÎñÒѾÔËÐÐÆðÀ´ÁË£¬Äã¿ÉÒÔµã»÷Á´½Óhttp://localhost:3000/graphiql.....½øÐбä¸ü²Ù×÷Ìí¼ÓÒ»¸öperson¡£
ºÜ¿á°É£¿
¼ÌÐøÔÙÊÔÊÔÆäËû²Ù×÷£¬ºó¶ËÔËÐÐÆðÀ´µÄЧ¹ûºÜˬ²»ÊÇô£¿ÎÒÃÇÔÙÀ´¿´Ò»Ð©¼òµ¥µÄReact×é¼þÒÔ¼°ËüÃÇÈçºÎÓëGraphQLºó¶ËͨÐÅ¡£
ǰ¶Ë¿ØÖÆÖÐÐÄ
ÏÖÔÚÎÒÃÇͨ¹ýչʾһЩReact×é¼þÀ´ÔËÓÃ֮ǰ¶¨ÒåµÄÁªÏµÈËAPI¡£Ê¹ÓÃWebpack¡¢React Router¡¢ReduxºÍÆäËûÔªËØ×齨ÍêÕûµÄǰ¶Ë³¬³öÁ˱¾Îĵķ¶Î§£¬ËùÒÔֻչʾApollo½«ÈçºÎÈÚÈë¡£
Ê×ÏÈ£¬ÏÈ¿´Ò»Ð©¶¥²ã´úÂ룬ÐèÒªÓõ½×é¼þÖÐApolloµÄReact¿â¡£Õâ¸önpmÄ£¿é½Ð×öreact-apollo¡£
import
{ ApolloClient, ApolloProvider } from 'react-apollo';
// ´´½¨Ò»¸öÉÏÃæÌáµ½µÄ¿Í»§¶Ë
const client = new ApolloClient();
ReactDOM.render(
<ApolloProvider client={client}>
<MyAppComponent />
</ApolloProvider>,
document.getElementById('root')
) |
ÕâÊÇÒ»¸ö¼òµ¥Ê¾Àý£¬ËüÓÃApolloProvider¸ß½××é¼þ°ü×°ÁËAPP£¬¿ÉÒÔÔÚ¿Í»§¶ËºÍGraphQL·þÎñÆ÷Ö®¼ä½¨Á¢ËùÐèµÄͨÐÅ¡£
ÎÒÃÇÀ´¿´Ëü½«ÈçºÎչʾIDΪ10µÄPerson¡£ÏÂÃæµÄÀý×Ó½«ÔÚ×é¼þ×°Åäºó×Ô¶¯´¥·¢GraphQL²éѯ¡£²éѯ°´ÕÕconst
query = gql¡.;Ä£°åÀ´¶¨Òå¡£²éѯºÍPersonView×é¼þͨ¹ýʹÓÃÕâÀï¿´µ½µÄgraphql¿âÀ´½øÐÐÕûºÏ¡£
ÕâÊÇPerson×é¼þµÄÒ»¸ö¸ß½××é¼þ¡£¾ÍÊÇ˵Apollo½«ÓÚGraphQL·þÎñÆ÷±£³ÖÁªÏµ£¬µ±Ëü½Óµ½Ò»¸öÓ¦´ðʱ£¬Apollo»á½«ÕâЩÊôÐÔ×÷Ϊprops.data.person×¢Èëµ½ÄãµÄ×é¼þ¡£
import
React from 'react'
import { gql, graphql } from 'react-apollo'
function Person ({ data: { person = {} } })
{
return (
<PersonView data={person} />
);
}
const query = gql`
query person($id: ID) {
person(id: $id) {
id
firstName
lastName
age
phone
isMobile
bestFriend {
id
firstName
}
}
}
`;
export default graphql(query, {
options: () => ({
variables: {
id: 10 // Äã¿ÉÄÜ»áʹÓÃURL²ÎÊý¶ø·ÇÓ²±àÂë
}
})
})(Person); |
½ÓÏÂÀ´¿´¿´±ä¸ü£¬Ëü²»Ì«Ò»Ñù¡£ÊÂʵÉÏ£¬²éѯºÍ±ä¸ü¿ÉÒÔÒÀÀµÍ¬ÑùµÄReact×é¼þ£¬ËùÒÔÎÒÃǶÔ֮ǰµÄÀý×Ó×öЩÀ©Õ¹À´ÈÃËü¿ÉÒÔ¸üÐÂperson¡£
import
React from 'react'
import { gql, graphql, compose } from 'react-apollo'
function Person ({ submit, data: { person =
{} } }) {
return (
<PersonView data={person} submit={submit}
/>
);
}
const query = gql`
¡ omitted ¡
`;
const update = gql`
mutation person($input: PersonInput) {
person(input: $input) {
id
firstName
lastName
age
phone
isMobile
bestFriend {
id
firstName
}
}
}
`;
export default compose(
graphql(query, {
options: () => ({
variables: {
id: 10 // Äã¿ÉÄÜ»áʹÓÃURL²ÎÊý¶ø·ÇÓ²±àÂë
}
})
}),
graphql(update, {
props: ({ mutate }) => ({
submit: (input) = mutate({ variables: { input
} })
})
})
)(Person);
|
×Ðϸ¹Û²ìÕâ¶Î´úÂ룬ÎÒÃÇÍÆ³öÁËcompose¹¤¾ß£¬¿ÉÒÔÓÃËüÔÚÒ»¸öµ¥¶ÀµÄ×é¼þÖÐ×éºÏ¶àÖÖGraphQL²Ù×÷¡£
ÎÒÃÇ»¹¶¨ÒåÁËÒ»¸öupdate²éѯÀ´Ê¹ÓÃÔÚģʽÖж¨ÒåµÄperson¸üС£ÔÚ´úÂëµÄβ²¿¿ÉÒÔ¿´µ½´´½¨ÁËÒ»¸öÃûΪsubmitµÄ°ü×°º¯Êý¡£Ëü×÷Ϊһ¸öÊôÐÔ´«µÝµ½Person×é¼þÖУ¬²¢´ÓÕâÀï´«µÝ¸øPersonView×é¼þ¡£
PersonView×é¼þ¿ÉÒÔÏñÏÂÃæµÄÀý×ÓÖÐÕâÑù¼òµ¥µ÷ÓÃsubmitº¯ÊýÀ´´¥·¢Ò»¸öperson¸üС£
props.submit({
firstName: ¡°Neil¡±,
lastName: ¡°Armstrong¡±,
¡
isMobile: true
}) |
µ±´¥·¢PersonÀàÐ͸üÐÂʱ£¬Apollo»á×Ô¶¯¸üÐÂÄãµÄ±¾µØ»º´æ¡£ËùÒÔÓ¦ÓÃÖÐÈκÎÓõ½Person¼Ç¼µÄµØ·½£¬¶¼½«±»×Ô¶¯¸üС£
×îºó£¬À´¿´¿´ÔÚÒ»¸ö±í¸ñÖÐչʾËùÓÐpeopleµÄ´úÂë¡£ÔÚÏÂÃæµÄÀý×ÓÖУ¬ÓÃÒ»¸ö¼òµ¥µÄHTML±í¸ñչʾperpleÇåµ¥¡£ÌرðҪעÒâloadingÊôÐÔ£¬ÕâÊÇApolloÔÚ»ñÈ¡Êý¾ÝʱÉèÖõÄÒ»¸öÊôÐÔ£¬Äã¿ÉÒÔÉèÖÃÒ»¸öÏÂÀÁбí×é¼þ»òÕ߯äËûUIÀ´Ìáʾ·ÃÎÊÕß¡£
»¹Ïñ֮ǰÄÇÑù¶¨ÒåReact×é¼þ¡£È»ºóqueryʹÓÃgql¹¤¾ß½«Ä£°åÎÄ×Öת»»ÎªÒ»¸öÓÐЧµÄGraphQLÇëÇó¡£×îÖÕ£¬ÓÃgraphql¹¤¾ß½«ËûÃǰóÔÚÒ»Æð¡£ÏÖÔÚÕâ¸ö×é¼þ×°Åäºó£¬×Ô¶¯´¥·¢²éѯ²¢¼ÓÔØºó¶Ë´æ´¢µÄpeople¡£
import
React from 'react'
import { gql, graphql } from 'react-apollo'
function People ({ data: { loading, people
= [] } }) {
// µ±»¹ÔÚ´ÓGraphQL»ñÈ¡Êý¾Ýʱ£¬Apollo½«ÉèÖÃloading = true
if (loading) return <Spinner />
return (
<table className='table table-hover table-striped'>
<tbody>
{people.map((person, i) =>
<tr key={i}>
<td>{person.firstName}</td>
<td>{person.lastName}</td>
<td>{person.age}</td>
<td>{person.phone}</td>
<td>{person.isMobile}</td>
<td>{person.bestFriend && person.bestFriend.firstName}</td>
</tr>
)}
</tbody>
</table>
);
}
const query = gql`
query people {
people {
id
firstName
lastName
age
phone
isMobile
bestFriend {
id
firstName
}
}
}
`;
export default graphql(query)(People); |
×ܽá
ÈçÄãËù¼û£¬GraphQLÊÇÒ»Ì×Ç¿´óµÄ¹¤¾ß£¬Äã¿ÉÒÔ½«ËüÕûºÏµ½ReactÓ¦ÓÃÖÐÀ´ÔöÇ¿API½»»¥¡£¶øÊ¹ÓÃApollo¿ÉÒÔ¸üÈÝÒ׵ؽ«GraphQLÌí¼Óµ½Reactǰ¶ËºÍNode.jsºó¶Ë¡£ÏÖÔÚÕýÊDzâÊÔÔÚGraphQLÖз¢ÏÖµÄм¼ÄܵĺÃʱ»ú¡£Äã¿ÉÒÔÔËÓÃÕâÃż¼Êõ±àдһ¸öСӦÓ㬻òÕßÇÄÇĵؽ«GraphQL°üº¬µ½ÒÑÓеÄAPI·þÎñÖС£ÎÞÂÛÑ¡ÔñÈçºÎÔÚÓ¦ÓÃÖÐÔËÓÃGraphQL£¬Äã¶¼½«»ñµÃºÜ¶àÀÖȤ¡£
|