Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓƵ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Model Center   Code  
»áÔ±   
   
 
     
   
 ¶©ÔÄ
  ¾èÖú
ÓÃGraphQLÔöÇ¿React
 
À´Ô´£º InfoQ ·¢²¼ÓÚ2017-8-17
  2513  次浏览      24
 

񻵋

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£¬Ä㶼½«»ñµÃºÜ¶àÀÖȤ¡£

   
2513 ´Îä¯ÀÀ       24
Ïà¹ØÎÄÕÂ

Éî¶È½âÎö£ºÇåÀíÀôúÂë
ÈçºÎ±àд³öÓµ±§±ä»¯µÄ´úÂë
Öع¹-ʹ´úÂë¸ü¼ò½àÓÅÃÀ
ÍŶÓÏîÄ¿¿ª·¢"±àÂë¹æ·¶"ϵÁÐÎÄÕÂ
Ïà¹ØÎĵµ

Öع¹-¸ÄÉƼÈÓдúÂëµÄÉè¼Æ
Èí¼þÖع¹v2
´úÂëÕû½àÖ®µÀ
¸ßÖÊÁ¿±à³Ì¹æ·¶
Ïà¹Ø¿Î³Ì

»ùÓÚHTML5¿Í»§¶Ë¡¢Web¶ËµÄÓ¦Óÿª·¢
HTML 5+CSS ¿ª·¢
ǶÈëʽC¸ßÖÊÁ¿±à³Ì
C++¸ß¼¶±à³Ì