技术控

    今日:2| 主题:49195
收藏本版 (1)
最新软件应用技术尽在掌握

[其他] Building RESTful APIs With Flask: The DIY Approach

[复制链接]
不忘初心 发表于 2016-10-5 18:57:58
75 2

立即注册CoLaBug.com会员,免费获得投稿人的专业资料,享用更多功能,玩转个人品牌!

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
REpresentational State Transfer (REST)    is a web development architecture design style which refers to logically separating your API resources so as to enable easy access, manipulation and scaling. Reusable components are written in a way so that they can be easily managed via simple and intuitive HTTP requests which can be GET, POST, PUT, PATCH, and DELETE (there can be more, but above are the most commonly used ones).  
  Despite what it looks like, REST does not command a protocol or a standard. It just sets a software architectural style for writing web applications and APIs, and results in simplification of the interfaces within and outside the application. Web service APIs which are written so as to follow the REST principles, they are called RESTful APIs.  
  In this three-part tutorial series, I will cover different ways in which RESTful APIs can be created using    Flaskas a web framework. In the first part, I will cover how to create class-based REST APIs which are more like DIY (Do it yourself), i.e. implementing them all by yourself without using any third-party extensions. In the latter parts of this series, I will cover how to leverage various Flask extensions to build more effective REST APIs in an easier way.  
  I assume that you have a basic understanding of Flask and environment setup best practices using    virtualenvto be followed while developing a Python application.  
  Installing Dependencies

  The following packages need to installed for the application that we'll be developing.
  1. $ pip install flask
  2. $ pip install flask-sqlalchemy
复制代码
The above commands should install all the required packages that are needed for this application to work.  
  The Flask Application

  For this tutorial, I will create a small application in which I will create a trivial model for    Product. Then I will demonstrate how we can write a RESTful API for the same. Below is the structure of the application.  
  1. flask_app/
  2.     my_app/
  3.         - __init__.py
  4.         product/
  5.             - __init__.py      // Empty file
  6.             - models.py
  7.             - views.py
  8.     - run.py
复制代码
I won't be creating a front-end for this application as RESTful APIs endpoints can be tested directly by making HTTP calls using various other methods.
  flask_app/my_app/__init__.py  

  1. from flask import Flask
  2. from flask.ext.sqlalchemy import SQLAlchemy

  3. app = Flask(__name__)
  4. app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.db'
  5. db = SQLAlchemy(app)

  6. from my_app.catalog.views import catalog
  7. app.register_blueprint(catalog)

  8. db.create_all()
复制代码
In the file above, the application has been configured with the initialisation of the extensions and finally creation of the database. The last statement creates a new database at the location provided against    SQLALCHEMY_DATABASE_URIif a database does not already exist at that location, otherwise it loads the application with the same database.  
  flask_app/my_app/catalog/models.py  

  1. from my_app import db

  2. class Product(db.Model):
  3.     id = db.Column(db.Integer, primary_key=True)
  4.     name = db.Column(db.String(255))
  5.     price = db.Column(db.Float(asdecimal=True))

  6.     def __init__(self, name, price):
  7.         self.name = name
  8.         self.price = price

  9.     def __repr__(self):
  10.         return '<Product %d>' % self.id
复制代码
In the file above, I have created a very trivial model for storing the name and price of a    Product. This will create a table in    SQLitecorresponding to the details provided in the model.  
  flask_app/my_app/catalog/views.py  

  1. import json
  2. from flask import request, jsonify, Blueprint, abort
  3. from flask.views import MethodView
  4. from my_app import db, app
  5. from my_app.catalog.models import Product

  6. catalog = Blueprint('catalog', __name__)

  7. @catalog.route('/')
  8. @catalog.route('/home')
  9. def home():
  10.     return "Welcome to the Catalog Home."


  11. class ProductView(MethodView):

  12.     def get(self, id=None, page=1):
  13.         if not id:
  14.             products = Product.query.paginate(page, 10).items
  15.             res = {}
  16.             for product in products:
  17.                 res[product.id] = {
  18.                     'name': product.name,
  19.                     'price': str(product.price),
  20.                 }
  21.         else:
  22.             product = Product.query.filter_by(id=id).first()
  23.             if not product:
  24.                 abort(404)
  25.             res = {
  26.                 'name': product.name,
  27.                 'price': str(product.price),
  28.             }
  29.         return jsonify(res)

  30.     def post(self):
  31.         name = request.form.get('name')
  32.         price = request.form.get('price')
  33.         product = Product(name, price)
  34.         db.session.add(product)
  35.         db.session.commit()
  36.         return jsonify({product.id: {
  37.             'name': product.name,
  38.             'price': str(product.price),
  39.         }})

  40.     def put(self, id):
  41.         # Update the record for the provided id
  42.         # with the details provided.
  43.         return

  44.     def delete(self, id):
  45.         # Delete the record for the provided id.
  46.         return


  47. product_view =  ProductView.as_view('product_view')
  48. app.add_url_rule(
  49.     '/product/', view_func=product_view, methods=['GET', 'POST']
  50. )
  51. app.add_url_rule(
  52.     '/product/<int:id>', view_func=product_view, methods=['GET']
  53. )
