Polymer + Apolloのクラむアントを䜿甚しおYii2のGraphQL APIサヌバヌを䜜成しおいたす。 パヌト4.怜蚌。 結論

パヌト1.サヌバヌ
パヌト2.クラむアント
パヌト3.突然倉異
パヌト4.怜蚌。 結論


怜蚌ずUnionType


私が盎面しなければならなかった興味深いタスクの1぀は、デヌタを倉曎するずきのサヌバヌ怜蚌でした。 オブゞェクトの倉曎時に゚ラヌが発生した堎合はどうなりたすか 蚘事では、この問題の倚くの解決策を芋぀けるこずができたすが、耇合型のUnionタむプを䜿甚するこずにしたした。 簡単に蚀えば、Unionずは、resolveの実行結果に応じお、リク゚ストの結果が1぀のタむプだけでなく、異なる堎合もあるずいうこずです。


さあ始めたしょう


たずえば、ナヌザヌオブゞェクトにメヌルフィヌルドを远加し パヌト1.サヌバヌを参照、誀ったアドレスでオブゞェクトを保存できないようにしたす。


 蚘事の完成したプロゞェクトはgithubからダりンロヌドできたす 


手順1.デヌタベヌスにフィヌルドを远加する


パヌト1からサヌバヌに戻り、ナヌザヌにメヌルフィヌルドを远加したしょう。 デヌタベヌスにフィヌルドを远加するには、移行を䜜成したす。


$> yii migrate/create add_email_to_user 

それを開いお、safeUpメ゜ッドを倉曎したす。


  public function safeUp() { $this->addColumn('user', 'email', $this->string()); } 

保存しお実行


 $> yii migrate 

手順2.ルヌルをナヌザヌオブゞェクトに远加する


Yiiで怜蚌を実装する唯䞀の正しい方法は、Model :: rulesメ゜ッドをオヌバヌラむドするこずです。 このメカニズムは、任意にカスタマむズされた怜蚌の可胜な限り広範な実装を提䟛し、すべおの機胜に詳现なドキュメントが添付されおいたす。 それを回避する䟡倀があるのは、ごくたれな堎合のみで、99でフレヌムワヌクツヌルを䜿甚しおすべおを実行できたす。


/models/User.php


 ... /** * @inheritdoc */ public function rules() { return [ [['id', 'email'], 'required'], [['id', 'status'], 'integer'], [['createDate', 'modityDate', 'lastVisitDate'], 'safe'], [['firstname', 'lastname', 'email'], 'string', 'max' => 45], ['email', 'email'], ]; } ... 

したがっお、rulesメ゜ッドに3぀のルヌルを远加したした。


  1. フィヌルドを空にするこずはできたせん。
  2. フィヌルドは文字列でなければなりたせん。
  3. フィヌルドには有効な電子メヌルが含たれおいる必芁がありたす。

ステップ3. GraphQLタむプを曎新する


スキヌマ/ UserType.phpでは、倉曎は最小限です。


 ... 'email' => [ 'type' => Type::string(), ], ... 

しかし、突然倉異では、楜しみが始たりたす。


ステップ4. ValidationErrorTypeを远加する


Yiiフレヌムワヌクに慣れおいない堎合、フィヌルドが怜蚌されなかったためにオブゞェクトが保存されなかった堎合、$ object-> getErrorsメ゜ッドを䜿甚しおすべおの゚ラヌを取埗できるこずを明確にしたす。 


 [ '' => [ '  ', '  ', ... ], ... ] 

この圢匏は非垞に䟿利ですが、GraphQLには適しおいたせん。 事実、連想配列はオブゞェクトのフィヌルドずなるオブゞェクトに倉換されるため、JSONで盎接吐き出すこずはできず、各オブゞェクトには独自の属性がありたす。 そしおご存じのように、GraphQLは予枬可胜な結果でのみ機胜したす。 あるいは、もちろん、UserValidationErrorのようなオブゞェクトごずに個別のタむプを䜜成できたす。このタむプでは、すべおのフィヌルドがオブゞェクト自䜓のフィヌルドず䞀臎し、Type :: listOfType :: stringを含みたす。 しかし、非垞に倚くのタむプの手動䜜成はあたりにも最適ではないようでした。


ナニバヌサルスキヌマ/ ValidationErrorType構造を持぀単䞀のクラスを远加したす。


 <?php namespace app\schema; use GraphQL\Type\Definition\ObjectType; use GraphQL\Type\Definition\Type; class ValidationErrorType extends ObjectType { public function __construct() { $config = [ 'fields' => function() { return [ 'field' => Type::string(), 'messages' => Type::listOf(Type::string()), ]; }, ]; parent::__construct($config); } } 

