Problem/Motivation

Drupal 8 wants to provide a great REST experience out of the box.

Yet /node/1?_format=json only gives you:

{
"status": "2",
"cid": "8",
"last_comment_timestamp": "1454237193",
"last_comment_name": "",
"last_comment_uid": "1",
"comment_count": "6"
}

… that's only one comment ID (cid) there. And it's the one for the last comment. How do you get the five other comments?

Presumably this is because it's not the Node entities that point to Comment entities, it's Comment entities that point to Node entities. Hence it makes sense that a Node entity doesn't list all the Comment entities' IDs. But that makes it not less frustrating for front-end developers, who not necessarily have deep Drupal knowledge.

The answer?

Create a "REST export" view.

That's not an API-first Drupal. This makes it so that you cannot even get such basic content without having deep Drupal knowledge!

Proposed resolution

Provide a "REST export" view at /node/{node}/comments that returns all published comments for that node. Ship this view by default.

Alternative solutions include:

  1. allow referenced entity collections to be embedded in HAL+JSON responses: #2100637: REST views: add special handling for collections
  2. native http://jsonapi.org/support
  3. native http://graphql.org/ support

2 and 3 are not practical. 1 we should work on, but because nodes don't reference comments, it seems implausible that we'd be able to do this, unless we perhaps provide a custom comment field normalizer.

Remaining tasks

  1. Agree on solution.
  2. Build solution.
  3. Review solution.
  4. Commit solution.

User interface changes

None.

API changes

None.

Data model changes

None.

Comments

Wim Leers created an issue. See original summary.

dawehner’s picture

Maybe comment should ship with a view by default?

wim leers’s picture

Maybe comment should ship with a view by default?

From the IS:

Ship this view by default.

So… +1 :)

dawehner’s picture

Oh yeah I was more referring to your choice of using rest module as component.

wim leers’s picture

I'd say this would ship as optional configuration with REST module, no? i.e. core/modules/rest/config/optional/views.view.node_comments_rest.yml

wim leers’s picture

Status: Active » Needs review
StatusFileSize
new6.73 KB

In fact, let's just create a patch.

wim leers’s picture

Component: rest.module » comment.module
StatusFileSize
new6.74 KB
new466 bytes

Oh hm, I see your point. Never mind me.

The last submitted patch, 6: REST_node_comments_view-2662010-6.patch, failed testing.

Status: Needs review » Needs work

The last submitted patch, 7: REST_node_comments_view-2662010-7.patch, failed testing.

dawehner’s picture

Issue tags: +Needs tests
  1. +++ b/core/modules/comment/config/optional/views.view.node_comments_rest.yml
    @@ -0,0 +1,245 @@
    +status: true
    

    I guess we want to disable it by default so sites don't accidentally leak data?

  2. +++ b/core/modules/comment/config/optional/views.view.node_comments_rest.yml
    @@ -0,0 +1,245 @@
    +tag: REST
    

    Nice!

  3. +++ b/core/modules/comment/config/optional/views.view.node_comments_rest.yml
    @@ -0,0 +1,245 @@
    +      access:
    +        type: perm
    +        options:
    +          perm: 'access comments'
    ...
    +        status_node:
    +          value: true
    +          table: node_field_data
    +          field: status
    ...
    +      arguments:
    +        nid:
    +          id: nid
    +          table: node_field_data
    +          field: nid
    +          relationship: node
    

    What kind of access logic do we actually expect? People with access to the parent entity should have access to the individual comments?

  4. +++ b/core/modules/comment/config/optional/views.view.node_comments_rest.yml
    @@ -0,0 +1,245 @@
    +      pager:
    +        type: full
    +        options:
    

    Any reason to use a full pager, not a mini one?

  5. +++ b/core/modules/comment/config/optional/views.view.node_comments_rest.yml
    @@ -0,0 +1,245 @@
    +      row:
    +        type: fields
    +        options:
    

    Really fields? I would just expose the entire comment.

  6. +++ b/core/modules/comment/config/optional/views.view.node_comments_rest.yml
    @@ -0,0 +1,245 @@
    +        node:
    +          id: node
    +          table: comment_field_data
    +          field: node
    

    If you use the entire comment you also don't have issues with not displaying the data for the parent entity. It would be just included all the time.

