Skip to content
No description, website, or topics provided.
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
build
eng
src
.gitattributes
.gitignore
Directory.Build.props
Directory.Build.targets
LICENSE
Migrap.AspNetCore.Hateoas.sln
NuGet.config
README.md
azure-pipelines.yml
build.cmd
build.sh
global.json

README.md

Migrap.AspNetCore.Hateoas

Description

HATEOAS (Hypermedia as the Engine of Application State) framework for ASP.NET Core.

Commands

https://github.com/aspnet/Extensions/blob/release/2.2/Directory.Build.props

Example(s)

Current implementation(s):

  • Siren
  • JsonApi
public class Startup {
    public void ConfigureServices(IServiceCollection services) {
        services.AddMvc(options => {
        }).AddSirenOptions(options => {
            options.StateConverters.Add(new ArticleSirenStateConverterProvider());
        });            
    }

    public void Configure(IApplicationBuilder app) {
        app.Use((context, next) => {
            if(context.Request.Path.StartsWithSegments("/ping")) {
                return context.Response.WriteAsync("pong");
            }
            return next();
        });

        app.UseMvc();
    }
}

[Route("[controller]")]
public class ArticlesController : Controller {
    [HttpGet()]
    public IEnumerable<Article> Get() {
        return new List<Article> {
            new Article {
                Id ="1",
                Title = "JSON API paints my bikeshed!",
                Body = "The shortest article. Ever.",
                Created =1432306588,
                Updated =1432306589
            },
            new Article {
                Id ="2",
                Title = "JSON API paints my homework!",
                Body = "The shortest article. Ever... again",
                Created =1432306588,
                Updated =1432306589
            }
        };
    }
}

public class ArticleSirenStateConverterProvider : IStateConverterProvider {
    public IStateConverter CreateConverter(StateConverterProviderContext context) {
        if(context == null) {
            throw new ArgumentNullException(nameof(context));
        }

        if(typeof(Article).IsAssignableFrom(context.ObjectType) || typeof(IEnumerable<Article>).IsAssignableFrom(context.ObjectType)) {
            return new ArticleSirenStateConverter();
        }

        return null;
    }
}

public class ArticleSirenStateConverter : IStateConverter {
    public Task<object> ConvertAsync(StateConverterContext context) {
        var articles = (context.Object as IEnumerable<Article>);

        var path = context.HttpContext.Request.GetDisplayUrl();

        var properties = new {
            count = articles.Count()
        };
            
        var document = new Migrap.AspNetCore.Hateoas.Siren.Core.Document {
            Class = new Class { "article", "collection" },
            Properties = properties,
            Href = path,
        };

        var entities = articles.Select(a => {
            return new Entity {
                Class = new Class { "article" },
                Properties = a,
                Href = $"{path}/{a.Id}",
            };
        });

        document.Entities.Add(entities);

        return Task.FromResult<object>(document);
    }
}    

public class Article {
    public Article() {
    }

    public Article(string id, string title, string body, long created, long updated) {
        Id = id;
        Title = title;
        Body = body;
        Created = created;
        Updated = updated;
    }

    public string Id { get; set; }
    public string Title { get; set; }
    public string Body { get; set; }
    public long Created { get; set; }
    public long Updated { get; set; }
}
You can’t perform that action at this time.