.net core实践系列之短信服务-Sikiro.SMS.Api服务的实现(一)

本文涉及的产品
短信服务,200条 3个月
短信服务,100条 3个月
简介: .net core实践系列之短信服务-Sikiro.SMS.Api服务的实现(一)

前言


上篇《.net core实践系列之短信服务-架构设计》介绍了我对短信服务的架构设计,同时针对场景解析了我的设计理念。本篇继续讲解Api服务的实现过程。


源码地址:https://github.com/SkyChenSky/Sikiro.SMS


此服务会使用.NET Core WebApi进行搭建,.NET Core WebApi基础原型就是RESTful风格,然而什么叫RESTful呢。


REST API简介


REST


Representational State Transfer的缩写,翻译为“表现层状态转化”,是由Roy Thomas Fieding在他的博士论文《Architectural Styles and the Design of Network-based Software Architectures》中提出的一种架构思想。


而他的论文中提出了一个RESTful应用应该具备的几点约束。


  • 每个资源都应该有一个唯一的标识
  • 每一个对象或资源都可以通过一个唯一的URI进行寻址,URI的结构应该是简单的。
  • 使用标准的方法来更改资源的状态
  • GET、POST、PUT、PATCH、DELETE
  • Request和Response的自描述
  • 资源多重表述
  • URI所访问的每个资源都可以使用不同的形式加以表示(XML或JSON)
  • 无状态的服务
  • 不需要保存会话状态(SESSION),资源本身就是天然的状态,是需要被保存的。


RESTful


当某Web服务遵守了REST这些约束条件和原则,那么我们可以称它设计风格就是 RESTful。


三特点


REST有三大特点:

  • 资源(名词)
  • 动作(动词)
  • 表述(超文本)



1650718264(1).png


资源


抽象的说他可以是音频、也可以是视频,更可以是订单。更俗讲其实就是实体,更接*我们*常说的“类(class)”。另外REST强调资源有唯一的URI。下面有对比


动作


主要动作:

  •  GET:检索单个资源;
  •  POST:主要是创建资源,但是GET的参数长度受限,因此也可以用在复杂参数的检索资源场景;
  •  PUT:更新资源所有属性,也可以称为替换资源;
  •  PATCH:更新资源部分属性;
  •  DELETE:删除资源;


表述


对于Request与Response的自描述,而表述方式有多种:XML、JSON等,强调HTTP通信的语义可见性。


对比


RPC


SMSApi.com/api/GetSMS


SMSApi.com/api/CreateSMS


传统的接口设计面向过程的,每个动作有特定的URI。


REST


SMSApi.com/api/SMS  GET


SMSApi.com/api/SMS  POST


REST API每个资源只有唯一的URI,而资源可以有不同的动作执行相应的接口


RPC的更加倾向于面向过程,而RESTful则以面向对象的思想进行设计。


接口定义


回到我们的短信服务,以上面的三特点进行出发,SMS不需要由外部服务进行删除、修改资源因此:


资源:SMS

动作:GET、POST

表述方式:我们约定Request、Response为JSON格式


/// <summary>
    /// 短信接口
    /// </summary>
    [Route("api/[controller]")]
    [ApiController]
    public class SmsController : ControllerBase
    {
        private readonly SmsService _smsService;
        private readonly IBus _bus;
        public SmsController(SmsService smsService, IBus bus)
        {
            _smsService = smsService;
            _bus = bus;
        }
        /// <summary>
        /// 获取一条短信记录
        /// </summary>
        /// <param name="id">主键</param>
        /// <returns></returns>
        [HttpGet("{id}")]
        public ActionResult<SmsModel> Get(string id)
        {
            if (string.IsNullOrEmpty(id))
                return NotFound();
            var smsService = _smsService.Get(id);
            return smsService.Sms;
        }
        /// <summary>
        /// 发送短信
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        [HttpPost]
        public ActionResult Post([FromBody] List<PostModel> model)
        {
            _smsService.Add(model.MapTo<List<PostModel>, List<AddSmsModel>>());
            _smsService.SmsList.Where(a => a.TimeSendDateTime == null)
                .ToList().MapTo<List<SmsModel>, List<SmsQueueModel>>().ForEach(item =>
                {
                    _bus.Publish(item);
                });
            return Ok();
        }
        /// <summary>
        /// 查询短信记录
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        [HttpPost("_search")]
        public ActionResult<List<SmsModel>> Post([FromBody] SearchModel model)
        {
            _smsService.Search(model.MapTo<SearchModel, SearchSmsModel>());
            return _smsService.SmsList;
        }
    }


功能描述


由上可见一共定义了三个接口


  • GET   http://localhost:port/api/sms/id 获取一条短信记录
  • POST http://localhost:port/api/sms 发送短信
  • POST http://localhost:port/api/sms/_search 查询短信记录


获取一条短信记录就不多解析了


查询短信记录


动作我使用了POST,有人会问检索资源不是用GET么?对,但是GET的参数在URL里是受限的,因此在复杂参数的场景下应该选择POST,然而我是模仿elasticsearch的复杂查询时定义,添加多一个节点/_search申明此URI是做查询的。


发送短信


此接口的实现逻辑主要两件事,持久化到MongoDB,过滤出及时发送的短信记录发送到RabbitMQ。


在持久化之前我做了一个分页的动作,我们提供出去的接口,同一条短信内容支持N个手机号,但是不同的短信运营商的所支持一次性发送的手机数量是有限的。