このタむプには、1぀のフィヌルドの怜蚌゚ラヌ情報が含たれたす。 私の堎合、ValidationErrorTypeタむプのフィヌルドは明らかであり、゚ラヌが発生したフィヌルドの名前ず、゚ラヌを含むメッセヌゞのリストが含たれおいたす。 すべおが非垞に簡単です。


1぀だけでなく、すべおのフィヌルドを怜蚌した結果を返す必芁があるため、別のタむプを䜜成したすschema / ValidationErrorsListType


 <?php namespace app\schema; use GraphQL\Type\Definition\ObjectType; use GraphQL\Type\Definition\Type; class ValidationErrorsListType extends ObjectType { public function __construct() { $config = [ 'fields' => function() { return [ 'errors' => Type::listOf(Types::validationError()), ]; }, ]; parent::__construct($config); } } 

ステップ5. UnionTypeを生成する


GraphQLにはUnion型がありたす。これは、resolveフィヌルドの結果が1぀の型だけでなく、いく぀かの型の1぀を返す堎合ですすでに曞いたようですが、ここでもう䞀床蚀及する䟡倀がありたした。 したがっお、私たちの目暙は、オブゞェクトの倉曎/䜜成を倉曎せずに怜蚌に合栌するか、その逆の堎合、怜蚌に成功するず、倉曎されたオブゞェクト自䜓たたはValidationErrorsListType型のオブゞェクトを返すこずです。


䞖代ずはどういう意味ですか 事実、戻りのUnionTypeを各突然倉異に察しお䜜成するのではなく、基本型に基づいおその堎で生成したす。 どのように正確に、今私は衚瀺したす。


スキヌマ/ Types.phpを倉曎したす。


 ... use GraphQL\Type\Definition\UnionType; use yii\base\Model; ... private static $validationError; private static $validationErrorsList; //       private static $valitationTypes; ... // c     public static function validationError() { return self::$validationError ?: (self::$validationError = new ValidationErrorType()); } public static function validationErrorsList() { return self::$validationErrorsList ?: (self::$validationErrorsList = new ValidationErrorsListType()); } //     ,   // ,     public static function validationErrorsUnionType(ObjectType $type) { // -     ,   //    ,    // (     ,  / //    GraphQL   ) if (!isset(self::$valitationTypes[$type->name . 'ValidationErrorsType'])) { // self::$valitationTypes    ,    self::$valitationTypes[$type->name . 'ValidationErrorsType'] = new UnionType([ //    'name' => $type->name . 'ValidationErrorsType', //      // (    ,      //     ) 'types' => [ $type, Types::validationErrorsList(), ], //    resolveType //       // / , //     //     $model->getError() //      'resolveType' => function ($value) use ($type) { if ($value instanceof Model) { //   return $type; } else { //   (    , //     , //   ) return Types::validationErrorsList(); } } ]); } return self::$valitationTypes[$type->name . 'ValidationErrorsType']; } ... 

ステップ6.突然倉異


UserMutationTypeに倉曎を加えたす。


 ... use app\schema\Types; ... //     update 'type' => Types::validationErrorsUnionType(Types::user()), ... //     'email' => Type::string(), ... 'resolve' => function(User $user, $args) { //      , // ..      : //     ,     //     ,   $user->setAttributes($args); if ($user->save()) { return $user; } else { //  ,      - // ,     //    foreach ($user->getErrors() as $field => $messages) { //   ValidationErrorType $errors[] = [ 'field' => $field, 'messages' => $messages, ]; } //    //    //   (   ValidationErrorsListType) return ['errors' => $errors]; } } ... 

それがどのように機胜するかを芋る時間です。


テスト䞭


GraphiQLを再床開き、最も簡単なこずを詊しおください。


入力フィヌルドでCtrl +スペヌスをクリックしお、曎新メ゜ッドが返す内容を確認したす。


画像


すごい。


さお、私たちは䜕が必芁なのかを尋ねようずしおいるので、䜕が起こるか芋おいきたす。


画像


ご芧のずおり、最初のルヌルが機胜したした。これは、フィヌルドが必須であるこずを瀺しおいたす。


画像


ルヌル2-実際には、メヌルフィヌルドはそのようなものでなければなりたせん。 怜蚌は機胜したした。


さお、最埌に成功した結果を芋おみたしょう


画像


䞀般に、説明されおいる怜蚌のアプロヌチは、唯䞀の最適で䞍完党なものではなく、特定のニヌズに合わせお改善および改善できるず確信しおいたすが、䞀般的には非垞に普遍的であり、実際に誰かが助けお問題の解決策を芋぀けられるこずを願っおいたす問題。


結論


結論を導き出しおいるものを正確に理解するには、4぀のパヌトすべおを読むこずをお勧めしたす。


GraphQLを䜿甚する必芁があるのはい぀ですか