复制代码
The major crux of this tutorial is dealt with in the file above. Flask provides a utility called    pluggable views, which allows you to create views in the form of classes instead of normally as functions. Method-based dispatching (    MethodView) is an implementation of pluggable views which allows you to write methods corresponding to the HTTP methods in lower case. In the example above, I have written methods    get()and    post()corresponding to HTTP's    GETand    POSTrespectively.  
  Routing is also implemented in a different manner, in the last few lines of the above file. We can specify the methods that will be supported by any particular rule. Any other HTTP call would be met by    Error 405 Method not allowed.  
  Running the Application

  To run the application, execute the script    run.py. The contents of this script are:  
  1. from my_app import app
  2. app.run(debug=True)
复制代码
Now just execute from the command line:
  1. $ python run.py
复制代码
To check if the application works, fire up    http://127.0.0.1:5000/in your browser, and a simple screen with a welcome message should greet you.  
  Testing the RESTful API

  To test this API, we can simply make HTTP calls using any of the many available methods. GET calls can be made directly via the browser. POST calls can be made using a Chrome extension like Postman or from the command line using    curl, or we can use Python's    requestslibrary to do the job for us. I'll use the requests library here for demonstration purposes.  
  Let's make a    GETcall first to assure that we don't have any products created yet. As per RESTful API's design, a get call which looks something like    /product/should list all products. Then I will create a couple of products by making    POSTcalls to    /product/with some data. Then a    GETcall to    /product/should list all the products created. To fetch a specific product, a    GETcall to    /product/<product id>should do the job. Below is a sample of all the calls that can be made using this example.  
  1. $ pip install requests
  2. $ python
  3. >>> import requests
  4. >>> r = requests.get('http://localhost:5000/product/')
  5. >>> r.json()
  6. {}
  7. >>> r = requests.post('http://localhost:5000/product/', data={'name': 'iPhone 6s', 'price': 699})
  8. >>> r.json()
  9. {u'1': {u'price': u'699.0000000000', u'name': u'iPhone 6s'}}
  10. >>> r = requests.post('http://localhost:5000/product/', data={'name': 'iPad Pro', 'price': 999})
  11. >>> r.json()
  12. {u'2': {u'price': u'999.0000000000', u'name': u'iPad Pro'}}
  13. >>> r = requests.get('http://localhost:5000/product/')
  14. >>> r.json()
  15. {u'1': {u'price': u'699.0000000000', u'name': u'iPhone 6s'}, u'2': {u'price': u'999.0000000000', u'name': u'iPad Pro'}}
  16. >>> r = requests.get('http://localhost:5000/product/1')
  17. >>> r.json()
  18. {u'price': u'699.0000000000', u'name': u'iPhone 6s'}
复制代码
Conclusion

  In this tutorial, you saw how to create RESTful interfaces all by yourself using Flask's pluggable views utility. This is the most flexible approach while writing REST APIs but involves much more code to be written.
  There are extensions which make life a bit easier and automate the implementation of RESTful APIs to a huge extent. I will be covering these in the next couple of parts of this tutorial series.
友荐云推荐




上一篇:Encrypt form data without SSL in PHP - PHP Classes
下一篇:Juggling Databases Between Datacenters
酷辣虫提示酷辣虫禁止发表任何与中华人民共和国法律有抵触的内容!所有内容由用户发布,并不代表酷辣虫的观点,酷辣虫无法对用户发布内容真实性提供任何的保证,请自行验证并承担风险与后果。如您有版权、违规等问题,请通过"联系我们"或"违规举报"告知我们处理。

黎静 发表于 2016-10-11 16:28:41
我就是来看帖子的,楼主英明啊!
回复 支持 反对

使用道具 举报

冯敏 发表于 2016-11-15 22:37:33
有的人聪明得像天气,多变;有的人傻得像天气预报,变天它都看不出来。
回复 支持 反对

使用道具 举报

*滑动验证:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

我要投稿

推荐阅读

扫码访问 @iTTTTT瑞翔 的微博
回页顶回复上一篇下一篇回列表手机版
手机版/CoLaBug.com ( 粤ICP备05003221号 | 文网文[2010]257号 )|网站地图 酷辣虫

© 2001-2016 Comsenz Inc. Design: Dean. DiscuzFans.

返回顶部 返回列表