服务端 API 设计到什么程度算合适 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
请不要在回答技术问题时复制粘贴 AI 生成的内容
Immortal

服务端 API 设计到什么程度算合适

  •  
  •   Immortal
    0x7a7a Feb 13, 2017 7808 views
    This topic created in 3363 days ago, the information mentioned may be changed or developed.

    我是做服务端这块的,主要现在是做 API
    最近工作中碰到一些不是很顺利的情况,不知道是不是我自己想法不对,在我概念里,如果不涉及到安全问题,很多数据展现上的逻辑工作都应该可以放在客户端处理.具体我也不好举例子,现在客户端(主要是 APP)的要求就是要做到他们数据是拿来就用,不用经过任何处理那种(遍历整理数据等操作).宁可增加网络请求,也不太愿意客户端自己处理掉,最好我这边都全部帮他们解决了.
    我是这么想的:
    1\考虑到服务器的负载,所以想把一定计算量放到客户端
    2\考虑到流量,但客户端同事总说现在到处是 wifi,大家流量也很多,这些都是忽略不计的.道理也没错,但这不还有一方面是服务器的带宽么...
    3\考虑到版本迭代,因为如果服务端数据处理到很细节,适用性很低,基本没法复用,一个需求本来是几个基础 api 提供的数据客户端整合处理下能解决的,需要我提供一个新接口,我不是非常乐意.当然如果整合的接口多,逻辑复杂我也愿意处理的,这里指的是很简单的那些. 客户端一个版本逻辑处理写死了,下个版本改了就改了,作为服务端每次改动要考虑到兼容性,所以我不太愿意维护这么多小接口.

    有点罗嗦,也不知道有没有表达清楚意思.就是想问下大家在做 api 的时候是设计到什么尺度? 真要做到客户端拿到数据只需要展示这种程度么?

    Supplement 1    Feb 13, 2017
    看评论想了下
    是不是比较合理的都分的层数比较多:
    1.基础数据层:提供各种最底层的数据,最基础的获取,不会有任何逻辑
    2.数据逻辑层:这个也是服务端做,就是之前争论的 api 做还是客户端做的那些操作,全部放到这一层,向上从基础数据层获取数据,向下对客户端提供数据.
    3.最后才是客户端

    应该很多都大概这么分的吧..
    如果争论问题比较大,以后我想慢慢改成这样
    67 replies    2017-02-15 10:17:47 +08:00
    kulove
        1
    kulove  
       Feb 13, 2017
    客户端能做且数据不重要那就客户端做,流量不用太在意但也不能滥用,接口加版本号
    Immortal
        2
    Immortal  
    OP
       Feb 13, 2017
    @kulove 我大概也是这么个意思 客户端大佬们觉得 数据处理这种事情就不应该放在客户端做 这个问题每次都能争好久 接口加版本号这个懂的 想问下 你那对于每个版本的接口路由分发 做在了 web 服务器那层(比如 nginx) 还是项目的路由里 我不知道做哪里和是 我这边用 golang 写的
    dangyuluo
        3
    dangyuluo  
       Feb 13, 2017
    大家都在推诿,做客户端的肯定想偷懒啦。
    minbaby
        4
    minbaby  
       Feb 13, 2017
    @Immortal 哈哈,这个问题我遇到过,客户端的同学特别“拗”,能让我( API )做的都让我做,恨不得我把所有工作都做了,为了一个东西能争论很久(有这个时间早做完了),目的是让我明白我的思路是错的。恩,就这样,结果是我还在这家公司。
    Immortal
        5
    Immortal  
    OP
       Feb 13, 2017
    @dangyuluo 的确有这个问题...有时候我在表达我的想法,客户端大佬们觉得我想偷懒,少写点代码...我是觉得应该做的都会去做不会推卸,不应该做(意思是不应该放在服务器处理的)就不是很乐意做,不过最后都会妥协..因为项目组 ios+安卓有 2 个大佬,而服务端就我一个小弟,百口莫辩啊
    Immortal
        6
    Immortal  
    OP
       Feb 13, 2017
    @minbaby ...我现在正在遇到这个问题,大佬们心情好点就少说我两句,帮我分担点,一般都是我这边都处理掉了
    ytmsdy
        7
    ytmsdy  
       Feb 13, 2017
    1:无关紧要的计算放在客户端,服务器的计算量能省一点是一点。如果客户量大,省下来的计算量也是很客观的
    2 :流量,先保证 app 正确可用,闲着无聊可以做流量的优化。
    3 :具体情况具体分析,如果都是 get 的请求。如果返回的数据包大,那就让客户端分多次来,数据包小那就你整理一下一个 API 返回。如果是 post ,或者是 put , delete 涉及到数据操作的,最好在一个 api 里面做完,要不然网络中断什么的,出现脏数据是很讨厌的。

    按照你的说法,客户端的同事只是想省力一点而已。
    helloccav
        8
    helloccav  
       Feb 13, 2017 via Android
    我也遇到这个问题,对了,我是那个客户端
    Immortal
        9
    Immortal  
    OP
       Feb 13, 2017
    @ytmsdy 对于 1,可能我自己太理想话了,想把性能上的问题在开发时候能考虑到的顺手都做了,客户端的意思是现在不用考虑这么多,等流量大了服务器啥的就多了,说不定客户端代码都重写了云云,我不知道怎么说服,三观不是很和. 2 我同意你说的,我思路主要和 1 一样,开发时候想到的想顺手做,这个优化的确可以滞后. 3 明白你的意思,对于事务操作肯定是放一个 api 处理了,这边主要是指的 get,数据整合类的逻辑,有时候需求数据可以从几个基础 API 获取自己整合,客户端不是很乐意

    我也就吐槽下,他们想省力我也不是很有办法说服他们多写代码...
    Immortal
        10
    Immortal  
    OP
       Feb 13, 2017
    @helloccav 可以说下你们客户端的想法...我看看我们逻辑差在哪里
    rockyou12
        11
    rockyou12  
       Feb 13, 2017
    还是看业务吧, app 重新发布需要用户自己更新,不像 web 这么方便,很多业务要变的话放 app 里面很不方便。除此我觉得 app 多请求几次去处理没什么问题
    Immortal
        12
    Immortal  
    OP
       Feb 13, 2017
    @rockyou12 主要不是在业务逻辑上,业务逻辑因为很多涉及到安全问题,基本都放服务端了,很多问题是在展现逻辑上,这个数据要帮他们整理好,这个数据帮他们拼接好等等,但是其实是可以从 A 接口和 B 接口里获取自己整合,现在需要给他们新写一个 C 接口,我就不太愿意,一个是增加维护成本,一个就是没复用性
    helloccav
        13
    helloccav  
       Feb 13, 2017 via Android
    @Immortal 我们客户端的想法就是和你题目里面那个客户端的想法一样,想要服务器端处理好各种计算,客户端只负责直接展示。在我们这个项目里服务器端的工程师自己就是这样设计的,不用客户端的工程师去提要求。
    我们项目里面,服务器端和客户端的工程师的关系还是挺好的,不会为了这个吵架。
    Exin
        14
    Exin  
       Feb 13, 2017 via iPhone
    这种事需要一个统管前后端的上级来做决定,
    因为两边都可以做、都有理,争论难休
    helloccav
        15
    helloccav  
       Feb 13, 2017
    @Immortal 我自己在有些项目里开发客户端,有些项目里开发服务器端。对于一个展示要同时读 A 接口和 B 接口然后组合数据这样的情况,我们一般都是要求服务器端整合成一个 C 接口提供数据,主要原因是减少网络请求。
    我们的要求是:
    1 、尽量减少网络请求
    2 、后期业务的调整尽量通过服务器端实现,客户端不修改。所以我们把尽可能多的计算和逻辑放在服务器端口实现。例如某个预订的总价是商品价格+服务费,这个总价的计算 就放在服务器端而不是客户端,这样以后想去掉服务费可以只改服务器,不用改客户端,免得客户端要重新上架(这个例子可能举得不太对,但我一时找不到更好的例子。)。
    learnshare
        16
    learnshare  
       Feb 13, 2017
    客户端来做无关紧要的处理比较合适。服务端的 API 应该定位成可以服务于多种客户端的( Android/iOS/Web 等),不是以某个客户端为主。

    But 真的要分析具体问题,最好是有一个独立的 API 方案或者方法,服务端和客户端都按文档来,彼此不关心实现。
    xiaoyangsa
        17
    xiaoyangsa  
       Feb 13, 2017
    能后台处理就后台处理吧。前台永远给他们做展示好了。
    这就想 mvc 里面的 view 层一样,只做数据展示就行。
    以后要换客户端的人就会简单得多。
    要加入一个新的客户端平台也会很方便。
    nanlong
        18
    nanlong  
       Feb 13, 2017
    1, 流量必然要考虑,必定会碰到没有 wifi 的情况,优化流量也能提高项目整体性能,何乐不为。
    2, GraphQL 解决了数据组合、复用的问题。
    3, 写客户端也是程序员啊,该干的、能干的不可以推诿,别给程序员丢脸。一些处理放在客户端必然能缓解后端服务器的压力,凭啥不做。
    rockyou12
        19
    rockyou12  
       Feb 13, 2017
    不涉及业务那你给他们写什么,难道界面改了你后台还要改?这不增加大家工作量嘛
    ideascf
        20
    ideascf  
       Feb 13, 2017
    观点: 后台提供的 api 应该是面向数据的,而不是面向页面的。 面向页面的接口,一旦页面发生变动, api 就要发生对应的调整。 而且这样的接口也不够通用,会导致很多割裂的接口,这不是一个好的现象。
    方案: 如果大佬讲理由讲不通,那也只得按他们的来咯。 但是你可以考虑增加一个 API gateway , 由这个 api gateway 完成面向页面的 api 封装,向后调用面向数据的 api 。 如果前端后 node.js 的话,直接丢给他们做。
    ideascf
        21
    ideascf  
       Feb 13, 2017
    补充一个连接: [微服务实战(二):使用 API Gateway]( http://dockone.io/article/482) 或许有些帮助。
    helloccav
        22
    helloccav  
       Feb 13, 2017 via Android
    @ideascf 如果 api 面向而不是面向页面,那么一个页面由很多部分组成,那就要调用好几个接口,这就大大增加了网络请求的负担。在我们的项目里面, api 都是面向页面的,一个页面尽量只请求一次 /一个 api
    hwiiago
        23
    hwiiago  
       Feb 13, 2017
    没有业务场景单纯谈该放哪边来计算是没有意义的。
    wizardoz
        24
    wizardoz  
       Feb 13, 2017
    不考虑用户的流量,我觉得是很作死的行为。
    要是用户哪天打开流量统计,发现你的 app 是流量大户,说不定就卸载了。
    Immortal
        25
    Immortal  
    OP
       Feb 13, 2017
    @Exin 是的 的确有发现这个问题 扁平化管理的缺陷
    Immortal
        26
    Immortal  
    OP
       Feb 13, 2017
    @helloccav 明白你的意思了 这种会影响业务逻辑的改动 的确需要考虑进去 学习了
    Immortal
        27
    Immortal  
    OP
       Feb 13, 2017
    @ideascf 很同意你的说法 应该面向数据而不是页面, 做着做着就做到页面的误区了.回头想了下,主要应该是一般开发没文档,都是看着页面+口头问需求的原因...
    Immortal
        28
    Immortal  
    OP
       Feb 13, 2017
    @wizardoz 会有这个可能,主要用户量不上来,很多问题不愿意也可能都想不到,光凭嘴巴说服不了很尴尬
    ystop
        29
    ystop  
       Feb 13, 2017
    我觉得 一般情况下 这些逻辑是要放在后台做的。 因为 APP 发版的成本很高,而且客户端过多的接口业务反而会导致项目复杂度的提高,平时有什么 BUG,问题的,兼容的 后台直接改就好了,非常方便。 对于通用性,我觉得底层的服务代码肯定是通用的,不同的端确实是需要不同的接口的,需要加个 api 层完成面向页面的 api 封装.
    Immortal
        30
    Immortal  
    OP
       Feb 13, 2017
    @helloccav 这个问题感觉又很难完全有个标准.按页面有按页面的好处,按数据也是.前者连接数是会少,后者更加灵活和容易维护.扯到最后又要扯到具体需求了,不过这种我觉得可以灵活的定,但是可以有一个侧重面
    crashX
        31
    crashX  
       Feb 13, 2017
    看你后台有几层了,如果你是中间层对接客户端应该做,如果是底层需要对接所有端那应该给客户端做。
    susucoolsama
        32
    susucoolsama  
       Feb 13, 2017
    感觉 APP 还是面向页面写接口好啊,面向数据很蠢的,虽然通用性好,但是架不住一个页面请求好几次接口,逻辑也写在 APP 里,网络请求负担很大。
    ideascf
        33
    ideascf  
       Feb 13, 2017
    @helloccav 是的,如果有多个模块,就请求多个 api ,我们目前就是按照这样的方式处理。 这样 api 在很大程度上能得到复用,这更有利于 api 维护管理。 如果全部面向页面来做 api ,我认为越往后走, api 维护以及代码维护的成本就会越来越高。 当然,这样肯定就会面临多次网络 io 的开销,但我认为在目前 4G 流行的场景这不是一个大问题。 而且如果发现这块真的是一个短板,那么可以考虑加入 API gateway 。
    ideascf
        34
    ideascf  
       Feb 13, 2017
    @Immortal 要立字据啊
    Immortal
        35
    Immortal  
    OP
       Feb 13, 2017
    @crashX 刚好想到这个问题,应该问题也在我分层不是很清晰.前期规划的问题.对于这个事情上我自己看来问题也很大,准备慢慢解藕
    Immortal
        36
    Immortal  
    OP
       Feb 13, 2017
    @ideascf 唉 工作环境没这么理想化呢,我也想有个文档,写代码的时候只要动手动眼别动口.没办法
    jiangzhuo
        37
    jiangzhuo  
       Feb 13, 2017
    我给你讲个不是笑话的笑话曾经有款手游,战斗动画都是服务端渲染然后以流媒体的形式传回给客户端的。
    TangMonk
        38
    TangMonk  
       eb 13, 2017
    @kulove 版本号这个我觉得不是很必要,如果有大版本变动,数据结构就会有不同。如果两个版本使用同一个数据库,那么数据就会错乱的。

    如果确实需要兼容老版本接口的话,还要单独做数据兼容处理。
    TangMonk
        39
    TangMonk  
       Feb 13, 2017
    @TangMonk 如果是类似 AWS 那种给开发者提供接口的话,就有必要加上版本号。 如果是普通的应用场景,版本号不是很必要。
    kulove
        40
    kulove  
       Feb 13, 2017
    @TangMonk #38 如果不传版本号的话就确定不了版本,如果是改变接口地址还不如传版本号方便,设计兼容新老版本的 API 我觉得是很有必要的,没有那个 APP 发布大版本后之前的版本就不能用的例子吧
    kaka8wp
        41
    kaka8wp  
       Feb 13, 2017
    对于给 app 的接口,工作上遇到的就是客户端同事觉得最好接口面向页面,不希望一个页面调用几次接口,我感觉是不是可以在服务端还是按照面向数据来做接口,给 app 包装出来一个调用多个面向数据的面向页面的接口。后面更新维护也稍微好弄点
    TangMonk
        42
    TangMonk  
       Feb 13, 2017
    @kulove

    有时候兼容起来很困难,不得不再开一个数据库。
    如果是普通 app 的话,我觉得不如直接强制更新了。
    对于已经有大量的老用户的话,还是得做兼容。

    http://stackoverflow.com/questions/389169/best-practices-for-api-versioning
    Eoss
        43
    Eoss  
       Feb 13, 2017 via iPhone
    @jiangzhuo 说的是炉石吧。
    Immortal
        44
    Immortal  
    OP
       Feb 13, 2017
    @kaka8wp 比如我附加的说明?你看下是不是这个意思
    kulove
        45
    kulove  
       Feb 13, 2017
    @TangMonk #42 兼容确实是问题,如果是企业内部使用倒还可以强制更新,如果对象是大众还真要仔细考虑考虑,能兼容尽量兼容
    kaka8wp
        46
    kaka8wp  
       Feb 13, 2017
    @Immortal 对的~我觉得这个挺合理的,后续维护的话对于 app 页面调整这种,只要修改那一个有数据逻辑的接口就好,而且减少影响其他引用相同的面向数据接口的地方。
    工作中几个项目都是轻量化客户端,基本上都是数据显示不做任何处理~我这样做之后同事关系明显好了~就是一有问题不管怎么样都先说是后端返回的数据问题。哈哈
    Limius
        47
    Limius  
       Feb 13, 2017
    作为 PM 我跟技术团队完成项目时也遇到过这种事,你考虑到的是性能的问题,实际上我考虑到的是如果由服务端提供 API ,客户端只做展示功能,业务抗错能力会比较强,数据计算逻辑写死在客户端,如果上线后发现需要调整,这时你只能通过更新客户端版本来修正数据展示,而 appstore 的上线审批需要几天时间,对于我们 PM 来说这几天基本是不可忍受的,特别是互金行业,涉及到金额数据的展示这种是致命的,所以宁愿计算逻辑由服务端完成,毕竟随时可改,这是我从产品角度的一些看法,供你参考。
    Limius
        48
    Limius  
       Feb 13, 2017
    @TangMonk 这个链接很好的回答了嘛
    learnshare
        49
    learnshare  
       Feb 13, 2017 via Android
    补充里的三层是合理的,不过一般项目都前两层合并到一起了。甚至划分不清楚,数据和业务逻辑部分融合到一起了,难以维护。

    实在有必要,就另搞一层后端,专门服务客户端。
    bombless
        50
    bombless  
       Feb 13, 2017
    我们这边倾向于尽可能让服务器端做。
    其实我挺同意的,我们做 app 的让客户端节省点电量让手机续航更长一点挺好的。
    我自己是负责服务端这边的。
    Immortal
        51
    Immortal  
    OP
       Feb 13, 2017
    @Limius 嗯 这个问题之前没有很重视 的确很重要
    Immortal
        52
    Immortal  
    OP
       Feb 13, 2017
    @learnshare 是的 现在我就是只有两层 想慢慢分出来 被坑到了..
    renshaojuncool
        53
    renshaojuncool  
       Feb 13, 2017
    我感觉应该看具体情况吧,我是做 iOS 的,一般数据处理是很希望放在服务端来做的,客户端在渲染页面之前,对请求到的数据做过度的处理,会造成反应缓慢,卡顿的感觉(当然也可以进行一些优化,做预处理),但是考虑到 APP 健壮性,还是放在服务端处理比较好,这样造成的结果就是,如果线上出现了某个问题,我会先查是否是自己的问题或者是数据返回的问题,一般后台背锅就比较多了(虽然客户端已经做了比较多的安全处理,但是某些数据还是不可避免的会发生),这种情况下,后台直接修改代码或数据,就可以立马结局,而如果放在客户端,就 iOS 而言,审核就够难受的了
    Limius
        54
    Limius  
       Feb 13, 2017
    @renshaojuncool 我上面回答的正是这个意思~
    sampeng
        55
    sampeng  
       Feb 13, 2017
    设计到自己懒得去实现为止。就是设计 api 总有个一界限。过了界限,自己就要加班去实现。。。我个人觉得不用想太多,以加班为平衡点来是最实际的。什么?扩展性,放心好了。其他人看别人的 api 设计都是一坨屎
    Alucns
        56
    Alucns  
       Feb 13, 2017 via iPhone
    能 App 本地处理的,就不需要去向服务器请求;
    CFM880
        57
    CFM880  
       Feb 13, 2017
    现在每次穿过的数据都要遍历一遍。。。。。
    zwhu
        58
    zwhu  
       Feb 13, 2017
    也许你们想要的是 graphql
    bigdogbigpig
        59
    bigdogbigpig  
    PRO
       Feb 14, 2017
    写 app 应该也是有成熟的体系了,如果 app 是核心业务的话后台只是处理器而已, dirty work 自然多。

    这里和 app 的性质其实有很大的关系,如果涉及较多的交互那无可厚非数据得干净,如果更多的动态变化的展示那就自己处理数据。
    Chyroc
        60
    Chyroc  
       Feb 14, 2017 via iPhone
    试试 graphql
    lovebirdegg
        61
    lovebirdegg  
       Feb 14, 2017
    逻辑处理放在服务端比较好,放在客户端维护起来太不方便了。
    wupher
        62
    wupher  
       Feb 14, 2017
    一般而言,数据和逻辑是放到服务端,展示层是客户端的事,这是大原则。

    在可能的基础上,尽量提高接口的友好程度,方便客户端拿到数据后能方便处理,这是原则 2 。

    流量是肯定要考虑的,我自己也做 iOS 客户端,他这么说肯定是瞎扯。现在弱网络,如地铁,火车、汽车等情况其实相较以前更常见了。本地在可能的情况下,都是要做 cache 的。

    理由 3 ,我倒觉得未必成立。其实,数据实际传输的时间消耗不一定高,往往是链接建立的耗时更高。所以一般建议,尽量一个请求搞定数据,而不要让客户端连续调用多个 http 请求来为一个界面加载数据。如果服务端只是将几个 http 请求包起来,统一做个门面,其实这事也不难。比客户端回调套回调好处理多了。
    adoyle
        63
    adoyle  
       Feb 14, 2017   1
    只能协商。逻辑放在客户端或者服务端 (gateway) 里实现并没有绝对的定论,因为这都包含了业务逻辑。以固有逻辑来定论我觉得都是错误的,要根据具体场景、团队、业务逻辑来判断放哪实现**最为合适**。业务逻辑是难以根据平台区分的。协商会有几点考虑因素:

    1. 安全性。有些数据只能在服务端计算。
    2. 性能开销。根据不同场景,可以放在客户端,也可以放在服务端。
    3. 可复用性。业务逻辑实现在客户端,就难以复用了;但实现在服务端,又要考虑通用性。
    4. 人为因素。观点争执不下,沟通成本太高等等。

    我觉得解决这个问题的最好办法,不是讨论这块逻辑究竟该放哪里。因为每个新 feature 都得讨论一遍接口,会非常麻烦。
    而是应该由一个人去负责一个 feature 的完成,由同一个人完成前后端的代码,即所谓的全栈。这样的好处在于:

    1. 避免沟通交流上的争执。在编程领域,一个人干活往往比两个人效率更高。
    2. 只有经历过同样的场景,才会换位思考,知道对方的难点,才会互相体谅。
    3. 当一个人去实现,因为放哪做都是自己做,才更有可能去思考代码结构,真正考虑业务逻辑放哪实现**最为合适**。
    4. 当一个人去跨端,会培养全局意识,对于技术发展也是有好处的。

    你可能会觉得让前端来学服务端难度太大。这是有前提的,前提是你的项目架构要清晰可维护,新手进来能快速上手,当项目可维护性做得很好,有很好的结构,那么入门门槛就只在于语言了。对于学一门新语言,对稍微有点经验的开发者来说不算难事吧。待对方实现好代码后,你可以参与 code review ,把控项目质量。
    barbery
        64
    barbery  
       Feb 14, 2017
    理论上,我觉得服务器的接口是尽可能的考虑到通用性,返回基础数据,由客户端根据自己的业务需要来自行处理然后渲染出来。这个在 web 端一直没什么问题,但是自从 IOS 和 Android 出来后情况又不一样了,考虑到发包的成本,基本上服务端都要包揽了所有的数据处理的逻辑,这么搞可以理解,但是如果出现不同的平台同一个页面不同的功能设计就很尴尬了,为了不同平台的处理逻辑,又要拆分出一个接口~
    orvice
        65
    orvice  
       Feb 14, 2017
    大部分情况下都是因为客户端懒吧。。。
    Immortal
        66
    Immortal  
    OP
       Feb 15, 2017
    @orvice 看大家评论,也不完全是懒,也有很多无奈的地方.app 和 web 还是不太一样,ios 要过审什么的所以很多只能放服务端
    orvice
        67
    orvice  
       Feb 15, 2017
    @Immortal 过审核我们是添加一个配置项目, ios 取到以后再 client 端关掉相关功能
    About     Help     Advertise     Blog     API     FAQ     Solana     1216 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 171ms UTC 17:31 PVG 01:31 LAX 10:31 JFK 13:31
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86