paulcwarren/spring-content

Configuring REST paths for content properties

Closed this issue · 2 comments

Is your feature request related to a problem? Please describe.

I would like to configure the path where a content property gets exposed.

We can already configure the link relation that is used for content properties on an entity, but the URL path is currently always derived directly from the property name.

class MyResource {
   @ContentId
   @RestResource(linkRel="received_document")
   private String receivedDocumentId;
}

Describe the solution you'd like

Because we can have multiple pieces of content stored on one object, we would like to modify that path with an annotation on the @ContentId-annotated property.

The @RestResource annotation already has a paths parameter, and is already supported on the @ContentId-annotated property.

So I would propose accepting this paths parameter to set the path segment for the content property.

For this example, we want to have the URLs /myResource/123/received-document and /myResource/123/sent-document

class MyResource {
   @ContentId
   @RestResource(linkRel="received_document", paths="received-document")
   private String receivedDocumentId;

   @ContentId
   @RestResource(linkRel="sent_document", paths="sent-document")
   private String sentDocumentId;
}

I know that the paths parameter is a String[], so could potentially take multiple values.
That is due to the fact that the @RestResource annotation (with exported=false and paths set to some contentProperty paths) can also be put on methods of a ContentStore.

If you feel that this is mixing two distinct features too much, separating the annotations would also be fine for me.

Describe alternatives you've considered

I considered using @StoreRestResource(path="xyz") on the ContentStore, but that actually changes the segment at the start of the URL.

Annotations on the store also won't work in general, because that would apply the path segment to all content properties on an entity, which is of course undesired.

We could of course also write a custom controller, but that feels very heavyweight for just changing a static value of the path segment.

Hi @vierbergenlars,

If I recall you are using @Embedded so you might also want to influence the shortened version of the path too, correct?

i.e.

public class Contract {
  @Id
  private Long id;

  @Embedded
  @RestResource(rel="package", paths={"package"})
  private Content _package;

  @Embedded
  private Customer customer;
}

public class Customer {
  @Embedded
  @RestResource(rel="private", paths={"private"})
  private Content _private;
}

public class Content {
  @ContentId
  private UUID id;

  @ContentLength
  private long length;
}

Resulting in something like this for contract?

  "_links" : {
    ...
    "package" : {
      "href" : "http://localhost:8080/contracts/1/package"
    },
    "customer/private" : {
      "href" : "http://localhost:8080/contracts/1/customer/private"
    }

Hi Paul,

I did not think about those details when I was creating the issue, but your example is exactly to the point of what we are trying to create.

Would you envision supporting multiple values for the paths parameter in these cases as well?

With nested @Embedded annotations, it does lead to a combinatoral explosion of possibilities.

While we don't have a need for multiple values support, it would be confusing if only the first value is taken into account.