ãã¯ã©ã¯äºæ¥é¨ã®APIãã¼ã ã§ã½ããã¦ã§ã¢ã¨ã³ã¸ãã¢ããã¦ãã @anashi ã§ãã
ç§ãã¡ã®ãã¼ã ã¯ããã¯ã©ã¯ã¨å¤é¨ã·ã¹ãã ã¨ã®é£æºãå¯è½ã«ããããã®REST APIãéçºã»æä¾ãã¦ãã¾ãã
ãã®APIã使ãã°ãä¾ãã°ä¼è¨ã·ã¹ãã ãERPãZapierã®ãããªiPaaSãå種ãã¡ã¤ã«ã¹ãã¬ã¼ã¸ãªã©ãã客æ§ãå©ç¨ããã¦ããæ§ã ãªã·ã¹ãã ã¨ãã¯ã©ã¯ã飿ºãããããçµç¹ã«æé©åãããæ¥åããã¼ããã¶ã¤ã³ãããã¨ãå¯è½ã«ãªãã¾ãï¼å ·ä½çãªé£æºã¤ã¡ã¼ã¸ã«èå³ãããæ¹ã¯ããã²ä»¥ä¸ã®è¨äºãã覧ãã ããï¼ï¼ã
ãã¦ããã¯ã©ã¯ã§REST APIãæä¾ããã®ã¯ä»åãåãã¦ã§ã¯ããã¾ããã以åã«ãããã¼ããã¼æ§åãã«REST APIãæ§ç¯ããçµé¨ãããã¾ãã
LayerXã«ã¯ãBe Animalãããæè¡ãã¾ã試ããã¨ããè¡åæéã»æåããããããã¯æ¥ã éçºã«ç¨ããæè¡ã®é¸å®ã«ããã¦ãåæ§ã§ããéå»ã®çµé¨ããå¦ã³ã¤ã¤ããä»åã®å¤é¨ã·ã¹ãã 飿ºç¨APIã®è¦ä»¶ã«ç §ããåãããç§ãã¡ã¯æ¹ãã¦æé©ãªæè¡ã¹ã¿ãã¯ãæ¤è¨ã»é¸æãã¾ããã
ãã®è¨äºã§ã¯ããã®çµæã¨ãã¦æ§ç¯ãããæ°ããããã¯ã©ã¯å¤é¨ã·ã¹ãã 飿ºç¨REST APIãããã©ã®ãããªæè¡çãªå·¥å¤«ã®ä¸ã«æãç«ã£ã¦ããã®ããããã¦ãã®é¸æãã©ã®ãããªã¡ãªãããããããã¦ããã®ãããç´¹ä»ãã¾ãã
ç¹ã«ãå é¨API Gatewayã§ãããçµ±åGraphQL Gatewayãã¨ããããå¤é¨ã«å ¬éããããã®ãæ°ããREST APIåºç¤ãã®çµã¿åããã«ç¦ç¹ãå½ã¦ã¦ããã¾ãã
ãããã®æ§æã¯ããããç§ããã¼ã ã«åå ããã¨ãã«ã¯æ¢ã«æ§ç¯ããã¦ãã¾ãããæè¡é¸å®ã«é¢ããæææ±ºå®ã®çµç·¯ãèæ¯ã«ã¤ãã¦ã¯ã社å ã«èç©ããã¦ããArchitecture Decision Record (ADR) ãéãã¦å¾ããã§ã詳ããç¥ããã¨ãã§ããã®ã§ããã®æ å ±ãªã©ãåèã«ããªããè¨ãã¦ããããã¨æãã¾ãã
çµ±åGraphQL Gateway
ã¾ããç§ãã¡ã®REST APIãå é¨çã«ã©ã®ããã«ãã¼ã¿ãåå¾ã»æä½ãã¦ããããããã¯ãçµ±å GraphQL Gatewayããéãã¦è¡ããã¾ãã
ãã¯ã©ã¯ã¯è¤æ°ã®ãããã¯ãï¼ãµã¼ãã¹ï¼ããæãç«ã£ã¦ãã¾ããå½åã¯åãµã¼ãã¹ãWebã¢ããªåãã®APIãæã£ã¦ãã¾ãããããµã¼ãã¹ãå¢ããã«ã¤ãã¦èªç¥è² è·ãå¢å¤§ãããµã¼ãã¹éã®é£æºãè¤éåãã¦ãã¾ããã

