Flask یک میکروفریمورک سبک و انعطافپذیر برای پایتون است که برای ساخت APIهای RESTful بسیار مناسب است. در این راهنما، به صورت گام به گام نحوه ساخت یک API ساده با استفاده از Flask را توضیح میدهیم.
گام 1: نصب Flask
ابتدا Flask را با استفاده از pip نصب کنید:
pip install Flask
گام 2: ایجاد یک برنامه Flask ساده
یک فایل پایتون جدید ایجاد کرده و کد زیر را در آن قرار دهید:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
return 'Hello, World!'
if __name__ == '__main__':
app.run()
Flask(__name__)
یک نمونه از کلاس Flask ایجاد میکند.@app.route('/')
یک دکوراتور است که تابعhello()
را به آدرس/
متصل میکند.- وقتی به آدرس
http://127.0.0.1:5000/
در مرورگر مراجعه کنید، تابعhello()
اجرا شده و متن “Hello, World!” را برگرداند.
گام 3: ایجاد یک API ساده
بیایید یک API ساده برای مدیریت کاربران ایجاد کنیم. ابتدا یک لیست برای ذخیره اطلاعات کاربران ایجاد میکنیم:
users = [
{'id': 1, 'name': 'Alice'},
{'id': 2, 'name': 'Bob'}
]
سپس یک endpoint برای دریافت لیست تمام کاربران اضافه میکنیم:
from flask import jsonify
@app.route('/users')
def get_users():
return jsonify(users)
تابع jsonify()
دادههای پایتون را به فرمت JSON تبدیل میکند که فرمت استاندارد برای تبادل داده در APIهای RESTful است.
گام 4: ایجاد endpoint برای دریافت اطلاعات یک کاربر خاص
برای دریافت اطلاعات یک کاربر خاص، از متغیرهای مسیر استفاده میکنیم:
@app.route('/users/<int:user_id>')
def get_user(user_id):
user = [user for user in users if user['id'] == user_id]
if len(user) == 0:
return jsonify({'message': 'User not found'}), 404
return jsonify(user[0])
در این مثال، user_id
یک متغیر مسیر است که به صورت یک عدد صحیح تفسیر میشود.
گام 5: ایجاد endpoint برای افزودن یک کاربر جدید
برای افزودن یک کاربر جدید، از روش POST استفاده میکنیم:
from flask import request
@app.route('/users', methods=['POST'])
def create_user():
data = request.get_json()
new_user = {'id': len(users) + 1, 'name': data['name']}
users.append(new_user)
return jsonify(new_user), 201
request.get_json()
دادههای ارسال شده در بدنه درخواست را به صورت JSON دریافت میکند.- کد وضعیت
201
نشان میدهد که یک منبع جدید ایجاد شده است.
گام 6: بهبود امنیت
برای امنیت بیشتر، میتوانید از روشهای زیر استفاده کنید:
- احراز هویت: از ابزارهایی مانند Flask-JWT-Extended برای احراز هویت کاربران استفاده کنید.
- مجوزدهی: دسترسی کاربران مختلف را به منابع مختلف محدود کنید.
- رمزنگاری: دادههای حساس را رمزنگاری کنید.
گام 7: استقرار API
برای استقرار API، میتوانید از پلتفرمهای مختلفی مانند Heroku، AWS یا Google Cloud استفاده کنید.
موارد دیگری که باید در نظر بگیرید:
- مدیریت خطا: برای هر وضعیت خطا، کد وضعیت HTTP مناسب را برگردانید.
- مستندسازی: API خود را به خوبی مستند کنید تا توسعهدهندگان دیگر بتوانند به راحتی از آن استفاده کنند.
- تست: API خود را به طور کامل تست کنید تا از عملکرد صحیح آن اطمینان حاصل کنید.
ابزارهای مفید:
- Flask-RESTful: یک افزونه Flask است که ساخت APIهای RESTful را سادهتر میکند.
- Postman: یک ابزار برای تست APIها.
با استفاده از Flask و رعایت اصول RESTful، میتوانید APIهای قدرتمند و قابل سفارشیسازی ایجاد کنید.
تعریف روتها برای منابع مختلف در APIهای RESTful
در APIهای RESTful، روتها (Routes) به عنوان آدرسهای اینترنتی برای دسترسی به منابع مختلف عمل میکنند. هر روت با یک متد HTTP (مانند GET، POST، PUT، DELETE) همراه است که نشان میدهد چه عملیاتی باید روی آن منبع انجام شود.
ساختار روتها
یک روت معمولاً شامل بخشهای زیر است:
- متد HTTP: مشخص میکند چه عملیاتی باید انجام شود (GET، POST، PUT، DELETE و …)
- مسیر (Path): آدرس منبع درخواستی
- توابع کنترلکننده: کدی که در پاسخ به درخواست اجرا میشود
مثال
فرض کنید میخواهیم یک API برای مدیریت کتابها ایجاد کنیم. روتهای مختلف برای این API ممکن است به شکل زیر باشند:
- GET /books: تمام کتابها را برمیگرداند.
- POST /books: یک کتاب جدید ایجاد میکند.
- GET /books/{id}: اطلاعات یک کتاب خاص را برمیگرداند.
- PUT /books/{id}: اطلاعات یک کتاب خاص را بهروزرسانی میکند.
- DELETE /books/{id}: یک کتاب خاص را حذف میکند.
تعریف روتها در Flask
در مثال قبلی که با Flask کار کردیم، از دکوراتور @app.route()
برای تعریف روتها استفاده کردیم. این دکوراتور یک تابع را به یک URL متصل میکند. برای مثال:
@app.route('/users')
def get_users():
# ...
پارامترهای مسیر
برای تعریف روتهایی که شامل پارامترهای متغیر هستند، میتوان از علامت <>
استفاده کرد:
@app.route('/users/<int:user_id>')
def get_user(user_id):
# ...
در این مثال، user_id
یک پارامتر مسیر است که به صورت یک عدد صحیح تفسیر میشود.
روشهای مختلف برای تعریف روتها
- دکوراتورهای متد HTTP: برای هر متد HTTP (GET، POST، …) یک دکوراتور جداگانه وجود دارد.
- قلبهای روتها: برخی فریمورکها از یک شیء پیکربندی برای تعریف روتها استفاده میکنند.
- تعیین روتها به صورت برنامهنویسی: در برخی موارد، میتوان روتها را به صورت برنامهنویسی تعریف کرد.
نکات مهم در تعریف روتها
- سادگی و خوانایی: روتها باید ساده و قابل فهم باشند تا به راحتی قابل نگهداری باشند.
- سازگاری با استانداردهای REST: از روشهای HTTP استاندارد و ساختار URI مناسب استفاده کنید.
- مدیریت خطا: برای هر وضعیت خطا، کد وضعیت HTTP مناسب را برگردانید.
- امنیت: از روشهای احراز هویت و مجوزدهی برای محافظت از API خود استفاده کنید.
مثال کاملتر با Flask-RESTful
برای ساخت APIهای RESTful پیچیدهتر، میتوانید از افزونه Flask-RESTful استفاده کنید. این افزونه امکانات بیشتری برای تعریف منابع، فیلترها و سریالایزرها را فراهم میکند.
from flask_restful import Resource, Api, reqparse
# ...
api = Api(app)
class UserList(Resource):
def get(self):
return jsonify(users)
def post(self):
# ...
api.add_resource(UserList, '/users')
استفاده از JSON برای تبادل داده در APIهای RESTful
JSON (JavaScript Object Notation) یک فرمت سبک و خوانا برای تبادل داده است که به طور گستردهای در APIهای RESTful مورد استفاده قرار میگیرد. دلیل محبوبیت JSON به عنوان فرمت تبادل داده در APIهای RESTful، سادگی، خوانایی و پشتیبانی گسترده از آن در زبانهای برنامهنویسی مختلف است.
چرا JSON؟
- سادگی و خوانایی: ساختار JSON شبیه به اشیاء و آرایهها در زبانهای برنامهنویسی است و به راحتی قابل درک و پردازش است.
- سبک بودن: JSON نسبت به فرمتهای XML حجیمتر، سبکتر است و باعث کاهش حجم دادههای منتقل شده میشود.
- پشتیبانی گسترده: تقریباً تمام زبانهای برنامهنویسی مدرن از JSON پشتیبانی میکنند و کتابخانههای بسیاری برای کار با JSON موجود است.
- مستقل از زبان: JSON یک فرمت مستقل از زبان است و میتواند توسط هر زبانی که از آن پشتیبانی میکند، خوانده و نوشته شود.
ساختار JSON
JSON از دو ساختار اصلی تشکیل شده است:
- اشیاء (Objects): مجموعه نام-مقدار هستند که با {} مشخص میشوند.
- آرایهها (Arrays): مجموعهای از مقادیر هستند که با [] مشخص میشوند.
مثال:
{
"name": "Ali",
"age": 30,
"city": "Tehran",
"hobbies": ["reading", "coding"]
}
در مثال بالا، یک شیء JSON داریم که اطلاعات یک شخص را نمایش میدهد.
استفاده از JSON در APIهای RESTful
در APIهای RESTful، JSON معمولاً برای نمایش دادههای برگردانده شده از سرور استفاده میشود. برای مثال، اگر یک درخواست GET برای دریافت اطلاعات یک کاربر ارسال کنیم، سرور ممکن است یک پاسخ JSON به شکل زیر برگرداند:
{
"id": 1,
"name": "Ali",
"email": "ali@example.com"
}
همچنین، برای ارسال دادهها به سرور (مثلاً در درخواستهای POST یا PUT)، دادهها معمولاً به صورت JSON ارسال میشوند.
مزایای استفاده از JSON در APIهای RESTful
- سادگی درک و پردازش: توسعهدهندگان به راحتی میتوانند دادههای JSON را در برنامههای خود پردازش کنند.
- انعطافپذیری: JSON میتواند برای نمایش انواع دادهها استفاده شود، از جمله اعداد، رشتهها، بولینها، آرایهها و اشیاء.
- کارایی: JSON به دلیل ساختار ساده و سبک خود، باعث افزایش کارایی API میشود.
مثال عملی با Python و Flask
from flask import Flask, jsonify
app = Flask(__name__)
users = [
{'id': 1, 'name': 'Ali'},
{'id': 2, 'name': 'Zahra'}
]
@app.route('/users')
def get_users():
return jsonify(users)
if __name__ == '__main__':
app.run()
در این مثال، یک API ساده با Flask ایجاد شده است که لیستی از کاربران را به صورت JSON برمیگرداند.
اعتبارسنجی دادههای ورودی در APIهای RESTful
اعتبارسنجی دادههای ورودی یکی از مهمترین جنبههای امنیت و یکپارچگی داده در APIهای RESTful است. اطمینان از اینکه دادههای دریافتی از کلاینتها معتبر، امن و مطابق با محدودیتهای تعریف شده هستند، از اهمیت بالایی برخوردار است.
چرا اعتبارسنجی دادهها مهم است؟
- امنیت: جلوگیری از حملاتی مانند تزریق SQL، XSS و سایر آسیبپذیریهای تزریق.
- یکپارچگی داده: اطمینان از اینکه دادههای ذخیره شده در پایگاه داده معتبر و سازگار با ساختار داده هستند.
- بهبود عملکرد: جلوگیری از پردازش دادههای نامعتبر که میتواند منجر به خطاهای غیرمنتظره و کاهش عملکرد سیستم شود.
- بهبود تجربه کاربری: ارائه پیامهای خطای مناسب به کاربر در صورت وارد کردن دادههای نامعتبر.
روشهای اعتبارسنجی دادهها
-
اعتبارسنجی سمت سرور:
- تایپ داده: اطمینان حاصل کنید که دادههای دریافتی از نوع داده مورد انتظار هستند (مثلاً اعداد، رشتهها، تاریخها).
- طول داده: بررسی کنید که طول دادهها در محدوده مجاز باشد.
- الگوهای منظم (Regular Expressions): برای اعتبارسنجی فرمت دادهها (مثلاً آدرس ایمیل، شماره تلفن).
- قواعد کسبوکار: بررسی کنید که دادهها با قواعد کسبوکار شما مطابقت داشته باشند (مثلاً محدوده مقادیر، روابط بین فیلدها).
- اعتبارسنجی سفارشی: ایجاد قوانین اعتبارسنجی خاص برای هر فیلد.
-
اعتبارسنجی سمت کلاینت:
- JavaScript: استفاده از کتابخانههایی مانند jQuery Validation برای اعتبارسنجی اولیه دادهها قبل از ارسال به سرور.
- HTML5: استفاده از ویژگیهای HTML5 مانند
required
,pattern
,min
,max
برای اعتبارسنجی اولیه در فرمها.
ابزارها و کتابخانهها
- Python: Flask-WTF، WTForms، Pydantic
- JavaScript: Joi, Yup, Zod
- Node.js: Express-Validator
مثال با استفاده از Flask-WTF
from flask_wtf import FlaskForm
from wtforms import StringField, IntegerField
from wtforms.validators import DataRequired, Length
class UserForm(FlaskForm):
username = StringField('Username', validators=[DataRequired(), Length(min=4, max=25)])
age = IntegerField('Age', validators=[DataRequired()])
بهترین شیوهها
- اعتبارسنجی در لایههای مختلف: هم در سمت کلاینت و هم در سمت سرور اعتبارسنجی انجام دهید.
- پیامهای خطای واضح: به کاربر پیامهای خطای واضح و آموزنده ارائه دهید.
- مدیریت خطاهای اعتبارسنجی: در صورت بروز خطا، یک پاسخ HTTP مناسب (مثلاً 400 Bad Request) با جزئیات خطا برگردانید.
- استفاده از ابزارها و کتابخانهها: از ابزارها و کتابخانههای موجود برای سادهسازی فرآیند اعتبارسنجی استفاده کنید.
- مدارک اعتبارسنجی: مستندات کاملی از قوانین اعتبارسنجی برای توسعهدهندگان کلاینت فراهم کنید.
مثال کامل با Flask
from flask import Flask, request, jsonify
from flask_wtf import FlaskForm
from wtforms import StringField, IntegerField
from wtforms.validators import DataRequired, Length
app = Flask(__name__)
class UserForm(FlaskForm):
# ... (همانند مثال قبلی)
@app.route('/users', methods=['POST'])
def create_user():
form = UserForm()
if form.validate_on_submit():
# دادهها معتبر هستند، عملیات ایجاد کاربر را انجام دهید
return jsonify({'message': 'User created successfully'}), 201
else:
return jsonify({'errors': form.errors}), 400
جمعبندی
اعتبارسنجی دادههای ورودی یک مرحله حیاتی در توسعه APIهای RESTful است. با پیروی از بهترین شیوهها و استفاده از ابزارهای مناسب، میتوانید از امنیت و یکپارچگی دادههای خود محافظت کنید و تجربه کاربری بهتری را برای کاربران فراهم کنید.