Yelp GraphQL Styleguide - ðšã¹ããŒãèšèš
ããã¯å èšäº(GraphQL@Yelp Schema Design Guidelinesã®GraphQL Styleguide)ãèè ã®äžäºº Mark Larahããããèš±å¯ãããã ãæ¥æ¬èªèš³ãããã®ã§ãã
ðš ã¹ããŒãèšèš
GraphQLã¹ããŒãã¯ãYelpã®ãšã³ãžãã¢ãªã³ã°å šäœã«å¯ŸããŠã°ããŒãã«ã§ããæçµçã«ã¯ãŠãŒã¶ãŒåãããžãã¹ããŒã¿å šäœãGraphQLã§ã¢ãã«ååºæ¥ãããã«ããããšèããŠããŸãããã®ããŒãžã«ã¯ãã¯ãªãŒã³ã§äœ¿ããããã¹ã±ãŒã©ãã«ãªã¹ããŒããæäŸããããã«ãã©ã®ããã«èããã«ã€ããŠã®ã¬ã€ãã³ã¹ãå«ãŸããŠããŸãã
å ã«é²ãåã«ãã¹ããŒããã©ã®ããã«æ©èœããããç解ããããã«ããã®ããŒãã«é¢ããå ¬åŒããã¥ã¡ã³ãããã£ãšèªãããšã匷ããå§ãããŸãã
Contents
- åã®çš®é¡
- ãããã¬ãã«ã®ã¯ãšãªãæå°ã«ä¿ã€
- åã®åœåã¯å ·äœçã«ãã
- ãã£ãŒã«ãã«åå空éãã€ããªã
- Viewã§ã¯ãªãããŒã¿ã説æãã
- IDã§ã¯ãªãåãä»ããŠãªã³ã¯ãã
- æ¢åã®æšæºåãããåãšã¹ã«ã©ãŒã䜿çšãã
- é¢é£ãããã£ãŒã«ããã°ã«ãŒãåãã
- 説æã«ã¯äžéåŒçšç¬Š(""")ã䜿çšãã
- ãã£ãŒã«ãã®èª¬æã¯ã¹ããŒã¹ã空ãã
- ã³ã¡ã³ããšèª¬æã§è¶ æ確ã«ãã
- ããã©ã«ãã§ã¯ãã»ãšãã©ã®ãªããžã§ã¯ããã£ãŒã«ãã«null蚱容åã䜿çšããŸãããå€ãã®äŸå€ããããŸã
åã®çš®é¡
äžè¬çã«ãYelpã«ã¯2ã€ã®åã®çš®é¡ããããŸãðè¿œå ããåã®çš®é¡ãæ€èšããå¿ èŠããããŸã:
- ã³ã¢å
Business
,User
çã¯ãYelpã«ãããŠå€ãã®ããŒãžãããŒã ãã³ã³ããŒãã³ãã«å ±éããŠããåã§ã - ãã¡ã€ã³åºæã®å
ãããã¯ã1ã€ãŸãã¯å°æ°ã®ã³ã³ããŒãã³ããããŒã ã§ã®ã¿äœ¿çšãããåã§ããäŸãã°BusinessClaimability
ãEventsPageLeftRailAttendWidget
ã§ãã
åã«ã€ããŠãã®ããã«èããããšã¯ãç§ãã¡ãã³ãã¥ãã±ãŒã·ã§ã³ãåãããªãŒããŒã·ããã確ç«ããã®ã«åœ¹ç«ã¡ãŸããããšãã°ãããã¯ç§ãã¡ã以äžã®ãããªããšã決å®ããã®ã«åœ¹ç«ã¡ãŸã:
- ã¹ããŒãå€æŽã«é¢ããã³ãŒãã¬ãã¥ãŒã§ã©ã®çšåºŠç²Ÿæ»ããå¿ èŠãããã
- ãªãŸã«ããåžžã«å€±æããããã«ãªã£ãŠããŸã£ãå Žåã®åœ±é¿ã¯äœã§ãã
ã³ã¢åã¯æãåºã䜿çšãããŠãããå€ãã®ã¯ãšãªã®ã«ãŒãã«ããããŸãããã®ãããéåžžã¯ã¹ããŒãã¬ã€ãã©ã€ã³ãæºããããã®åºæºãé«ããå®è¡æã®åé¡ã¯æ©æ¥ã«ããªã¢ãŒãžããå¿ èŠããããŸãã
ãããã¬ãã«ã®ã¯ãšãªãæå°ã«ä¿ã€
å¯èœãªéãã«ãŒãããŒããšããŠã³ã¢åã䜿çšããŠYelpã®ããŒã¿ãããªãŒãšããŠã¢ãã«åããå¿ èŠããããŸããæ°ãããããã¬ãã«ã®ã¯ãšãªãè¿œå ããåã«ã代ããã®æ¢åã®ã¿ã€ãã®å±æ§ãšããŠè¿œå ããã»ããçã«ããªã£ãŠãããã©ããæ€èšããŠãã ããã
Why?
ããããããšã§ã¹ããŒãããããã¬ãã«ã§èªã¿ããããªããããŒã¿ã®æ§ææ¹æ³ã®äžè²«æ§ãä¿ã€ããšãåºæ¥ãŸã
Example
root
ã®äžã®ãããã¬ãã«ã®ã¯ãšãªãšããŠcanClaimBusiness
ãè¿œå ãã代ããã«ããããæ¢åã®Businness
åã®å±æ§(claimability
)ãšããäºãã§ããŸãã
åã®åœåã¯å ·äœçã«ãã
åã®ååãå ·äœçã«æå®ããŠãã ãããïŒåŠ¥åœãªç¯å²ã§ïŒå¯èœãªéãåå空éã«ïŒ
Why?
ã©ã®åãä»ã®åã«é¢é£ããŠããããæ確ã«ããã®ã«åœ¹ç«ã¡ãååã®è¡çªãæžãããŸããïŒããšãã° Price
ã¯ãã·ãã¹ã®äŸ¡æ Œåž¯ã§ããïŒãããšãYelpã€ãã³ãã®ãã±ããäŸ¡æ Œã§ããïŒãããšãä»ã®äœãïŒïŒ
Example
Category
ã®ä»£ããã«BusinessCategory
ãåªå
ãã
ãã£ãŒã«ãã«åå空éãã€ããªã
äžèšã®è£è¶³ãšããŠããã£ãŒã«ãã¯é床ã«å ·äœç/åå空éçã§ããå¿ èŠã¯ãããŸããã
Why?
ãã£ãŒã«ãã¯ãã£ãŒã«ããæã€åã«ãã£ãŠæ¢ã«æé»çã«åå空éãã€ããããŠããŸããã€ãŸãããã£ãŒã«ãåã®ã³ã³ããã¹ãã§èŠªã®åãäœããåžžã«ç¥ã£ãŠããŸããïŒå¯Ÿè±¡çã«ãåã¯ã©ãããã§ãè¿ãããšãã§ããŸããã©ã®ãã£ãŒã«ãããããè¿ããã¯ããããŸãããïŒ
Example
- ãã¡ããã
type BusinessAddress {
"""
Formatted stringy version of address based on locale
It reflects a new line using a new line character
Example: 196 N Pleasant St\nAmherst, MA 01002
"""
formattedBusinessAddress: String
}
- ãã¡ãã奜ãŸãã
type BusinessAddress {
"""
Formatted stringy version of address based on locale
It reflects a new line using a new line character
Example: 196 N Pleasant St\nAmherst, MA 01002
"""
formatted: String
}
ããã®äŸå€ã¯ãã«ãŒãã¿ã€ãïŒQuery, Mutation, SubscriptionïŒã®ãã£ãŒã«ãã®å Žåã§ãããã®ãããªããããã¬ãã«ããã£ãŒã«ãã¯ã°ããŒãã«ã§ãããããããåå空éãå¿ èŠã§ãã
Viewã§ã¯ãªãããŒã¿ã説æãã
Why?
APIãæåã«äœãããã€ã³ã¿ãŒãã§ãŒã¹ã®èŠæ±ãšããŸãå¯æ¥ã«ãªã³ã¯ãããŠããªãããšã確èªããŠãã ãããiOSã¢ããªçšã®APIãæ§ç¯ããŠããå Žåã¯ãåŸã§ãã¹ã¯ãããPCããã£ãŒãã£ãŒãã©ã³çã®ä»ã®ããã€ã¹ã«ç§»æ€ããå¯èœæ§ããããŸããã¯ãšãªãäœæããæã¯ãã¢ããªã±ãŒã·ã§ã³ã®è¡šçŸæ¹æ³ã§ã¯ãªããå ã«ãªãããŒã¿ã«æ³šç®ããŠãã ããã
https://www.graphql.com/articles/4-years-of-graphql-lee-byron
Example
- Yelpã®çšèªã§èšãã°ãProfileã³ã³ããŒãã³ãã§ãŠãŒã¶ãŒã®æ å ±ãã¬ã³ããªã³ã°ããããã®ããŒã¿ãè¿ãããã«UserProfileCardåãè¿œå ããªãã§ãã ããã
- 代ããã«æ¢åã®
User
åã䜿çšããŠããŒã¿ãè¿ããProfile cardã³ã³ããŒãã³ãã«ããŒã¿ãå ¥åããŸãã
IDã§ã¯ãªãåãä»ããŠãªã³ã¯ãã
ããåãå¥ã®åããåç §ããå Žåã¯ããã®åã«çŽæ¥ãªã³ã¯ããŠãã ããã
Why?
ããã«ãããéçºè ã¯ããŒã¿ããã§ããããéã®æè»æ§ãé«ãŸããŸãããªã³ã¯ããŠããåã®IDã®ã¿ãæå®ããå Žåããã©ãŠã¶ã¯ãã®ãšã³ãã£ãã£ã«é¢ããããŒã¿ããã§ããããããã«è¿œå ã§ã¯ãšãªãå®è¡ããå¿ èŠãããããšãæå³ããŸãã
Example
ãã¡ããã
type Review {
"""
ID of the business that this review is about
"""
businessId: Int
}
ãã¡ãã奜ãŸãã
type Review {
"""
The business that this review is about
"""
business: Business
}
æ¢åã®æšæºåãããåãšã¹ã«ã©ãŒã䜿çšãã
以äžãè¡šçŸããããã®æ¢åã®æšæºåãããåããããšããŸãã
- åç
- æ¥ä»/æé
ãã®ãããªæ å ±ãè¡šããšãã¯ãããã®æ¢åã®æšæºåãããåã䜿çšããŸãã
Why?
ãããã®åã䜿çšãããšãã¹ããŒãå šäœã§å ±éã®ããŒã¿åãã¢ãã«åããŠäœ¿çšããæ¹æ³ãæšæºåã§ããŸããããã«ãããäœæ¥ãšæŠå¿µã®éè€ãåé¿ã§ããŸãã
Example
- ãã¡ããã
type Review {
"""
A photo that the user uploaded with this review
"""
uploadedPhotoUrl: String
"""
When was this review posted?
"""
createdAt: String
}
ãã¡ãã奜ãŸãã
type Review {
"""
A photo that the user uploaded with this review
"""
uploadedPhoto: BusinessPhoto
"""
When was this review posted?
"""
createdAt: DateTime
}
é¢é£ãããã£ãŒã«ããã°ã«ãŒãåãã
é¢é£ãããã£ãŒã«ããæ°ããåã«ã°ã«ãŒãåãéãããšå€±æããŸããã¹ããŒãã«ãã¹ããè¿œå ããããšãæããªãã§ãã ããã
Why?
Business ã User ãªã©ã®ã³ã¢ã¿ã€ããè¥å€§åããããšãæžãããããã³ã¢ã¿ã€ãã®ãã£ãŒã«ãæ°ãæå°éã«æããŠãæ¢åã®é¢é£ãããã£ãŒã«ããå ±éã®ãã¬ãã£ãã¯ã¹ã®äžã«ãµãã°ã«ãŒãäžããããšã§çºèŠããããããäºããå§ãããŸããïŒGraphiQLã®æ°çŸã®ãã£ãŒã«ãã§ããã¥ã¡ã³ãã®ãµã€ãããŒãã¹ã¯ããŒã«ããããšãæ³åããŠã¿ãŠãã ããïŒïŒ
次ã«ãçºèŠã®ããããã¯èª€ã£ãŠä»ã®å Žæã«éè€ãããã£ãŒã«ããè¿œå ããäºãåé¿ããããšã«åœ¹ç«ã¡ãŸãã
æ°ããåããåããŠãããããŸã ãµãã°ã«ãŒãåããå¿ èŠããããã©ããåãããªãå Žåã¯ãRule of threeãæ€èšããŠã¿ãŠãã ãããæåã«åã«çŽæ¥è¿œå ããŠãããããå°æ¥ä»ã®é¢é£ããã¿ã€ããè¿œå ããå¿ èŠãããå Žåã¯ããããéæšå¥šã«ããŠããã®æ°ãããã¿ãŒã³ã«ç§»è¡ããŠãã ããã
Example
ãã¡ããã
extend type Business {
"""
Is this business an advertiser with us?
"""
isAdvertiser: Boolean
"""
How many times have users clicked this business's advertisement
"""
adClicks: Number
"""
Amount of estimated revenue the business has earned from a campaign
"""
revenueFromCampaign: Number
"""
Search keywords that we should ads for this business on
"""
adKeywords: [String]
}
ãã¡ãã奜ãŸãã
type BusinessAdvertising {
"""
Is this business an advertiser with us?
"""
isAdvertiser: Boolean
"""
How many times have users clicked this business's advertisement
"""
clicks: Number
"""
Amount of estimated revenue the business has earned from a campaign
"""
revenueFromCampaign: Number
"""
Search keywords that we should ads for this business on
"""
keywords: [String]
}
extend type Business {
"""
Information related to our Business Advertising product
"""
advertising: BusinessAdvertising
}
åãããã«å€§ãããªããšãããã¯æéãšãšãã«æŽã«çŽ°ããåå²ãããå¯èœæ§ããããŸãïŒãããŠããããã¹ãã§ãïŒïŒ
å è¡æè¡
- Group closely-related fields together into subobjects
- GraphQL Schema Design: Building Evolvable Schemas
説æã«ã¯äžéåŒçšç¬Š(""")ã䜿çšãã
ãã£ãŒã«ãšã«èª¬æãè¿œå ãããšãã¯ãäžéåŒçšç¬Š("""
)ã䜿çšããŠãã ããã #
ã䜿çšããªãã§ãã ããã
Why?
- GraphQLã«ã³ã¡ã³ããè¿œå ããã«ã¯ãåŒçšç¬ŠïŒ
"""like this"""
ïŒãšããã·ã¥ã¿ã°ïŒ# like this
ïŒã®2ã€ã®æ¹æ³ããããŸãããã ããæ§æçã«ã¯ç°ãªããŸãã -
"""this is a description"""
ã¯èª¬æã§ããããã£ãŒã«ããšåãæç« åããããã«äœ¿çšããå¿ èŠããããŸãã -
# this is a comment
ã¯Parserã«ãã£ãŠã¯ç¡èŠããããããã¹ããŒãã®ããã¥ã¡ã³ãã«ã¯äœ¿çšããªãã§ãã ããã
Example
ãã¡ããã
extend type Business {
# The name of the business (e.g. "The French Laundry")
name: String
"The rating of the business"
rating: Float
}
ãã¡ãã奜ãŸãã
extend type Business {
"""
The name of the business (e.g. "The French Laundry")
"""
name: String
"""
The rating of the business
"""
rating: Float
}
ãã£ãŒã«ãã®èª¬æã¯ã¹ããŒã¹ã空ãã
è€æ°ã®ãã£ãŒã«ããšèª¬æãè¿œå ããå Žåã¯ãã¹ããŒã¹ãéããŠãã ããïŒïŒã€ãŸããç¯ããšã®æ¹è¡ïŒ
Why?
èªã¿ãããããïŒ
Example
ãã¡ããã
type YelpProsEntryPointBanner {
"Yelp Pros logo image url"
logoUrl: String
"Part of the heading for the banner - starting part"
headingStart: String
"Part of the heading for the banner - ending part"
headingEnd: String
"Sub heading of the banner"
subHeading: String
}
ãã¡ãã奜ãŸãã
type YelpProsEntryPointBanner @owners(teams: "services-marketplace") {
"""
Yelp Pros logo image url
"""
logoUrl: String
"""
Part of the heading for the banner - starting part
"""
headingStart: String
"""
Part of the heading for the banner - ending part
"""
headingEnd: String
"""
Sub heading of the banner
"""
subHeading: String
}
ã³ã¡ã³ããšèª¬æã§è¶ æ確ã«ãã
è¿œå ããåããã£ãŒã«ãããã©ã¡ãŒã¿ãŒãªã©ã«ã€ããŠãã§ããã ãå€ãã®ã³ã³ããã¹ããæäŸããŸãã該åœããç®æã®èšèšææ³ãã説æããŸãããã
èããã¹ãããã€ãã®äŸ:
- è¿œå ããããã®ã®æ確ãªèª¬æ
- ããŒã åºæã®é æåãé¿ãã
- æ§ã ãªéžæè¢ããªã«ãè¡šãã®ãåããããã«ãå šãŠã®Enumå€ã«ã€ããŠèª¬æãã
- ããŒã¿ãæŠå¿µãå®çŸ©ãŸãã¯æç« åããããæ£ç¢ºãªãœãŒã¹ãžã®ããŒããªã³ã¯
æ°å ¥ç€Ÿå¡ãschemaãèªãã§ãããšããŠã圌ããæã£ãŠããå¯äžã®ã³ã³ããã¹ãã¯ããªããæžãããã®ã ãã§ããããªãã®ã³ã¡ã³ãã ãã§ã圌ãã¯ãããã䜿çšããæ¹æ³ãç解ããã®ã«ååãªæ å ±ãåŸãããã§ããããïŒ
Why?
äœæããã°ããã®æ°ããã¹ããŒãã䜿çšããå°æ¥ã®ãã¹ãŠã®äººããããªããšåãç¥èãæã£ãŠãããšæã蟌ãŸãªãã§ãã ãããæ°å ¥ç€Ÿå¡ã®ç«å Žã«ç«ã£ãŠãã ãã-ã¹ããŒããäœãè¡šããŠããã®ããç解ããããã䜿çšã§ããããã«ããããã«ãã§ããã ãå€ãã®ã³ã³ããã¹ããå¿ èŠã§ãð
Example
ãã¡ããã
extend type Business {
"""
Return a list of Yelfies, given a yelfieType
"""
getYelfies(
# yelfie type
yelfieType: String!
): [Yelfie]
}
ãã¡ãã奜ãŸãã
extend type Business {
"""
Return a list of Yelfies.
A Yelfie is a user photo taken at a business, with some special filters
applied. See y/yelfies for more info about this feature.
"""
getYelfies(
"""
Provide the type of Yelfie to filter for.
e.g. âsmilingFaceâ, âeatingFoodâ
The yelfieTypes are defined in the yelfie.json config file - see y/yelfie-type-docs
"""
yelfieType: String!
): [Yelfie]
}
è€éãªããžãã¹ãªããžã§ã¯ããã¢ãã«åããå Žåãéåžžã¯ç°¡åãªèŠçŽãšè©³çŽ°ãèŠã€ããããã®ãªã³ã¯ã§ååã§ãã
ããã©ã«ãã§ã¯ãã»ãšãã©ã®ãªããžã§ã¯ããã£ãŒã«ãã«null蚱容åã䜿çšããŸãããå€ãã®äŸå€ããããŸã
詳现ãªæšå¥šäºé
ã«ã€ããŠã¯ãNullabilityãåç
§ããŠãã ããã
Discussion