7

API を拡張して GraphQL エンドポイントを含めようとしているときに、問題が発生しました。私が取り組んでいるアプリケーションは、Messages. メッセージには、タイプのコメントを含めることができますMessage。メッセージがコメントの場合、 type の親がありMessageます。単純化すると、スキーマは次のようになります。

type Message {
  id: String
  content: String
  comments: [Message]
  parent: Message
}

type RootQuery {
  message(id: String): Message
  messages: [Message]
}

このスキーマの問題は、次のようなクエリが許可されることです。

{
  messages {
    comments {
      parent {
        comments {
          parent {
            comments {
              parent {
                id
                content       
              }
            }       
          }
        }   
      }
    }
  }
}

コメントの任意の深いネストを許可したい場合があることに注意してください。その場合、次のクエリを許可する必要があります。

{
  messages {
    comments {
      comments {
        comments {
          id
          content
        }
      }
    }
  }
}

そこで、私の質問は次のとおりです。新しいタイプ (コメント) を、その親がわからない API に導入する必要がありますか? または、この種の望ましくない動作を制限する他の方法はありますか?

また、コメントタイプを使用するfragment messageFields on Messageと、クエリで構文を使用できなくなりますか? おそらく、今こそスキーマにインターフェースを導入する時ではないでしょうか?

タイプ コメントを導入した場合の解決策の提案 (私はこれを試していません):

interface Message {
  id: String
  content: String
  comments: [Message]
}

type DefaultMessage : Message {
  id: String
  content: String
  comments: [Comment]
  parent: Message
}

type Comment : Message {
  id: String
  content: String
  comments: [Message]
}

type RootQuery {
  message(id: String): Message
  messages: [Message]
}
4

3 に答える 3

4

他の誰かがここで、graphql-js で再帰型を行う方法を知りたがっている場合に備えて、graphql-js のコードに役立つヒントがあります。

 * When two types need to refer to each other, or a type needs to refer to
 * itself in a field, you can use a function expression (aka a closure or a
 * thunk) to supply the fields lazily.
 *
 * Example:
 *
 *     var PersonType = new GraphQLObjectType({
 *       name: 'Person',
 *       fields: () => ({
 *         name: { type: GraphQLString },
 *         bestFriend: { type: PersonType },
 *       })
 *     });
 *
 */

https://github.com/graphql/graphql-js/blob/master/src/type/definition.js#L274

于 2015-11-26T03:13:07.447 に答える
0

たとえば、ユーザーがコメントを投稿するときに最大のネストの深さを制限するために、データ構造のdepth属性があるとします。Comment

問題を次のように解決できるようにするresolverには、comments属性の で をチェックし、が不正になっているdepth場合は何も返さず、そうでない場合はコメントを取得して返します。depth

于 2015-09-10T09:35:05.247 に答える
0

メッセージがコメントの場合、Message 型の親があります。

フィールドはではなくparentの下にある必要があるようです。それでもクエリを防ぐことはできませんが、DDOS の理由でこれについて心配している場合は、REST API を使用しても計算が難しい他の多くの種類のリクエストがあり、そのような攻撃を検出するための他の手段が必要です。 .type CommentDefaultMessageparent - comments - parent

再帰ノード

ただし、ネストされたコメントで非常に興味深い質問をします。commentネストされたすべての応答を取得するには、クエリで を何回ネストする必要があるかをどうやって知ることができますか? 現在、GraphQL で再帰オブジェクトを指定することはできないと思います。

おそらく、最後のコメントから始めて、ネストされた各コメントを1つずつ(または一度にXレベルずつ)フェッチすることで、この制限を回避しますnode

{
  messages {
    comments {
      id
      content
    }
  }
}

に続く

{
  node(commendId) {
    comment {
      id
      content
    }
  }
}
于 2015-09-10T09:03:30.537 に答える