V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
prasanta
V2EX  ›  Python

基于配置的 API 接口写法设计讨论

  •  
  •   prasanta · Jun 19, 2017 · 3566 views
    This topic created in 3242 days ago, the information mentioned may be changed or developed.

    现在市面上的开源框架, 不管是 tornado, django 或者 flask. 写起 API 总感觉没有 Nodejs 中的 hapijs 框架爽, 根据 hapijs 的设计原理, 我设想了下面的写法. 大家一起来讨论. 基于配置的方法去写接口感觉真的很舒适. 部分代码如下. (框架还没有, 只是设想. )

    app.js

    from api import *
    from .apis.post import post
    from .apis.user import user
    from .plugins.my_plugin import MyPlugin
    
    app = App()
    
    app.plugin(MyPlugin)
    app.plugin(AuthorizationPlugin('jwt'))
    
    app.publish(user)
    app.publish(post)
    
    app.start(port=3000)
    

    user.js

    from api import *
    from .services.user import UserService
    
    user = BluePrint()
    user.role('admin')
    
    
    @user.cache({
        'expires_in': 30 * 1000,
        'privacy': 'private'
    })
    @user.query({
        'name': Field().string()
    })
    @user.role('all')
    @user.get('/')
    def list(self, request):
        users = UserService.list(**request.query)
        return Response(users)
    
    
    @user.cache({
        'expires_in': 30 * 1000,
        'privacy': 'private'
    })
    @user.params({
        'id': Field().string()
    })
    @user.role('login_user')
    @user.get('/{id}')
    def retrieve(self, request):
        user = UserService.retrieve(id=request.params[id])
        return Response(user)
    
    
    @user.payload({
        'name': Field().string()
    })
    @user.role('admin')
    @user.post('/')
    def create(self, request):
        user = UserService.create(request.payload)
        return Response(user)
    
    
    @user.payload({
        'name': Field().string()
    })
    @user.params({
        'id': Field().string()
    })
    @user.role('admin')
    @user.patch('/{id}')
    def update(self, request):
        user = UserService.update(id=request.params[id], payload=request.payload)
        return Response(user)
    
    
    @user.payload({
        'name': Field().string()
    })
    @user.params({
        'id': Field().string()
    })
    @user.role('admin')
    @user.put('/{id}/name')
    def replace_name(self, request):
        user = UserService.update(id=request.params[id], payload=request.payload)
        return Response(user)
    
    
    8 replies    2017-06-30 21:35:43 +08:00
    guyskk
        1
    guyskk  
       Jun 19, 2017 via Android
    Flask 稍微封装一下也可以写出这种效果,待我回去截个图
    zjq426
        2
    zjq426  
       Jun 20, 2017
    araraloren
        3
    araraloren  
       Jun 20, 2017
    ~~ 看不懂,也没个注释 讲解,进来一脸懵逼
    guyskk
        4
    guyskk  
       Jun 20, 2017
    API 写法

    Flask 封装




    这样写还是比较方便的,不过不建议造新框架,生态很重要
    guyskk
        5
    guyskk  
       Jun 20, 2017
    doc_view 里面我用模板生成了 .apib (API Blueprint https://apiblueprint.org/) 格式的文档。
    这些代码没从项目里抽取出来,要做成通用的框架或插件要考虑很多使用场景的问题。我这里约定 全部 POST,全部 JSON,所以省了很多事。
    guyskk
        6
    guyskk  
       Jun 20, 2017
    文档效果
    RaymondLiu
        7
    RaymondLiu  
       Jun 30, 2017 via iPhone
    @guyskk flask-restful 自带函数验证
    guyskk
        8
    guyskk  
       Jun 30, 2017 via Android
    @RaymondLiu 你指的是 RequestParser 吗,感觉有点繁琐,另外它不方便生成文档
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   3449 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 43ms · UTC 00:09 · PVG 08:09 · LAX 17:09 · JFK 20:09
    ♥ Do have faith in what you're doing.