Hypermedia links with new Servicestack API

I am evaluating how to add hyperlinks to DTO responses. Despite the lack of a standard, add a DTO answer list, which seems to be the proposed approach .

Do you know any example or link to implementations using the ServiceStack infrastructure?

Adding a list is suitable for me, but my doubts relate to where to put the logic of the following links (inside a service or a specialized class that contains a state machine?) And where to allow routes (filter?)

Thanks.

[Update] From ServiceStack version 3.9.62, you can access the configuration of routes through EndpointHost.Config.Metadata.Routes.RestPath, so the solution provided by tgmdbm can be improved taking into account the need for IReturn + Routes attributes, simply using the Metadata.Routes information. Virtually all service metadata can be requested and used for cross-cutting issues. Service rocks.

+7
c # rest servicestack
source share
1 answer

As I do this now, I pass a dto response that implements the interface

public interface IHaveLinks { [IgnoreDataMember] IEnumerable<Link> Links { get; } } public class Link { public string Name { get; set; } public IReturn Request { get; set; } public string Method { get; set; } } 

Then I use the response filter to generate the URLs and fill the response headers with links.

 this.ResponseFilters.Add((req, res, dto) => { if (!(dto is IHaveLinks)) return; var links = (dto as IHaveLinks).Links if(links == null || !links.Any()) return; var linksText = links .Select(x => string.Format("<{0}>; rel={1}"), x.Request.ToUrl(x.Method), x.Name)); var linkHeader = string.Join(", ", linksText); res.AddHeader("Link", linkHeader); }); 

It seems the cleanest way. The Link object above effectively says: "If you make this request using this method, you will return the named resource." The only HTTP thing that expires before the BLL is Method . But you can get rid of this and just go back to the GET URL. Or compare it with some generalized "operation"?

As an example:

 public class ExampleService : Service { public ExamplesResponse Get(ExamplesRequest request) { var page = request.Page; var data = // get data; return new ExamplesResponse { Examples = data, Links = new [] { new Link { Name = "next", Request = request.AddPage(1), Method = "GET" }, new Link { Name = "previous", Request = request.AddPage(-1), Method = "GET" }, } } } } [Route("/examples/{Page}")] public class ExamplesRequest : IReturn<ExamplesResponse> { public int Page { get; set; } // ... } 

(The AddPage method returns a clone of the request and sets the page property accordingly.)

Hope this helps.

+9
source share

All Articles