Crell’s picture

Comments are not unique to nodes anymore, so this should be done in a not-node-specific way. Also, to be properly RESTy we should have a link from the entity to its comment resource. Which means auto-generating the route information using a route provider.

How that fits in with using a View for the data itself... I'm not actually sure off hand. :-/

larowlan’s picture

Title: Impossible to get a node's comments via REST out of the box » Add a derivative view for each comment field providing a REST export of comments for host entities
Category: Task » Feature request
Priority: Major » Normal
larowlan’s picture

There is the possibility of multiple comment threads too, so lets not limit ourself to a single field either

wim leers’s picture

Title: Add a derivative view for each comment field providing a REST export of comments for host entities » Add a derivative view for each comment field providing a REST export of comments for commented entities

#10

  1. I guess you're right, but it's another thing you have to somehow magically know besides figuring out rest.settings.yml… but that ship has sailed anyway, so +1
  2. :)
  3. Good question, we should ensure the commented entity can be viewed by the current user.
  4. No idea, I basically disabled the pager (i.e. showing all comments). The Views UI says: Items to display:Display all items | All items
  5. Weird, I'm not at all using fields. I'm just exposing Comment entities. The Views UI says: The selected style or row format does not use fields.
  6. I don't quite understand what you're saying here.

#11: Agreed on all counts. Except I don't know how to do any of that.

#13: True again, but also no idea how to do that either.

Help very much welcomed!

wim leers’s picture

@Crell: would #2100637: REST views: add special handling for collections also be able to solve this for us?

larowlan’s picture

Ah, so if this runs off Comment entities - if we change the uri to comments/{entity_type_id}/{entity_id} and add an argument that filters using the entity_type_id column/field on Comments, it should be generic enough to support all entity-types. Then we'd just need a new link-template in the commented entity-type » something like 'comment-thread'. This could be done in comment_entity_type_alter by looping over comment-types and collecting all of the target entity types - Something like this:

function comment_entity_type_alter(&$entity_types) {
  if (\Drupal::moduleHandler()->moduleExists('views')) {
    $comment_types = CommentType::loadMultiple();
    foreach ($comment_types as $id => $comment_type) {
      $target_type = $comment_type->getTargetEntityTypeId();
      $entity_types[$target_type]->setLinkTemplate('comment-thread', 'comments/' . $target_type . '/{' . $target_type . '}');
    }
  }
}

We could also accept an optional field-name to make it extra useful comments/{entity_type_id}/{entity_id}/{field_name}?

Then when we generate the hal representation of a node with commenting enabled, we could add a link to the 'comment-thread' using the link template.

Thoughts?

wim leers’s picture

Sounds great! Just one problem: what if there are multiple comment types on the same entity?

larowlan’s picture

That's where the optional field name will come in, but could easily be the comment-type too - both are base fields on Comment entity, so should be available as arguments.

wim leers’s picture

Oops. You already covered that, I missed it in my first reading. Alright, let's do it? :)

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.0-beta1 was released on March 2, 2016, which means new developments and disruptive changes should now be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.0-beta1 was released on August 3, 2016, which means new developments and disruptive changes should now be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

wim leers’s picture

Do we still want this?

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.0-alpha1 will be released the week of January 30, 2017, which means new developments and disruptive changes should now be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

wim leers’s picture

Status: Needs work » Closed (works as designed)

Since this is obviously not going to work as simply as I had originally imagined (I was too naïve), and for the reasons given in #2100637-156: REST views: add special handling for collections, I'm going to close this issue.