Virtuesoft.Framework.Gateaway 一个超级简单的webapi接口框架

Virtuesoft.Framework.Gateaway api接口框架

起源

公司的系统需要做一个开放平台的接口对外提供一些服务.之前都用webapi 或者mvc来实现.但是用久了之后发现各种引用的包,各种插件其实都用不上.配置也麻烦.(首先申明我是一个非常懒,非常懒,懒到出奇的人,懒到多一个代码,多一个符号都不想打的人.)功能要求很很简单,就是响应http请求然后处理数据返回信息,而且我还不想写文档(写api文档太多拷贝复制,而且更新了还要…所以干脆写到代码,让前端去累!),仅此而已,所以干脆自己造个轮子,顺便可以了解和提升一下代码质量.(闲得蛋疼)所以就花了几个小时干了这么个玩意儿,再写个博客记录一下(差不多最后一次写博客是2012年).

最简单的使用

  1. 新建一个空的asp.net core web 项目,记住,什么都没有的.
  2. 导入nuget包 Virtuesoft.Framework.Gateaway ;
  3. 修改 Startup 在ConfigureServices中添加 services.AddGateaways() ,子Configure 中添加 app.UseGateaway();
    大概就是下面这个样子
		public void ConfigureServices(IServiceCollection services)
        {
            services.AddGateaways();
        }
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            app.UseGateaway();
        }

不要考虑了,就这些,没有多的代码.说了我讨厌那么多冗余的代码.而且不想写文档.

  1. 然后,就没有然后了.当然我个人习惯不喜欢直接用iis express启动,所以我修改了一下Program 用控制台方式启动;
    上代码吧,自己看.(我这个代码是用的控制台程序,没有使用asp.net core 项目)
public static void Main(string[] args)
        {
            WebHostBuilder webHost = new WebHostBuilder();
            webHost.UseStartup<Startup>()
                .UseDefaultServiceProvider(config => { })
                .UseUrls("http://10.0.0.90:1111")
                .UseKestrel()
                .Build()
                .Run();
        }

然后启动postman
post方式.form提交一个参数: method=api.doc
当然用json提交也可以,就是不支持get,不要问为什么,反正不支持.
这个是结果:
在这里插入图片描述
框架带了一个默认的接口文件,就是文档.可以返回当前项目中所有的接口信息和描述.这个就是想累死那些做前端,让他们直接ajax过去拿数据,然后生成文档界面.这样只要我更新代码,前端界面就更新了.由于文档页面可能出现在不同的网站上,而且界面也不同,所以就不做到api的接口里面了.个人觉得这样的方法,程序员最偷懒.
这里默认了3个api,
api.catalog : 接口文档目录,只返回接口名称和描述
api.doc : 显示所有接口文档
api.query : 查询单个接口详细内容
参数类型,返回值等都有,自己去看,我也懒得和前端沟通了.

写一个自己的接口

新建一个类 Member 继承GateawayBase
重写一下Controller 属性 (这个是导航属性)
算了,不想写中文了,直接上代码

public class Member:GateawayBase
    {
        public override string Controller => "member";
        public async Task<int> Online()
        {
            return await Task.FromResult(0);
        }
    }

再打开postman 修改参数 method=member.online
这次我用json提交,一定要记得类型是json
在这里插入图片描述
返回值的格式可以自己定义,后面再说.返回一个0 默认是 d 参数.
再写个方法,返回复杂类型的数据
先新增一个user类

  public class User {
        public string name { get; set; }
        public string sex { get; set; }
        public string phone { get; set; }
    }

再添加一个paged方法,用于获取一个用户的数组

 public User[] Paged() {
            return new User[] {
                new User(){ name="好",phone="1111111",sex="男"},
                new User(){ name="多",phone="2222222",sex="女" },
                new User(){ name="吊",phone="3333333",sex="男"},
                new User(){ name="毛",phone="4444444",sex="女"},
                new User(){ name="啊",phone="5555555",sex="男"},
            };
        }

postman 一下看结果
在这里插入图片描述
如果没有其他特殊的要求,就可以开始尽情的写接口了.
我们看看接口文档返回的是啥:
在这里插入图片描述
为什么没有描述?
为什么没有默认值?
为什么…
还没到地方.

进阶一步,验证必要参数.

