您身边的网站建设专家
成功案例

【建站服务】永兴网站制作【永兴网站优化】永兴建网站、永兴微信公众号运营、永兴网页设计、永兴微信小程序商城-域名申请

日期: 2022-09-20 13:23:17 浏览数:7


上往建站提供服务器空间服务商百度快照排名网站托管百度推广运营,致力于设计外包服务与源代码定制开发360推广搜狗推广,增加网站的能见度及访问量提升网络营销的效果,主营:网站公司,百度推广公司电话,官网搭建服务,网站服务企业排名,服务器空间,英文域名等业务,专业团队服务,效果好。


永兴网站制作【永兴网站优化】永兴建网站、永兴微信公众号运营、永兴网页设计、永兴微信小程序商城

永兴县是郴州市下辖县,地处湖南省东南部、郴州市北陲,东邻资兴市,南连苏仙区,西靠桂阳县,北接安仁县及衡阳市耒阳,辖10镇4乡2街道办事处,总人口71.1万人(常住54.4万人),是郴州市人口第二大县,国家“城市矿产”示范基地。 [1] 

地域狭长貌似蚕形,东西长90公里,南北宽56公里。全县土地总面积为1979.4平方公里,占湖南省土地总面积的0.93%,东部多山,西部以丘陵为主,中部丘岗平原间布,京广铁路、京珠高速公路、国道G107、省道S212纵横境内,耒水上游的便江四季通航。

2020年7月,全国爱卫会决定命名永兴县为2017-2019周期国家卫生县城。

2.3.2 会讲故事的Api接口层

在2015年大会上,我所敬仰的偶像Martin Fowler,通过下面这张Slice再次分享了何为微服务。

图2-2 Martin Fowler对微服务的定义

图2-2 Martin Fowler对微服务的定义

这里提到的微服务概念,对应PhalApi框架中的接口服务,主要体现在Api接口服务层。微服务与接口服务有些微妙的区别,但不管何种说法,我们都应该关注微服务里所提及到的这几点重要特质:

Api接口服务层,主要是负责响应客户端的请求,在抽象层面进行决策并对领域层进行调度,最后返回相应的结果。

接口服务的定义

在实际项目开发过程中,绝大部分我们编写的接口服气都是提供给别的开发工程师使用的,包括但不限于客户端开发人员,前端开发人员和其他后端系统开发人员。为了提高并行开发的速度,我们不能等到接口服务开发完成后才提供相应接口文档,而应尽早提供具体描述了接口服务定义的接口文档。

所以,使用接口服务的开发人员时常会问:什么时候可以提供接口文档?

我们提倡“接口先行”,即接口服务应该在使用方使用前就完成开发并通过自测,但往往在多任务、多项目并行的情况下很难百分百做到这一点,毕竟多变的需求促发多变的情境。此时,我们可以快速提供接口服务的定义。

接口服务的定义,是指声明接口服务的函数签名,并对接口服务的功能、接口参数和返回结果进行相应说明。在设计模式中,其中一个很重要的原则是:“针对接口编程,而不是针对实现编程”。我们在这里定义的接口服务,也正是很好体现了这一点。一开始通过关注客户端业务场景需要的视角,在规约层面定义好接口服务的功能,以及相关的签名、参数和返回结果,而不过多对实现的细节作深入地展开。

在PhalApi中定义一个接口服务,具体过程为:

下面以在Shop商城项目中添加获取商品快照信息服务为例,进行讲解。

假设此获取商品快照信息服务名称为:Goods.Snapshot,则先在Shop项目的Api层创建一个新的类文件并添加一个继承自PhalApi_Api的接口服务类Api_Goods,然后添加一个成员函数Api_Goods::snapshot()

//$ vim ./Shop/Api/Goods.php<?phpclass Api_Goods extends PhalApi_Api {

    public function snapshot() {
    }}复制代码

接口服务的功能,可以在成员函数的标准文档注释中进行说明,并且可使用@desc注解进行详细说明。如下:

    /**
     * 获取商品快照信息
     * @desc 获取商品基本和常用的信息
     */
    public function snapshot() {
    }复制代码

参数规则的配置,则是前面所说的接口参数规则配置,需要在Api_Goods::getRules()成员函数中进行配置,假设这里只需要一个商品ID的参数。

    public function getRules() {
        return array(
            'snapshot' => array(
                'id' => array('name' => 'id', 'require' => true, 'type' => 'int', 'min' => 1, 'desc' => '商品ID'),
            ),
        );
    }复制代码

最后,需要对接口返回的结果结构及字段进行说明,这部分也是在成员函数的标准文档注释中进行说明,并遵循@return注解的格式。假设此快照服务返回的结构格式和字段如下:

    /**
     * 获取商品快照信息
     * @return int      goods_id    商品ID
     * @return string   goods_name  商品名称 
     * @return int      goods_price 商品价格
     * @return string   goods_image 商品图片
     */
    public function snapshot() {
    }复制代码

至此,我们便完成了获取商品快照信息服务的雏形,即完成了对此接口服务的定义。简单尝试请求一下:

$ curl "http://api.phalapi.net/shop/?service=Goods.Snapshot&id=1"{"ret":200,"data":null,"msg":""}复制代码

可以看到上面定义的接口服务已经可以访问。因为还没具体实现,所以暂时没有业务数据返回。

那我们是要把这个接口服务链接提供给使用方吗?是,但不全面。我们最终要提供给使用方的是在线接口服务说明文档。请注意,在完成上面这4个步骤后,我们将会看到一份很酷、很实用、并且是自动实时生成的在线接口服务说明文档。

