2021-01-25HATEOAS

HATEOAS

Hypermedia As The Engine Of Application State

  • HATEOAS是rest架构风格中最复杂的约束,也是构建成熟Rest服务的核心,它的重要性打破了客户端与服务端的严格的契约,也让客户端更加的智能和自适应,而Rest本身的演化和更新则变得更容易。
  • 有助于自我描述性和可进化性。
  • 超媒体驱动如何消费和使用Api

相较于纯粹的资源

  • 客户端更多地需要了解Api的内在逻辑
  • 如果Api发生了一点变化,都会破坏消费者
  • Api无法独立于消费它的应用单独地进行进化。

支持HATEOAS

  • 需要给相应添加一个额外的属性“Links”,而客户端程序只需要检查这些Uri即可。

Html对HATEOAS的支持:

  • Json与Xml并没有展示Link的概念。
  • 而Html的anchor标签可以。
  • Href包含了URI。
  • rel描述了Link和资源的关系。
  • type可选,表示了媒体的类型。

方法

  1. 静态类型方法:通过基类和包装类,也就是返回的资源中都含有link,通过继承同一个基类实现。
  2. 动态类型方法:需要使用匿名类或者ExpandoObject等,单个资源使用ExpandoObject,集合类资源则使用匿名类。

代码

Link生成

        private IEnumerable<LinkDto> CreateLinksForCollege(long CollegeId,string fields)
        {
            var links = new List<LinkDto>();

            if (string.IsNullOrWhiteSpace(fields))
            {
                links.Add(new LinkDto(Url.Link(nameof(GetCollege), new { CollegeId }), "self", "GET"));
            }
            else
            {
                links.Add(new LinkDto(Url.Link(nameof(GetCollege), new { CollegeId , fields }), "self", "GET"));
            }
            links.Add(new LinkDto(Url.Link(nameof(DeleteCollege), new { CollegeId }), "delete_college", "DELETE"));

            links.Add(new LinkDto(Url.Link(nameof(IndustryController.GetIndustriesForCollege), new { CollegeId }), "industries", "GET"));

            links.Add(new LinkDto(Url.Link(nameof(IndustryController.CreateIndustryForCollege), new { CollegeId }), "create_industary_for_college", "POST"));

            return links;
        }

单个资源link添加到Model

            var link = CreateLinksForCollege(CollegeId, fields);
            var linkDict = _Mapper.Map<CollegeInfoDto>(college).ShapeData(fields) as IDictionary<string, object>;
            linkDict.Add("links", link);

多个资源Links生成

        private IEnumerable<LinkDto> CreateLinksForColleges(CollegeDtoParameters parameters,bool HasPrevious,bool HasNext)
        {
            var links = new List<LinkDto>();

            links.Add(new LinkDto(CreateCollegesResourceUri(parameters, ResourceUriType.CurrentPage), "self", "GET"));

            if(HasPrevious) links.Add(
                new LinkDto(CreateCollegesResourceUri(parameters, ResourceUriType.PreviousPage), "previous_page", "GET"));

            if (HasNext) links.Add(
                new LinkDto(CreateCollegesResourceUri(parameters, ResourceUriType.NextPage), "next_page", "GET"));
            return links;
        }

将Links添加到多个资源的Model中

            var shapeData = _Mapper.Map<IEnumerable<CollegeInfoDto>>(colleges).ShapeData(parameters.Fields);
            var links = CreateLinksForColleges(parameters, colleges.HasPrevious, colleges.HasNext);
            var shapeCollegesWithLinks = shapeData.Select(c =>
            {
                var collegeDict = c as IDictionary<string, object>;
                var collegeLinks = CreateLinksForCollege((long)collegeDict["Id"], null);
                collegeDict.Add("links", collegeLinks);
                return collegeDict;
            });
            var linkedCollegesResource = new
            {
                value = shapeCollegesWithLinks,
                links,
            };

Root目录

    [Route("Api")]
    [ApiController]
    public class RootController : Controller
    {
        [HttpGet(Name =nameof(GetRoot))]
        public IActionResult GetRoot()
        {
            var links = new List<LinkDto>();

            links.Add(new LinkDto(Url.Link(nameof(GetRoot), new { }), "self", "GET"));

            links.Add(new LinkDto(Url.Link(nameof(ConllegeController.GetColleges), new { }), "colleges", "GET"));

            links.Add(new LinkDto(Url.Link(nameof(ConllegeController.CreateCollege), new { }), "create_college", "POST"));

            return Ok(links);
        }
    }

课程来源:Restful Api

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值