2015-10-28 14 views
43

Tôi bắt đầu với relay-starter-kit và cũng đã làm việc theo cách của tôi thông qua tài liệu Relay và GraphQL. Nhưng có một vài khu vực không giải thích được và bí ẩn.Trong Relay, giao diện nút và thông số ID toàn cầu đóng vai trò gì?

Nghiêm túc tôi đọc rất nhiều tài liệu ở khắp mọi nơi về tất cả những điều này, nhưng không thể tìm thấy bất kỳ lời giải thích thỏa mãn cho các câu hỏi sau:

đây là cái gì? Tôi đặt đăng nhập nhưng nó không bao giờ thậm chí được gọi tại tất cả:

var {nodeInterface, nodeField} = nodeDefinitions(
    (globalId) => { 
    var {type, id} = fromGlobalId(globalId); 
    if (type === 'User') { 
     return getUser(id); 
    } else if (type === 'Widget') { 
     return getWidget(id); 
    } else { 
     return null; 
    } 
    }, 
    (obj) => { 
    if (obj instanceof User) { 
     return userType; 
    } else if (obj instanceof Widget) { 
     return widgetType; 
    } else { 
     return null; 
    } 
    } 
); 

Và hiệu quả thực tế của việc này là gì:

interfaces: [nodeInterface], 

lẽ liên quan đến đó, những gì hiện các lĩnh vực node đây làm:

var queryType = new GraphQLObjectType({ 
    name: 'Query', 
    fields:() => ({ 
    node: nodeField, 
    // Add your own root fields here 
    viewer: { 
     type: userType, 
     resolve:() => getViewer(), 
    }, 
    }), 
}); 

Và phép thuật xung quanh trường id là gì? globalIdField là gì?

Tôi có một id trong cơ sở dữ liệu của tôi và nghĩ rằng tôi có thể sử dụng nó trong các đối tượng GraphQL tôi:

Thay vì:

id: globalIdField('User'), 

Tôi muốn sử dụng id cơ sở dữ liệu của tôi:

id: { 
    type: GraphQLID, 
    description: 'The identifier' 
}, 

Nhưng nếu tôi làm như vậy, tôi gặp lỗi trong trình duyệt nói rằng RelayQueryWriter: Could not find a type name for record '1'.

Tôi có thể loại bỏ lỗi đó bằng cách thêm __typename vào bộ chứa thành phần của tôi Truy vấn chuyển tiếp nhưng dường như tất cả đều sai.

Thật tuyệt vời nếu bạn có thể đưa ra một số nội dung sâu hơn và giải thích rõ hơn ở đây và nâng cao tài liệu chính thức.

Cảm ơn bạn

Trả lời

51

Trường Node gốc, kết hợp với ID duy nhất toàn cầu, đi vào chơi khi Rơ le cần tìm nạp lại một đối tượng. Nạp lại xảy ra khi bạn gọi this.props.relay.forceFetch() hoặc khi bạn thêm trường vào truy vấn cho đối tượng có ID chung được biết vì nó đã được tìm nạp một phần.

Trong trường hợp như vậy, Rơ le sẽ làm ngắn mạch truy vấn thông thường và thực hiện truy vấn trực tiếp bằng (các) đối tượng sử dụng ID toàn cầu và cuộc gọi gốc node.

Ví dụ:

Giả sử rằng $showCommentsfalse khi truy vấn này lần đầu tiên được giải quyết.

query { 
    viewer { 
    stories(first: 10) { 
     edges { 
     node { 
      id, 
      comments(first: 10) @include(if: $showComments) { 
      author, 
      commentText 
      } 
      text, 
     } 
     } 
    } 
    } 
} 

này sẽ đã gây ra một lấy cho idtext đối với một số số câu chuyện, mà ID hiện đang được biết đến.

Hãy tưởng tượng rằng tại một số thời điểm trong tương lai, biến số $showComments đã trở thành true. Relay sẽ chỉ lấy lại dữ liệu cần thiết bằng trường gốc node.

query { 
    node(id: "ABC123") { 
    fragment on Story { comments(first: 10) { author, commentText } } 
    } 
    node(id: "DEF456") { 
    fragment on Story { comments(first: 10) { author, commentText } } 
    } 
    node(id: "GHI789") { 
    fragment on Story { comments(first: 10) { author, commentText } } 
    } 
    ... 
} 

này phụ thuộc vào một vài mẩu:

  1. Mỗi đối tượng phải có một ID duy nhất trên toàn cầu, hoặc được xác định bởi một cặp loại/ID (các globalIdField helper thực hiện điều này và tạo ra một chuỗi mã hóa base64).
  2. Máy chủ phải biết cách giải quyết một đối tượng từ một ID duy nhất trên toàn cầu và ngược lại. Đây là những gì mà nodeDefinitions dành cho.
  3. Bất kỳ đối tượng nào hy vọng có thể lấy lại được bằng cách sử dụng hệ thống này phải triển khai nodeInterface.

Xem thêm: https://facebook.github.io/relay/docs/graphql-object-identification.html#content

+2

Hy vọng rằng điều này sẽ làm theo cách của mình vào các hướng dẫn sớm. Tôi cũng bị bối rối bởi điều này trong một thời gian cho đến khi tôi cuối cùng đã làm việc thông qua tất cả mọi thứ và đặt các mảnh lại với nhau. –

+3

Có thể thêm một chút nữa vào câu trả lời này liên quan đến 'fromGlobalId' và' toGlobalId'? và cách chúng tạo điều kiện thuận lợi cho việc tìm nạp lại bất kỳ loại đối tượng nào? Đọc https://github.com/graphql/graphql-relay-js/blob/master/src/node/node.js và các tệp khác trong repo đó đã giúp tôi rất nhiều, nhưng việc chưng cất nội dung đó thành các từ sẽ giúp tôi tiết kiệm rất nhiều thời gian. –

+0

Đối với một ngắn gọn (bạn có thể bỏ qua đến cuối cho bản tóm tắt) & giải thích mã minh họa về những gì nodeInterface bí ẩn, nodeField, globalFieldId, có lẽ https://medium.com/p/relay-graphql-de-mystifying- node-id-38757121b9c – nethsix

Các vấn đề liên quan