请在浏览器,打开以下链接并访问。

http://api.phalapi.net/shop/checkApiParams.php?service=Goods.Snapshot复制代码

可以看到类似这样的截图效果。

图像说明文字

图2-3 接口服务Goods.Snapshot的在线说明文档

由前面创建的类和编写的代码、配置的规则以及文档注释,最终生成了这份接口文档。即使在未完成接口服务的开发情况下,通过此在线文档,使用方也能明确接口服务的功能,以及需要传递的参数和返回结果的说明,从而不影响他们的开发进度。

温馨提示:这里省略了公共参数中的签名参数和版本参数。关于在线文档的使用,后续会再进行详细说明。

在TDD下讲故事

在完成了接口服务定义后,可以说,我们为讲述故事铺垫好了背景,部署好了场景上下文。接下来,我们推荐遵循测试驱动开发的理念,在意图导向编程的引导下继续完成故事的讲述。主要的方向是,为了验证业务场景的正确性,应该先编写不断引导我们前往正确目的地的单元测试,再开始编写具体的代码。

继续上面的获取商品快照信息接口服务,我们可以使用PhalApi提供的脚本命令快速生成测试骨架。其用法如下:

$ cd ./Shop/Tests$ php ../../PhalApi/phalapi-buildtest ../Api/Goods.php Api_Goods ./test_env.php > ./Api/Goods_Test.php复制代码

温馨提示:关于phalapi-buildtest脚本命令的使用,详细请见3.5.2 phalapi-buildtest命令

上面主要是生成了Goods.Snapshot接口服务对应的测试骨架代码,并保存在文件./Api/Goods_Test.php里。然后,稍微修改完善生成的测试代码。

// $ vim ./Shop/Tests/Api/Goods_Test.phprequire_once dirname(__FILE__) . '/../test_env.php'; // 调整测试环境文件的加载... ...

    public function testSnapshot()
    {
        // Step 1. 构建请求URL
        $url = 'service=Goods.Snapshot';
        $params = array(
            'id' => 1,
        );

        // Step 2. 执行请求
        $rs = PhalApi_Helper_TestRunner::go($url, $params);
        //var_dump($rs);

        //Step 3. 验证
        $this->assertNotEmpty($rs);
        $this->assertArrayHasKey('goods_id', $rs);
        $this->assertArrayHasKey('goods_name', $rs);
        $this->assertArrayHasKey('goods_price', $rs);
        $this->assertArrayHasKey('goods_image', $rs);
    }复制代码

上面的单元测试,根据构建-执行-验证模式,对商品ID为1的信息进行验证,主要是验证是否包含goods_id、goods_name、goods_price、goods_image这四个字段。

试执行一下此单元测试,明显是失败的。

Tests$ phpunit ./Api/Goods_Test.php 

.FThere was 1 failure:1) PhpUnderControl_ApiGoods_Test::testSnapshotFailed asserting that a NULL is not empty./path/to/Shop/Tests/Api/Goods_Test.php:56复制代码

温馨提示:PHPUnit的安装请参考安装 PHPUnit 。

到这里,我们讲述了一个失败的故事,因为这个故事讲不下去了。但我们知道错在哪里。要想让这个故事讲得通,我们可以先简单模拟一些数据,即先讲一个假故事。

修改Goods.Snapshot接口服务的源代码,返回以下模拟的商品数据。

// $ vim ./Shop/Api/Goods.php
    public function snapshot() {
        return array(
            'goods_id' => 1,
            'goods_name' => 'iPhone 7 Plus',
            'goods_price' => 6680,
            'goods_image' => '/images/iphone_7_plus.jpg',
        );
    }复制代码

此时,再运行单元测试,是可以通过的了。到这一步,虽然我们最终尚未实现接口服务的开发,但已经是非常 接近了。因为我们已经提供了在线接口说明文档给使用方,现在又可以有一份模拟的接口返回数据,虽然是假的。而这些文档和模拟数据,都已经可以帮忙客户端完成主流程的业务功能开发。

接下来,让我们再进一步,把这个故事讲得更真实,更动听,更丰满一点。

还记得我们Api层的职责吗?Api层主要负责请求响应、进行决策和高层的调度。下面是Goods接口层调整后的代码实现:

// $ vim ./Shop/Api/Goods.php
    public function snapshot() {     
        $domain = new Domain_Goods();
        $info = $domain->snapshot($this->id);
        return $info;
    }复制代码

即根据客户端传递的商品ID,把具体的快照信息提取委托给领域业务层Domain_Goods进行,最后返回结果给客户端。

那么什么是领域业务层呢?


永兴网站制作永兴网站优化永兴建网站、永兴微信公众号运营、永兴网页设计、永兴微信小程序商城


上往建站提供搭建网站域名注册官网备案服务网店详情页设计企业网店专业网络店铺管理运营全托管公司咨询电话,服务器空间,微信公众号托管网页美工排版,致力于域名申请竞价托管软文推广全网营销,提供标准级专业技术保障,了却后顾之忧,主营:虚拟主机网站推广百度竞价托管网站建设上网建站推广服务网络公司有哪些等业务,专业团队服务,效果好。

服务热线:400-111-6878 手机微信同号:18118153152(各城市商务人员可上门服务)


全国咨询热线:400-111-6878

地址:全国各地都有驻点商务

Copyright © 2021 通陆科技

网站建设上往建站