Flask против Django: сравнение создания REST API

Почему Flask или Django является распространенным вопросом? Если бы вы искали «лучший язык программирования для изучения» в Google, он сказал бы, что Python является одним из наиболее часто рекомендуемых языков для начинающих. Это не должно вызывать удивления, поскольку Python является одним из самых удобных языков на сегодняшнем рынке и является основой таких компаний, как Instagram, Pinterest и Spotify.

Хотя, когда дело доходит до фактического построения приложения в Python, нет недостатка в выборе инструментов, которые вы можете использовать. Тем не менее, в мире, управляемом сетью, в котором мы в настоящее время живем, API являются главными, а когда дело доходит до Python, два популярных варианта для создания масштабируемого, производительного REST API: Django и Flask.

Flask против Django: создание API для гадалки

Две самые популярные платформы для Python, Django и Flask, используют невероятно разные подходы к веб-разработке. Django, более старый из двух фреймворков, часто называют фреймворком «с батарейками», что означает, что он содержит практически все, что вам нужно для запуска полнофункционального приложения в кратчайшие сроки. Flask, с другой стороны, является чрезвычайно расширяемой «микро-структурой», которая запускается с минимальным набором функций, но имеет процветающую экосистему плагинов, которая позволяет разработчикам включать только те функции, которые им необходимы для успеха.

Чтобы продемонстрировать различия между этими двумя средами, давайте взглянем на процесс создания базового REST API «Fortune Cookie» с использованием каждого из них. Для простоты этот API будет иметь только одну конечную точку /fortune, которая будет возвращать базовый ответ JSON, содержащий случайное состояние.

Ничего особенного, но достаточно, чтобы понять всю сложность (или простоту) каждой структуры.

Если вы хотите следовать примерам, убедитесь, что у вас установлена последняя версия Python, а также Flask и Django. Чтобы быстро начать, вы можете:

  • Загрузите и установите предварительно созданную среду выполнения «Fortune Cookie API» для Windows 10, macOS, CentOS 7 или…
  • Загрузите предварительно созданную среду Python WebDev, которая содержит все популярные фреймворки, инструменты и утилиты, необходимые для быстрого запуска и работы всей команды, независимо от того, используют ли они Mac, Windows или Linux.

С этого момента в данной статье предполагается, что у вас есть Flask и Django, а также Python, установленный в вашей системе и в вашем PATH.

Flask против Django: создание API с помощью Flask

Давайте продолжим и сделаем нашу конечную точку API. Для этого давайте сначала начнем с очень простой конечной точки /fortune, которая возвращает только одно состояние. Сначала создайте новый файл с именем app.py в вашем любимом текстовом редакторе и введите следующий код:

from flask import Flask, jsonify

app = Flask(__name__)
app.config["DEBUG"] = True

@app.route('/fortune', methods=['GET'])
def fortune():
  return jsonify({
 'data': 'How many of you believe in psycho-kinesis? Raise my hand.',
 'status': 'awesome'
  }), 200

Чтобы разбить вышеприведенный блок кода, мы определяем маршрут, который, с точки зрения веб-приложения, является частью, которая идет после имени домена, например /fortune в https://api.flower.codes/fortune. Часть, который следует после, def fortune(), является функцией, которая обрабатывает запросы к маршруту /fortune, который в настоящее время возвращает единственное состояние.

Давайте сделаем вещи немного более интересными и добавим еще несколько состояний, которые мы выберем наугад, чтобы обеспечить то непредсказуемое благосостояние, которое мы ожидаем. Чтобы сделать это, мы добавим немного магии Python и добавим еще несколько пословиц плохого состояния:

from flask import Flask, jsonify
import random

app = Flask(__name__)
app.config["DEBUG"] = True

@app.route('/fortune', methods=['GET'])
def fortune():
    fortunes = [
      'A feather in the hand is better than a bird in the air. ',
      'A golden egg of opportunity falls into your lap this month.',
      'Bide your time, for success is near.',
      'Curiosity kills boredom. Nothing can kill curiosity.',
      'Disbelief destroys the magic.',
      'Don't just spend time. Invest it.',
      'Every wise man started out by asking many questions.',
      'Fortune Not Found: Abort, Retry, Ignore?',
      'Good to begin well, better to end well.',
      'How many of you believe in psycho-kinesis? Raise my hand.',
      'Imagination rules the world.',
      'Keep your face to the sunshine and you will never see 
shadows.',
      'Listen to everyone. Ideas come from everywhere.',
      'Man is born to live and not prepared to live.',
      'No one can walk backwards into the future.',
      'One of the first things you should look for in a problem is its positive side.',
      'Pick battles big enough to matter, small enough to win.',
      'Remember the birthday but never the age.',
      'Success is failure turned inside out.',
      'The harder you work, the luckier you get.',
      'Use your eloquence where it will do the most good.',
      'What's hidden in an empty box?',
      'Your reputation is your wealth.'
    ]

  return jsonify({
 'data': random.choice(fortunes),
 'status': 'awesome'
  }), 200