ãã®èª²é¡ã解決ããããã«å°å ¥ãããã®ããçµ±åGraphQL Gatewayãã§ããããã¯ãå ¨ã¦ã®ããã¯ã¨ã³ããµã¼ãã¹ã¸ã®ã¢ã¯ã»ã¹ãéç´ããåä¸ã®GraphQLã¨ã³ããã¤ã³ããæä¾ãããã®ã§ããGatewayã¨åãµã¼ãã¹éã¯gRPC (Connect)ã§éä¿¡ãã¦ãã¾ãã

ãã®ã¢ã¼ããã¯ãã£ã«ã¯ã以ä¸ã®ãããªã¡ãªãããããã¾ãã
- ãµã¼ãã¹éã®ä¾åé¢ä¿è§£æ±ºã®å®¹æã
- GraphQLã®Model Field Resolverãæ´»ç¨ãããã¨ã§ãä¾ãã°ã帳票ã¨ãã®ä½æã¦ã¼ã¶ã¼æ å ±ãã®ããã«ãç°ãªããµã¼ãã¹ã«åå¨ãããã¼ã¿éã®ä¾åé¢ä¿ãGateway層ã§ã¹ãã¼ãã«è§£æ±ºã§ãã¾ã
- N+1åé¡ã®æ¨æºçãªè§£æ±º
- ãªã½ã¼ã¹éã®ä¾åé¢ä¿ã解決ããéã«çºçããã¡ãªN+1åé¡ã«å¯¾ãã¦ããDataLoaderã¨ããGraphQLã§åºã使ããã¦ãããã¿ã¼ã³ã§å¯¾å¿ã§ãã¾ã
- åå©ç¨æ§
- ãã®Gatewayã¯ãä»åã®REST APIã ãã§ãªãããã¯ã©ã¯ã®Webã¢ããªãã¹ããã¢ããªãªã©ã社å ã®æ§ã ãªã¯ã©ã¤ã¢ã³ããããå©ç¨ãããå ±éåºç¤ã§ããä¸åº¦Gatewayã«æ©è½ã追å ããã°ãå¤ãã®ã¢ããªã±ã¼ã·ã§ã³ã§ãã®æ©æµãåãããã¾ã
ç§ãã¡ã®æ°ããREST APIåºç¤ã¯ããã®çµ±åGraphQL Gatewayãå é¨çã«å©ç¨ãããã¨ã§ãä¸è¨ã®ãããªã¡ãªããã享åãã¦ãã¾ãã
Protobufã¹ãã¼ãã¨GraphQLã¹ãã¼ãã®äºé管çåé¡
ããã§ããããã¯ã¨ã³ãã¯gRPC/Protobufãªã®ã«ãGatewayã¯GraphQLãã¹ãã¼ãå®ç¾©ãäºéã«ç®¡çããå¿ è¦ããã£ã¦å¤§å¤ãããªãï¼ãã¨çåã«æãããããããã¾ããã
ããã¯å½å大ããªèª²é¡ã§ãããããããã®èª²é¡ã解決ããããã«ã @izumin ãéçºããprotoc-gen-pothosã¨ãããã¼ã«ãæ´»ç¨ãã¦ãã¾ããããã¯ãProtobufã®å®ç¾©ãã¡ã¤ã«ãããGraphQLã¹ãã¼ãå®è£ ã©ã¤ãã©ãªã§ããPothos GraphQLã§å©ç¨å¯è½ãªTypeScriptã®å®ç¾©ãèªåçæãããã®ã§ãã
ããã«ãããã¹ãã¼ãå®ç¾©ã®å¤§å ã¯Protobufã«ä¸æ¬åãããäºé管çã®æéã¨é½é½¬ã®ãªã¹ã¯ãè§£æ¶ããã¾ããã
æ°REST APIåºç¤: tsoa + GraphQL Codegen
ãã¦ãå é¨ã«å¼·åãªçµ±åGraphQL Gatewayãããã¨ãã¦ããããã©ã®ããã«ãã¦å¤é¨åãã®REST APIã¨ãã¦å ¬éãã¦ããã®ã§ããããï¼
ããã§ãç§ãã¡ã¯ãéå»ã®çµé¨ãè¸ã¾ããæ¹ãã¦æè¡é¸å®ãè¡ãã¾ãããéè¦ããã®ã¯ãAPIå©ç¨è ã®å©ä¾¿æ§ãé«ããOpenAPI仿§ã¸ã®æºæ ããã³Specã®èªåçæã¨ãéçºã®æè»æ§ã»å¹çæ§ã§ãã
以åã®åºç¤ï¼GraphQL Sofaãå©ç¨ï¼ã§äº«åã§ãã¦ãã主ãªã¡ãªããã¯ä»¥ä¸ã§ãã
- GraphQLã¹ãã¼ããå ã«ãOpenAPI仿§ã«æºæ ããããã¥ã¡ã³ããèªåçæã§ãã
- GraphQLã¹ãã¼ããã容æã«REST APIã®ã¤ã³ã¿ã¼ãã§ã¼ã¹ãæ§ç¯ã§ãã
ä»åã®æ°ããåºç¤ã§ã¯ãtsoaã¨ããOpenAPIæºæ ã®ãã¬ã¼ã ã¯ã¼ã¯ã¨graphql-codegenãçµã¿åããããã¨ã§ã以ä¸ã®ã¡ãªããã享åã§ããããã«ãªãã¾ããã
- GraphQLã¹ãã¼ãããã®åé¢ã«ãããããé«ãèªç±åº¦ã¨æè»æ§
- REST APIåºæã®ã¬ã¹ãã³ã¹å½¢å¼ã¸ã®æ´å½¢ããããç²¾å¯ãªãªã¯ã¨ã¹ã/ã¬ã¹ãã³ã¹ã®ããªãã¼ã·ã§ã³ã«ã¼ã«ãªã©ããGraphQLã¹ãã¼ãã«å½±é¿ãããã«å®è£ å¯è½
- tsoaã§ã¢ããã¼ã·ã§ã³ã使ããOpenAPI仿§ãç´°ããå¶å¾¡å¯è½
- å
é¨GraphQLåºç¤ã¨ã®å¹ççãã¤åå®å
¨ãªé£æº
- graphql-codegenãç¨ãã¦çµ±åGraphQL Gatewayã®ã¹ãã¼ãããçæããTypeScriptã®åå®ç¾©ããtsoaã®ã³ã³ããã¼ã©ã¼ã®å®è£ ã§ãã®ã¾ã¾åå©ç¨å¯è½
- ããã«ããåã®æ´åæ§ãä¿ã¡ãªãããå¹ççã«REST APIã¬ã¤ã¤ã¼ã®éçºãé²ãããã¨ãå¯è½
ãããã«ãã£ã¦å é¨ã®GraphQL Gatewayã®æ©æµãåãã¤ã¤ãå¤é¨ã«ã¯æ¨æºçã§æè»æ§ã®é«ãREST APIãæä¾ããã¨ãããã¨ãå¯è½ã«ãªã£ã¦ãã¾ãã
ãããã«
ãã®è¨äºã§ã¯ããã¯ã©ã¯ã®æ°ããå¤é¨ã·ã¹ãã 飿ºç¨REST APIãæ¯ããæè¡ã¹ã¿ãã¯ã«ã¤ãã¦ãå ·ä½çãªæè¡é¸å®ã¨ãã®ã¡ãªãããããç´¹ä»ãã¾ããã
å é¨çã«ã¯ãçµ±åGraphQL Gatewayããå ±éåºç¤ã¨ããprotoc-gen-pothosã«ããProtobufããã®ã³ã¼ãçæã«ãã£ã¦ããµã¼ãã¹éã®é£æºãã¹ãã¼ãã®äºé管çãªã©ã®èª²é¡ã«å¯¾å¿ãã¦ãã¾ãã
æ°REST APIåºç¤ã¨ãã¦ã¯ãtsoa + graphql-codegenã ãæ¡ç¨ãããã¨ã§ãOpenAPIã¸ã®æºæ ããã³Specèªåçæã«ããAPIã®ä½¿ããããã¨ãå é¨ã®GraphQLã¹ãã¼ãããé©åº¦ã«åé¢ããããã¨ã«ããå®è£ ã®æè»æ§ã両ç«ããã¾ããã
ç§ãã¡ã¯ããããããéçºè ä½é¨ãé«ãããã便å©ã§å¼·åãªAPIãæä¾ã§ãããããæè¡çãªææ¦ãç¶ãã¦ããã¾ãããã®è¨äºããLayerXã®æè¡ãæåã«èå³ãæã¤æ¹ã ã®åèã«ãªãã¨å¬ããã§ãã
ãã¯ã©ã¯ã§åããã¨ã«èå³ã®ããæ¹ã¯ããã²ä»¥ä¸ãããå¿åãã ããï¼