开始实现时,我把分页发送写到队列消费服务的发送短信逻辑里,但是这里有个问题,如果分页后部分发送成功,部分发送失败,那么这个聚合究竟以失败还是成功的状态标示呢?换句话来说我们无法保证聚合内的数据一致性。


因此我的做法就是优先在分页成多个文档存储,那么就可以避免从数据库取出后分页导致部分成功、失败。


public void Add(List<AddSmsModel> smsModels)
        {
            DateTime now = DateTime.Now;
            var smsModel = new List<SmsModel>();
            foreach (var sms in smsModels)
            {
                var maxCount = _smsFactory.Create(sms.Type).MaxCount;
                sms.Mobiles = sms.Mobiles.Distinct().ToList();
                var page = GetPageCount(sms.Mobiles.Count, maxCount);
                var index = 0;
                do
                {
                    var toBeSendPhones = sms.Mobiles.Skip(index * maxCount).Take(maxCount).ToList();
                    smsModel.Add(new SmsModel
                    {
                        Content = sms.Content,
                        CreateDateTime = now,
                        Mobiles = toBeSendPhones,
                        TimeSendDateTime = sms.TimeSendDateTime,
                        Type = sms.Type
                    });
                    index++;
                } while (index < page);
            }
            SmsList = smsModel;
            _mongoProxy.BatchAddAsync(SmsList);
        }


目录
相关文章
|
11月前
|
JSON 安全 Java
API 一键转换 MCP 服务!Higress 助今日投资快速上线 MCP 市场
今日投资的技术负责人介绍了如何通过Higress MCP 市场完善的解决方案,快捷地将丰富的金融数据 API 转化为 MCP 工具,帮助用户通过 MCP 的方式非常轻松地调用专业金融数据,自由快速地构建自己的金融大模型应用。
1258 23
|
10月前
|
监控 供应链 搜索推荐
电商数据开发实践:深度剖析1688商品详情 API 的技术与应用
在电商数字化转型中,数据获取效率与准确性至关重要。本文介绍了一款高效商品详情API,具备全维度数据采集、价格库存管理、多媒体资源获取等功能,结合实际案例探讨其在电商开发中的应用价值与优势。
|
10月前
|
前端开发 Java API
利用 Spring WebFlux 技术打造高效非阻塞 API 的完整开发方案与实践技巧
本文介绍了如何使用Spring WebFlux构建高效、可扩展的非阻塞API,涵盖响应式编程核心概念、技术方案设计及具体实现示例,适用于高并发场景下的API开发。
710 0
|
12月前
|
缓存 监控 搜索推荐
电商生态协同的关键:API接口在电商数据对接中的应用与实践
电商数据对接API接口是连接电商平台与外部系统的智慧桥梁,通过标准化协议实现商品管理、订单处理、支付结算、物流追踪及数据分析等全链路支持。本文从核心功能、对接流程、应用场景和优化策略四个方面解析其技术逻辑与实践路径。API接口助力店铺管理自动化、精准营销与跨境电商全链路管理,同时通过安全防护、性能调优与合规管理提升效能,推动电商行业向智能化、高效化发展。
|
11月前
|
JSON API UED
运营商二要素验证 API:核验身份的一致性技术实践(Python示例)
随着线上业务快速发展,远程身份核验需求激增。运营商二要素验证API通过对接三大运营商实名数据,实现姓名、手机号、身份证号的一致性校验,具备权威性高、实时性强的优势,广泛应用于金融、电商、政务等领域。该接口支持高并发、低延迟调用,结合Python示例可快速集成,有效提升身份认证的安全性与效率。
989 0
|
11月前
|
自然语言处理 供应链 前端开发
深度解析与技术实践:高效调用淘宝商品评论API的策略与代码实现
本文深入解析淘宝开放平台商品评论接口(Taobao.item_review),涵盖接口功能、调用逻辑与实战代码,助力开发者高效获取用户评价数据,提升电商数据分析能力。
|
12月前
|
人工智能 自然语言处理 API
电商API技术文档编写规范白皮书:方法论与行业实践
本文系统阐述电商API接口文档的编写规范与最佳实践,涵盖结构设计、技术语言、开发者体验、版本控制及质量保障等方面,助力企业提升开发效率,构建开放共赢的电商生态。
|
9月前
|
供应链 安全 API
唯品会:利用银行转账API实现企业采购对公支付的技术实践
企业采购支付面临合规、效率与对账难题。唯品会通过银行API实现银企直连,构建安全高效对公支付系统,支持ISO 20022标准与多重风控,支付耗时从72小时降至90秒,错误率下降98%,推动供应链数字化升级。(236字)
|
9月前
|
算法 API 数据安全/隐私保护
深度解析京东图片搜索API:从图像识别到商品匹配的算法实践
京东图片搜索API基于图像识别技术,支持通过上传图片或图片URL搜索相似商品,提供智能匹配、结果筛选、分页查询等功能。适用于比价、竞品分析、推荐系统等场景。支持Python等开发语言,提供详细请求示例与文档。
|
11月前
|
数据采集 缓存 JSON
1688商品API全链路开发实践
本文介绍了对接1688开放平台的核心要点,涵盖OAuth2.0认证流程、商品列表接口调用技巧、高并发优化策略及异常处理清单。内容包含获取access_token示例、隐藏参数解析、数据清洗方案与缓存设计,并强调合规调用注意事项。
1688商品API全链路开发实践