Теперь все, что нам нужно сделать, это запустить API, что можно сделать с помощью команды работы с flask (не забудьте установить переменную FLASK_APP для файла app.py, который мы только что создали):

$ FLASK_APP=app.py flask run
 * Serving Flask app "app.py"
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

Если бы мы взяли указанное доменное имя и добавили наш определенный маршрут, который является http://127.0.0.1:5000/fortune, мы должны увидеть случайный ответ на состояние в формате JSON, который мы определили:

Чтобы проверить случайность, попробуйте перезагрузить страницу. Каждый раз вы должны получать что-то новое, и вы также сможете пометить «создать REST API» в своем списке.

Flask против Django: создание API с помощью Django

Как мы только что видели, Flask - это очень практичная среда. Он минимально самоуверен и дает своим пользователям достаточно веревки, чтобы повеситься, если они не будут осторожны. Но как насчет Джанго? Что отличает это? В двух словах: особенности.

Чтобы понять, что я имею в виду, давайте сначала создадим проект. Он будет отличаться от примера Flask, потому что проекты Django гораздо более устойчивы, что означает, что их скаффолдинг должен быть сгенерирован для начала, вместо простого добавления нескольких строк кода в один файл .py:

$ django-admin startproject activestate_django_api_example

Приведенная выше команда создает базовую структуру каталогов, которая определяет наше приложение Django. Если вы посмотрите на свою файловую систему, вы увидите новую папку, основанную на названии проекта, который вы только что создали, с несколькими другими файлами, вложенными внизу.

+-- activestate_django_api_example
 +-- manage.py
 +-- activestate_django_api_example
     +-- __init__.py
     +-- settings.py
     +-- urls.py
     +-- wsgi.py

Хотя каждый из этих файлов можно использовать для изменения конфигурации и функциональности вашего приложения, мы сосредоточимся в основном на файле urls.py для целей этой демонстрации. Однако прежде чем мы сможем приступить к созданию нашего API, мы должны сначала запустить встроенную миграцию базы данных:

$ python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying sessions.0001_initial... OK

Эти миграции инициализируют таблицы базы данных, которые необходимы для аутентификации, управления сеансами и интерфейса администратора (то, с чем Flask не поставляется).

Чтобы запустить сервер как есть, все, что вам нужно сделать, это запустить python manage.py runserver, который запустит сервер на порту 8000 вашей локальной машины:

$ python manage.py runserver
Performing system checks...

System check identified no issues (0 silenced).
August 14, 2019 - 19:07:37
Django version 1.11.23, using settings 'activestate_django_api_example.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

Как уже упоминалось, Django поставляется со встроенным интерфейсом администратора. Поэтому, если бы мы перешли на http://127.0.0.1:8000/admin, мы бы увидели страницу, которая выглядит примерно так:

Если, например, мы хотим использовать интерфейс администратора, мы можем создать пользователя администратора, например:

$ python manage.py createsuperuser
Username (leave blank to use 'zach'): zach
Email address: zach@flower.codes
Password:
Password (again):
Superuser created successfully.

Использование интерфейса администратора выходит за рамки данной статьи, но это прекрасный пример того, насколько полнофункциональный Django по сравнению с Flask (по замыслу). Следующее, что нам нужно сделать, чтобы создать наш Fortune API, - это создать приложение Fortune в нашем проекте Django:

$ python manage.py startapp fortune

При запуске приведенная выше команда создаст новую папку в каталоге нашего проекта под названием «fortune», которая будет содержать несколько файлов, похожих на те, которые уже были созданы:

+-- activestate_django_api_example
 +-- db.sqlite3
 +-- manage.py
 +-- activestate_django_api_example
     +-- __init__.py
     +-- settings.py
     +-- urls.py
     +-- wsgi.py
 +-- fortune
     +-- __init__.py
     +-- admin.py
     +-- apps.py
     +-- models.py
     +-- tests.py
     +-- views.py
     +-- migrations
         +-- __init__.py

