joukevandermaas / saule

JSON API library for ASP.Net Web API 2.
https://joukevandermaas.github.io/saule
MIT License
76 stars 37 forks source link

Make links optional #150

Closed bjornharrtell closed 7 years ago

bjornharrtell commented 7 years ago

According to the specification links are optional, see:

I've encountered situations where I would like them not included. Saule autogenerates links and has AFAIK no option to disable them all or selectively. Would it make sense to introduce such a feature?

I have tried overriding as described by https://github.com/joukevandermaas/saule/wiki/Generating-links but even if returning null there will be an empty links objekt. Also, that way seem a bit overkill and I'm thinking an attribute could perhaps be created for this purpose instead.

joukevandermaas commented 7 years ago

Somewhat related to #121. I think it's pretty nice that Saule theoretically (after #121 is in) allows you to implement this attribute yourself, but I agree it could be a bit more ergonomic.

I imagine you want to disable links for a resource, not an endpoint. That implies the configuration should be in ApiResource.

bjornharrtell commented 7 years ago

I'm not certain it's always for ApiResource. In my mind I thought about excluding them for a specific relationship only. I'll see if I can think up a description on how it could be designed, unless you have a suggestion already? #121 does not seem to give any indication on how to make the properties optional.

joukevandermaas commented 7 years ago

I'm curious about your use-case for per-relationship link behavior. In any case, I would like for the configuration to occur on the ApiResource. Either on the resource itself, or when the relationship is defined. Examples:

// On relationship:

class PersonResource : ApiResource
{
  public PersonResource() {
    BelongsTo<CompanyResource>(nameof(Person.Job), "/job", LinkTypes.None);
  }
}

// On resource itself:

class PersonResource : ApiResource
{
  public PersonResource() {
    WithLinks(LinkTypes.None);
  }
}

The names of the methods/enum values are not really that important (they can change). The enum could look something like this:

[Flags]
enum LinkTypes
{
  None = 0,
  Self = 1,
  Related = 2,
  RelatedCanonical = 4,
  All = ~None
}

It would be respected by the UrlPathBuilders that come with Saule and the default value would be All.

This allows for easy configuration when the needs are simple, but it also allows custom UrlPathBuilders to have the same power as the built in ones.

bjornharrtell commented 7 years ago

In my initial case where I thought about this it's about the "self" link for a relationship object that will point to a path that is non-existent unless you implement it so I wanted to remove it since it was not relevant for use in this particular case. Also, the links property will take up considerable space if you are fetching a collection of entities with multiple relationships.

In any case I like your proposed API, will try to implement. :)