简单的接口框架

  日常开发中经常会用到接口,传输都基于http,.net下有简单的ashx或aspx等搭载接口或MVC下的WebApi,或Wcf等。。

之前开发中用到了Web轻型框架:Nancy,Json序列化工具ServiceStack.Text,于是将两者结合下构造一个我自己的小接口框架

一.服务端抽象

先上5个基本抽象类和接口

1.请求基类:可包含一些账户等信息

public class RequestBase
    {
    }

2.响应基类:包括响应状态

public class ResponseBase
    {
        public ResponseBase()
        {
            Status = new ResponseStatus();
        }
        public ResponseStatus Status { get; set; }
    }
public class ResponseStatus
    {
        public ResponseStatus()
        {
            this.ErrCode = string.Empty;
            this.ErrMsg = string.Empty;
        }
        public ResponseStatus(string errCode, string errMsg)
        {
            this.ErrCode = errCode;
            this.ErrMsg = errMsg;
        }
        /// <summary>
        /// 是否成功
        /// </summary>
        public bool IsSuccess
        {
            get
            {
                if (string.IsNullOrEmpty(ErrCode) || string.IsNullOrEmpty(ErrMsg))
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
        }
        /// <summary>
        /// 错误码
        /// </summary>
        public string ErrCode { get; set; }
        /// <summary>
        /// 错误信息
        /// </summary>
        public string ErrMsg { get; set; }
    }

3.接口验证接口:验证请求参数等

public interface IBaseService<R, S>
        where R : RequestBase
        where S : ResponseBase
    {
        /// <summary>
        /// 请求验证
        /// </summary>
        /// <param name="request">请求实体</param>
        /// <returns></returns>
        ResponseStatus Vaild(R request);
    }

4.接口逻辑处理接口:处理核心逻辑

public interface ICoreService<R, S>
        where R : RequestBase
        where S : ResponseBase
    {
        S GetResponse(R r);
    }

最终一个接口的请求验证——处理流程变成了这样:

public class ServiceClient
    {
        public static S Excute<R, S>(R r, IBaseService<R, S> baseService, ICoreService<R, S> coreService)
            where R : RequestBase
            where S : ResponseBase
        {
            S s = System.Activator.CreateInstance<S>();
            try
            {
                s.Status = baseService.Vaild(r);
                if (s.Status.IsSuccess)
                {
                    s = coreService.GetResponse(r);
                }
            }
            catch (Exception ex)
            {
                s.Status = new ResponseStatus("0", "接口内部异常" + ex.Message);
            }
            return s;
        }
    }

以上是接口服务端抽象出来的各个部分

二.接口Host:包括接口部署寄存的web以及Url规则和反射

Host采用Nancy框架,主要有两个路由:

Post["{Service}/{Request}"] = p =>
            {
                ErrResponse errResponse = new ErrResponse();
                try
                {
                    string reqName = p.Request.ToString().ToLower().Trim();
                    string serviceName = p.Service.ToString().ToLower().Trim();
                    if (!Config.ServiceTypeList.ContainsKey(serviceName) || !Config.RequestTypeList.ContainsKey(reqName))
                    {
                        errResponse.Status = new ResponseStatus("0", "无此接口");
                        return JsonSerializer.SerializeToString<ErrResponse>(errResponse);
                    }
                    Type request = Config.RequestTypeList[reqName];
                    Type response = Config.ResponseTypeList[reqName];
                    Type service = Config.ServiceTypeList[serviceName];

                    object req = JsonSerializer.DeserializeFromStream(request, Request.Body);
                    if (req == null)
                    {
                        errResponse.Status = new ResponseStatus("0", "请求参数不能为空或格式错误");
                        return JsonSerializer.SerializeToString<ErrResponse>(errResponse);
                    }
                    object res = Config.DelegateList[reqName](req);//直接缓存委托
                    return JsonSerializer.SerializeToString(res, response);
                }
                catch (Exception ex)
                {
                    errResponse.Status = new ResponseStatus("0", "接口内部异常" + ex.Message);
                    return JsonSerializer.SerializeToString<ErrResponse>(errResponse);
                }
            };
            Get["{Service}/{Request}"] = p =>
            {
                ErrResponse errResponse = new ErrResponse();
                try
                {
                    string reqName = p.Request.ToString().ToLower().Trim();
                    string serviceName = p.Service.ToString().ToLower().Trim();
                    if (!Config.ServiceTypeList.ContainsKey(serviceName) || !Config.RequestTypeList.ContainsKey(reqName))
                    {
                        errResponse.Status = new ResponseStatus("0", "无此接口");
                        return JsonSerializer.SerializeToString<ErrResponse>(errResponse);
                    }

                    Type request = Config.RequestTypeList[reqName];
                    Type response = Config.ResponseTypeList[reqName];
                    Type service = Config.ServiceTypeList[serviceName];

                    string strReq = Request.Query["request"];
                    object req = JsonSerializer.DeserializeFromString(strReq, request);
                    if (req == null)
                    {
                        errResponse.Status = new ResponseStatus("0", "请求参数不能为空或格式错误");
                        return JsonSerializer.SerializeToString<ErrResponse>(errResponse);
                    }

                    object res = Config.DelegateList[reqName](req);//直接缓存委托效率更高
                    return JsonSerializer.SerializeToString(res, response);
                }
                catch (Exception ex)
                {
                    errResponse.Status = new ResponseStatus("0", "接口内部异常" + ex.Message);
                    return JsonSerializer.SerializeToString<ErrResponse>(errResponse);
                }
            };

一个Get,一个Post处理逻辑是一样的,本来想分开,后来没什么时间,

Nancy部分可以参考开源项目:https://github.com/NancyFx/Nancy

这里主要讲下

1.路由:"{Service}/{Request}"根据不同的Service以及不同的Request获取对应的Type,接口在启动时已将所有Service以及请求,响应的Type做了缓存,还有处理方法(后面讲)

2.Json序列化:ServiceStack.Text

3.初始化缓存:

public class Config
    {
        public static Dictionary<string, Type> RequestTypeList = new Dictionary<string, Type>();
        public static Dictionary<string, Type> ResponseTypeList = new Dictionary<string, Type>();
        public static Dictionary<string, Type> ServiceTypeList = new Dictionary<string, Type>();
        //public static Dictionary<string, MethodInfo> MethodInfoList = new Dictionary<string, MethodInfo>();
        public static Dictionary<string, DoService> DelegateList = new Dictionary<string, DoService>();

        public static void Init()
        {
            if (RequestTypeList.Count > 0)
            {
                return;
            }
            EntityClient.AddToDomain();
            Assembly[] ass = AppDomain.CurrentDomain.GetAssemblies();

            Assembly entitysAss = ass.Where(t => t.FullName.Contains("FaceManage.Entitys")).FirstOrDefault();
            Assembly serviceAss = ass.Where(t => t.FullName.Contains("FaceManage.Services")).FirstOrDefault();

            List<Type> reqTypes = entitysAss.GetTypes().Where(t => t.BaseType == typeof(RequestBase)).ToList();
            List<Type> resTypes = entitysAss.GetTypes().Where(t => t.BaseType == (typeof(ResponseBase))).ToList();
            List<Type> serviceTypes = serviceAss.GetTypes().Where(t => t.BaseType == typeof(ServiceBase)).ToList();

            foreach (Type item in reqTypes)
            {
                RequestTypeList.Add(item.Name.Replace("Request", "").ToLower().Trim(), item);
            }

            foreach (Type item in resTypes)
            {
                ResponseTypeList.Add(item.Name.Replace("Response", "").ToLower().Trim(), item);
            }

            foreach (Type item in serviceTypes)
            {
                ServiceTypeList.Add(item.Name.Replace("Service", "").ToLower().Trim(), item);
                MethodInfo[] methods = item.GetMethods(BindingFlags.Public | BindingFlags.Static);
                foreach (MethodInfo method in methods)
                {
                    DoService serviceDelegate = (DoService)Delegate.CreateDelegate(typeof(DoService), null, method);
                    DelegateList.Add(method.Name.ToLower().Trim(), serviceDelegate);
                    //MethodInfoList.Add(method.Name, method);
                }
            }
        }
    }

这里我们知道接口符合一个委托,

public delegate object DoService(object request);

刚刚说到缓存方法就是创建方法的委托,并进行缓存,效率较高

 MethodInfo[] methods = item.GetMethods(BindingFlags.Public | BindingFlags.Static);
                foreach (MethodInfo method in methods)
                {
                    DoService serviceDelegate = (DoService)Delegate.CreateDelegate(typeof(DoService), null, method);
                    DelegateList.Add(method.Name.ToLower().Trim(), serviceDelegate);
                    //MethodInfoList.Add(method.Name, method);
                }
三。创建一个接口1.请求:
public class UpdateMemberTypeRequest : RequestBase
    {
        public int MemberId { get; set; }

        public int MemberType { get; set; }
    }

2.响应:

public class UpdateMemberTypeResponse : ResponseBase
    {
        public bool IsSuccess { get; set; }
    }

3.验证服务:

public class UpdateMemberTypeBase : IBaseService<UpdateMemberTypeRequest, UpdateMemberTypeResponse>
    {
        public ResponseStatus Vaild(UpdateMemberTypeRequest request)
        {
            ResponseStatus status = new ResponseStatus();
            try
            {
                if (request.MemberId <= 0)
                {
                    throw new Exception("会员Id不能小于0");
                }
            }
            catch (Exception ex)
            {
                status.ErrCode = "0";
                status.ErrMsg = ex.Message;
            }
            return status;
        }
    }

4.处理逻辑:

public class UpdateMemberTypeCore : ICoreService<UpdateMemberTypeRequest, UpdateMemberTypeResponse>
    {
        public UpdateMemberTypeResponse GetResponse(UpdateMemberTypeRequest request)
        {
            UpdateMemberTypeResponse response = new UpdateMemberTypeResponse();
            UpdateMemberTypeModel model = UpdateMemberTypeModel.Init(request);

            response.Status = model.UpdateMemberType();
            if (response.Status.IsSuccess)
            {
                response.IsSuccess = true;
            }
            return response;
        }
    }

5.一行代码

public static object UpdateMemberType(object req)
        {
            UpdateMemberTypeRequest request = (UpdateMemberTypeRequest)req;
            return ServiceClient.Excute<UpdateMemberTypeRequest, UpdateMemberTypeResponse>(request, new UpdateMemberTypeBase(), new UpdateMemberTypeCore());
        }

这样一个接口就开发Ok,

当然还忘了一点,这个时候其实你已经完成建立你自己接口的SDK

public static T Excute<T, S>(S req, string url)
        {
            T rsp = Activator.CreateInstance<T>();
            string reqJson = JsonSerializer.SerializeToString<S>(req);
            string resJson = HttpHelper.DoPost(url, reqJson, Encoding.UTF8);
            return JsonSerializer.DeserializeFromString<T>(resJson);
        }

调用方:

AddCooperaterRequest request = new AddCooperaterRequest()
            {
                Name = "test",
                PassWord = "test"
            };
            AddCooperaterResponse response = EntityClient.Excute<AddCooperaterResponse, AddCooperaterRequest>(request, "http://localhost/FaceManage/BaseMember/AddCooperater");

原项目将过几天开源

简单的接口框架

时间: 2024-10-03 09:56:52

简单的接口框架的相关文章

最简单的Java框架

框架framework的目的是定义骨架式方案,处理各种相同的底层细节:而开发人员使用框架时,能够依照自己的需求实现自己的功能--仅仅须要填入自己的东西/flesh. 最简单的框架,类似于JUnit,它有一个main(String[] args)启动本框架.假设是applet或GUI框架,就有太多底层细节须要处理. package principle.callback.lower; /** * 最简单的Java框架 * * @author yqj2065 * @version 2014.10 */

自己实现的一个简单的EF框架(反射实现)

我实现了一个简单的EF框架,主要用于操纵数据库.实现了对数据库的基本操纵--CRUD 这是项目结构 这是一个 core 下的 DLL 写了一个数据库工厂,用于执行sql语句.调用sql语句工厂 写了一个sql语句工厂,用于生成sql语句.调用类型工厂 写了一个类型工厂,用于获取所需的类型,识别特性等. appsettings.json是配置文件 最后一个是使用说明 我实现过程的首先从底层开始. 首先写的是类型工厂 结构 BaseTypeHelper.cs 是基础的类型帮助类 TypeHelper

Asp.net 面向接口框架之核心容器

新框架的容器部分终于调通了!容器实在太重要了,所有用了一个名词叫“核心容器”. 容器为什么那么重要呢?这个有必要好好说道说道. 1.首先我们说从框架名称面向接口编程说起,什么是面向接口编程?(这个度娘回答一下) 解读一下:类是个体的定义(建模), 个体的每一方面都可以是一个接口 说白点,其一接口可以代表对象(类)一个方面,再说透点对象可能是多面手(继承接口),能在不同场景(作为不同接口的实例)工作 其二每个接口可以不同实现,只要实现了这个接口,基本上就可以替换这个位置来正常工作 2.我觉得面向接

net 面向接口框架

Asp.net 面向接口框架之应用程序上下文作用域组件 在团队中推广面向接口开发两年左右,成果总体来说我还是挺满意的,使用面向接口开发的模块使用Unity容器配置的功能非常稳定,便于共享迁移(另一个项目使用只需要复制配置和调用接口即可)也很好扩展(操作的数据库.表.资源等都可以配置). 但是由于当时开发的匆忙(边开发边应用),留下一些比较致命的问题: 1.很多接口定义的不合理,通用性和扩展性不好 2.固定死了使用Unity容器,如果更大面积推广有问题,有些人已经很熟悉其他容器了,再来重新学Uni

Java http接口进阶——自我理解为接口框架形式

大龄青年初入Java,所以对有些专业术语的了解不是很深入,可能在写博文的时候,会有误解,望各大V能慷慨指出,感激不敬. 一.接口框架形式 接口框架如下: 形式比较简单,承接上篇的简单接口模式. 大概思路:以简单的servlet的形式做接口调用测试. bean层以@XMLRootElement注释进行bean与xml的转化. api层用来写具体需要实现的接口类,继承抽象接口类,进行数据库操作,并且返回对象. servlet层用来写每一接口来调用的servlet类. 一个bean对应一个api类对应

java简单的集合框架(一)

首先让我们看一下简单的集合框架的继承层次 collection                   list(有序的容器   元素可以重复)                                                        Queue(队列)                                                  set(无序的容器就是元素不可重复) linkedList        ArrayList   Vector          

使用idea搭建一个简单的SSM框架:(3)配置spring+mybatis

在此之前请先查看: 使用idea搭建一个简单的SSM框架:(1)使用idea创建maven项目 使用idea搭建一个简单的SSM框架:(2)配置springMVC 1 配置spring和mybatis整合文件 spring和mybatis整合分为三个步骤:(1)配置数据库,(2)配置SqlSessionFactoryBean (来自mybatis-spring),(3)配置MapperScannerConfigurer,该配置就我们通过接口定义的方法,就是mybatis的xml对应的namesp

简单实现接口自动化测试(基于python+unittest)

简单实现接口自动化测试(基于python+unittest) 简介 本文通过从Postman获取基本的接口测试Code简单的接口测试入手,一步步调整优化接口调用,以及增加基本的结果判断,讲解Python自带的Unittest框架调用,期望各位可以通过本文对接口自动化测试有一个大致的了解. 引言 为什么要做接口自动化测试? 在当前互联网产品迭代频繁的背景下,回归测试的时间越来越少,很难在每个迭代都对所有功能做完整回归.但接口自动化测试因其实现简单.维护成本低,容易提高覆盖率等特点,越来越受重视.

Facade,怎么可能只是提供简单的接口--

分层是软件解决问题的基本方法....不过仅仅一个分层就算一个设计模式的话...别闹了 栗子:贝爷在奥林匹斯山上抓动物 1.奥林匹斯山上生物的接口 public interface God { public String power(); public String getName(); } 2.奥林匹斯山上的生物 public class Apollo implements God { public String power() { return "乱搞"; } public void