zoukankan      html  css  js  c++  java
  • 简单的接口框架

      日常开发中经常会用到接口,传输都基于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");

    原项目将过几天开源

  • 相关阅读:
    Codeforces Round #657 (Div. 2) 题解
    洛谷 P2765 魔术球问题 (最小路径覆盖 or 贪心)
    洛谷 P2472 蜥蜴 (最大流)
    Codeforces Round #665 (Div. 2) 题解
    洛谷 P1231 教辅的组成 (三分图匹配,裂点)
    USACO5.4 奶牛的电信Telecowmunication (最小割,割边转割点)
    有关网络流的一些板子题
    洛谷 p2756 飞行员配对方案问题(最大流,二分图匹配)
    JSON.toJSONString中序列化空字符串遇到的坑
    关于mysql自动备份的小方法
  • 原文地址:https://www.cnblogs.com/isingel/p/3892717.html
Copyright © 2011-2022 走看看