Django следует стандарту Model-View-Controller, что означает, что для создания нашей конечной точки API /fortune в Django нам нужно будет добавить ее в файл views.py. Так как мы разработали случайный выбор состояния в нашем примере с Flask выше, мы пропустим этот шаг и перейдем прямо к полной функциональности:

from django.shortcuts import render
from django.http import JsonResponse
import random

# Create your views here.
def fortune(request):
  fortunes = [
 'A feather in the hand is better than a bird in the air. ',
 'A golden egg of opportunity falls into your lap this month.',
 'Bide your time, for success is near.',
 'Curiosity kills boredom. Nothing can kill curiosity.',
 'Disbelief destroys the magic.',
 'Don't just spend time. Invest it.',
 'Every wise man started out by asking many questions.',
 'Fortune Not Found: Abort, Retry, Ignore?',
 'Good to begin well, better to end well.',
 'How many of you believe in psycho-kinesis? Raise my hand.',
 'Imagination rules the world.',
 'Keep your face to the sunshine and you will never see shadows.',
 'Listen to everyone. Ideas come from everywhere.',
 'Man is born to live and not prepared to live.',
 'No one can walk backwards into the future.',
 'One of the first things you should look for in a problem is its positive side.',
 'Pick battles big enough to matter, small enough to win.',
 'Remember the birthday but never the age.',
 'Success is failure turned inside out.',
 'The harder you work, the luckier you get.',
 'Use your eloquence where it will do the most good.',
 'What's hidden in an empty box?',
 'Your reputation is your wealth.'
  ]

  return JsonResponse({
 'data': random.choice(fortunes),
 'status': 'awesome'
  })

Как и в нашем примере с Flask, метод fortune() в представлении Django вернет JSON-ответ, содержащий случайное состояние и базовый ответ о состоянии. Далее нам нужно определить наши маршруты. В то время как Flask обрабатывает все это в одном файле, Django предпочитает хранить маршруты в файле urls.py. Поскольку этот файл не включен в окружении приложений fortune, мы сначала создадим его и добавим следующий код:

from django.conf.urls import url
from . import views

urlpatterns = [
  url(r'^$', views.fortune, name='fortune'),
]

Этот код определяет шаблоны URL, которым мы хотим соответствовать, и соответствующие методы, которые возвращаются, когда эти шаблоны сопоставляются. В этом примере корневой маршрут будет выполнять наше представление состояния, которое было определено выше. Однако важно понимать, что эти маршруты еще не включены. Для этого нам нужно обновить основной файл urls.py:

from django.conf.urls import url
from django.contrib import admin
from django.conf.urls import include

urlpatterns = [
 url(r'^admin/', admin.site.urls),
 url(r'^fortune/', include('fortune.urls')),
]

Как вы можете видеть, наш новый файл urls.py был включен в пространство имен fortune/ нашего основного файла маршрутов. Это означает, что в то время как наш файл fortune/urls.py указывает, что наш метод fortune() должен выполнять только корневой путь, этот корневой путь фактически ограничен указателем fortune/ в соответствии с нашим основным файлом маршрутов. Если бы мы затем посетили нашу новую конечную точку API http://127.0.0.1:8000/fortune, мы должны увидеть ответ, похожий на наш пример Flask.

Flask против Джанго — что лучше?

Учитывая наш пример с Fortune, вам будет сложно найти кого-то, кто будет утверждать, что решение Django проще, чем решение Flask. Но эти две структуры потрясающе отличаются по дизайну. Django — это невероятно надежное решение для веб-приложений, которое подходит не только для создания API-интерфейсов REST. С Django (почти) из коробки можно сделать практически все, что делает его идеальным выбором для разработчиков, которые точно знают, что они хотят построить, и не хотят возиться со сборкой стандартных компонентов с нуля.

С другой стороны, Flask с гордостью представляют как микрофреймворк. Он не претендует на звание конкурента Django, а скорее на лучшую альтернативу для разработчиков, которые хотят детально контролировать дизайн и разработку своего приложения. Flask — отличная система для любого нового разработчика, который хочет изучить все тонкости веб-приложений. Он также является мощным инструментом, который предлагает достаточно структуры, чтобы быстро двигаться, и в то же время предлагая необходимую стабильность для опытных разработчиков создавать все, что они хотят, без компромиссов в дизайне или реализации.

Вернуться на верх