对于api接口来说,需要约束公共参数,这些都是必填的.比如商户平台,需要传递公共参数为商户的编号,签名方式,随机字串,时间戳等等.
当然,这个是很简单的.
修改 Startup 文件,

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            app.UseGateaway(option=> {
                option.OnVerifyPrameters = (forms,httpcontent) => {
                    if(!forms.ContainsKey("merchid"))
                        return (false, "缺少参数:merchid");
                    if (!forms.ContainsKey("timestamp"))
                        return (false, "缺少参数:timestamp");
                    if (!forms.ContainsKey("noncestr"))
                        return (false, "缺少参数:noncestr");
                    if (!forms.ContainsKey("signtype"))
                        return (false, "缺少参数:signtype");
                    if (!forms.ContainsKey("sign"))
                        return (false, "缺少参数:sign");
                    return (true,"ok");
                };
            });
        }

如果你问 return (true,“ok”); 这是什么写法的话,那去看看 System.ValueTuple 这个有详细说明,只是为了返回多个值.都说了我懒,不想为了几个参数就去新建一个类.
然后我们post一下数据过去.

post->
{"method":"api.doc"}
return->
{"s":false,"c":500,"m":"缺少参数:merchid","d":null}

正常返回错误信息.
我们吧参数写全

post->
{"method":"member.paged",
"merchid":"20191259856854",
"timestamp":"12345623413",
"noncestr":"daseedgerydfhtrjert",
"signtype":"md5",
"sign":"299A1196F95E628D98ADE35CCA04BE77"}
result->
{
    "s": true,
    "c": 200,
    "m": "",
    "d": [
        {
            "name": "好",
            "sex": "男",
            "phone": "1111111"
        },
        {
            "name": "多",
            "sex": "女",
            "phone": "2222222"
        },
        {
            "name": "吊",
            "sex": "男",
            "phone": "3333333"
        },
        {
            "name": "毛",
            "sex": "女",
            "phone": "4444444"
        },
        {
            "name": "啊",
            "sex": "男",
            "phone": "5555555"
        }
    ]
}

正常返回.

进阶第二部验证签名

至于你想怎么去验证我不知道,我就用支付宝的算法吧.
signtype,sign 和值为空的参数不参与签名
参数按键名排序->拼接为url格式->转换大写->md5.
当然这里少了一步拼接个key,这个是和调用者协商的密钥.当然你可以rsa,des,aes什么的乱七八糟一堆.
我见过一个接口,他把常用的加密方式全部用了一遍,不管解密麻烦,还多重加密一下(什么银行就不点名了).
服务器端验证签名:
修改 Startup 文件,

 public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            app.UseGateaway(option=> {
                option.OnVerifyPrameters = (forms,httpcontent) => {
                    if(!forms.ContainsKey("merchid"))
                        return (false, "缺少参数:merchid");
                    if (!forms.ContainsKey("timestamp"))
                        return (false, "缺少参数:timestamp");
                    if (!forms.ContainsKey("noncestr"))
                        return (false, "缺少参数:noncestr");
                    if (!forms.ContainsKey("signtype"))
                        return (false, "缺少参数:signtype");
                    if (!forms.ContainsKey("timestamp"))
                        return (false, "缺少参数:timestamp");
                    return (true,"ok");
                };
                option.OnVerifySign = (forms, httpcontent) =>
                {
                    var dataArry= forms.Where(t => t.Key != "signtype")
                    .Where(t => t.Key != "sign")
                    .Where(t => t.Value.IsNullOrEmpty())
                    .OrderBy(t => t.Key)
                    .Select(t=>$"{t.Key}={t.Value}")
                    .ToArray();
                    var sign = string.Join("&", dataArry)
                    .ToUpper()
                    .Md5Encrypt();
                    return sign== forms["sign"];
                };
            });

        }

继续测试

post->
{"method":"member.paged",
"merchid":"20191259856854",
"timestamp":"12345623413",
"noncestr":"daseedgerydfhtrjert",
"signtype":"md5",
"sign":"299A1196F95E628D98ADE35CCA04BE77"}
result->
{
    "s": false,
    "c": 500,
    "m": "签名错误",
    "d": null
}

当然你还可以验证其他的或者直接修改掉验证方式,甚至做个登录保存user的东西都没问题.
还有,访问数据库什么的和asp.net core一样,配置,接口也支持DI注入什么的.哎就不多说了.
所有的参数设置都I在 option.On*** 中,比如修改返回值的格式.在响应请求之前写入日志,响应之后写入日志,ip限制等都在里面.
我发现今天写了很多字,有点手累.
如果有什么好的建议可以留言,最后截图一个:
在这里插入图片描述
一个项目除了基础文件,几乎没有多余的任何文件,主要是真的懒.

后续更新
处理其他平台的回调函数
扩展修改路由方式
数据库操作案例

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值