/articles/2019_03_29-python_golang_best_practice.md

https://github.com/jiajunhuang/blog · Markdown · 66 lines · 50 code · 16 blank · 0 comment · 0 complexity · 3ab35243be4f5444249e862cd5548446 MD5 · raw file

  1. # Golang/Python最佳实践
  2. ## 统一好返回格式
  3. - 使用gRPC
  4. - 如果使用RESTful风格那么返回结果无论成功还是失败都应该遵循如下格式
  5. ```js
  6. {
  7. "code": 200, // 业务代码code,可以用于详细错误判断
  8. "msg": "succeed", // 给开发人员看的错误提示
  9. "data": {} // 无论成功或者失败,有无数据,此处都应当返回一个dict/map而不应该是nil/None
  10. }
  11. ```
  12. 为什么要这么做呢因为使用动态语言开发时不会有太大差别使用静态语言时数据类型不一将会导致不好定义返回结果
  13. ## 数据库
  14. - PG比MySQL好用数据类型支持更加丰富坑也更少唯一的缺点是流行程度不如MySQL
  15. - 使用Redis作缓存Redis的数据结构更加丰富而且数据结构可以用作其他用途
  16. ## Python
  17. - gunicorn + gevent异步比asyncio/tornado等更加方便
  18. - [Flask](http://flask.pocoo.org/) 总体来说是一个好用的web框架
  19. - ORM使用 [SQLAlchemy](https://www.sqlalchemy.org/) ,migration使用 [alembic](https://alembic.sqlalchemy.org/en/latest/)
  20. - 参数校验使用 [marshmallow](https://github.com/marshmallow-code/marshmallow)
  21. - 异步任务使用 gevent + python-rqcelery并发一高就容易遇到莫名假死的问题
  22. - 善用decorator例如参数校验时可以写如下代码
  23. ```python
  24. @hello_bp.route("/")
  25. @binding_schemma(HelloworldSchema)
  26. def hello(data):
  27. return "hello world"
  28. ```
  29. `binding_schemma` 的实现如下
  30. ```python
  31. def binding_schemma(schema):
  32. def wrapper(func):
  33. def inner(*args, **kwargs):
  34. # 获取参数
  35. arguments = request.get_json() or request.form or request.args
  36. if arguments is None:
  37. return failed(msg="请检查参数")
  38. # 校验
  39. try:
  40. data = schema().load(arguments)
  41. except ValidationError as err:
  42. return failed(msg=err.messages)
  43. # 执行函数
  44. return func(data.data, *args, **kwargs)
  45. return inner
  46. return wrapper
  47. ```
  48. ## Golang
  49. - Echo比GIN体验上好用一些
  50. - ORM还是pg好用一些此外更喜欢 sqlx + SQLAlchemy + alembic