たあ、たず、ゲヌムがろうそくに倀するかどうかを理解する必芁がありたす。 もちろん、いく぀かの簡単なメ゜ッドを䜜成するタスクがある堎合は、GraphQLは必芁ありたせん。 それは顕埮鏡を䜿った䞀皮の釘です。 私芋、GraphQLの䞻な利点の1぀は、スケヌリングの利䟿性です。 そしお、スケヌリングする胜力が必芁です ほが どのプロゞェクトでもさらに、䞀芋したずころたったく必芁のないプロゞェクトでも。


APIが「平均」である堎合、原則ずしお、遞択したプロトコルの違いを感じるこずはありたせん。 GraphQLの突然倉異はRESTaのアクションビヌルの䞋で働いおから1〜2時間埌、およびop-既にRESTful APIサヌバヌを持っおいたす。


だから...


゚ントリのしきい倀が非垞に䜎い。 GraphQLク゚リ蚀語の本質を理解し、あらゆる蚀語のバック゚ンドずフロント゚ンドに必芁なラむブラリを芋぀け、それらがどのように機胜するかを理解したす。これには1日たたは数時間しかかかりたせん。


新しいもの。 新しい経隓は垞に有甚ですマむナスであっおも。 ご存知のように、Webテクノロゞヌの分野では、新しいものをバむパスしお、私たちは劣化しおいるこずが知られおいたす。


倖郚倖郚APIの䜿甚法。 最終補品が、倚数のクラむアントが䜿甚するAPI䜕も知らないである堎合、GraphQLは非垞に柔軟性がありたす。これらのクラむアントはたったく異なるニヌズを持぀こずができるからです。 しかし、これは䞡刃の剣です。 技術的には、これは利点ですが、残念なこずに、クラむアントは䜕か新しいこずを孊ばなければならず、GraphQL APIの経隓を持぀開発者を探す必芁があるずいう事実によっお、クラむアントを抌しのけるこずができたす。 GraphQLの堎合、これらの甚語は実際には非垞に短い堎合があるずいう事実にもかかわらず。


GraphQLは、リモヌト䜜業の堎合にも圹立ちたす。その結果、バック゚ンド開発者ずフロント゚ンド開発者の間の密接なコミュニケヌションの欠劂毎日のスカむプ呌び出しが垞に「密接な」コミュニケヌションを保蚌するずは限りたせん。


欠点のうち、GraphQL + PHPのネットワヌク䞊のいく぀かの䟋を挙げたいず思いたす。なぜなら、真のsmushyチャンクはNode.jsたたはGoのいずれかを䜿甚するためですこのシリヌズの蚘事を曞くよう促されたした。 Apolloラむブラリず同じ状況で、公匏ドキュメントはすべおReactで曞かれおおり、私はバック゚ンド開発者ずしお、これがPolymerでどのように機胜するかを理解するのに時間を費やす必芁がありたしたが、移行䞭に倧きな問題ずは蚀いたせんでした。 ずころで、 Mediumの非垞に有益なApolloブログを読むこずをお勧めしたす。 GraphQLに関する興味深い実甚的な蚘事が本圓にたくさんありたす。


たた、短所の1぀は、SwaggerやApiDoc.jsのような䟿利なドキュメントゞェネレヌタヌがないこずです。 私はただ1台の発電機を芋぀けるこずができたしたが、残念ながら、それは非垞に悲惚です。 PDFの説明よりも高床なドキュメントの経隓がある堎合は、コメントで共有しおください。


有名䌁業のGraphQLを既に䜿甚しおいるのは誰ですか


Github 䞀般に、サむトの察象読者は開発者であり、APIを䜿甚できるかどうかに぀いお心配するこずはないため、驚くべきこずは䜕もありたせん。 ドキュメントは非垞に矎しく思慮深く、泚目に倀したす。GraphQLの基本、デバッグ方法、RESTからの移行に関するガむドに関する情報が少し含たれおいたす。


フェむスブック GraphQL自䜓のコンセプトの開発者であり、積極的に掚進しおいたす。 FacebookはGraphQLをどのように䜿甚しおいるかに぀いお、ネットワヌクに関する倚くのレポヌトがありたす。


PS友達 APIでOPTIONSメ゜ッドを䜿甚しおリク゚スト凊理を実装するこずを忘れないでください。これにより、サヌバヌは、そのようなすべおのリク゚ストに察しお垞に200のHTTPコヌドず空のボディを返したす。 これはあなたの神経现胞を救いたす。


䞀般に、APIを開発するずきはCORSのヘッダヌを忘れないでください


 <IfModule mod_headers.c> Header add Access-Control-Allow-Origin "*" Header add Access-Control-Allow-Headers "Content-Type, Authorization" Header add Access-Control-Allow-Methods "GET, POST, OPTIONS" </IfModule> 


Source: https://habr.com/ru/post/J337236/


All Articles