एक कमांड-लाइन एप्लिकेशन के लिए हाल ही में पायथन, रूबी और गोलंग की तुलना के बाद, मैंने एक साधारण वेब सेवा के निर्माण की तुलना करने के लिए उसी पैटर्न का उपयोग करने का निर्णय लिया। मैंने इस तुलना के लिए फ्लास्क (पायथन), सिनात्रा (रूबी), और मार्टिनी (गोलंग) को चुना है। हां, प्रत्येक भाषा में वेब एप्लिकेशन लाइब्रेरी के लिए कई अन्य विकल्प हैं लेकिन मुझे लगा कि ये तीनों तुलना करने के लिए उपयुक्त हैं।
लाइब्रेरी अवलोकन
यहाँ स्टैकशेयर द्वारा पुस्तकालयों की उच्च-स्तरीय तुलना है।
फ्लास्क (पायथन)
<ब्लॉकक्वॉट>फ्लास्क पाइथन के लिए एक माइक्रो-फ्रेमवर्क है जो Werkzeug, Jinja2 और अच्छे इरादों पर आधारित है।
बहुत ही सरल अनुप्रयोगों के लिए, जैसे कि इस डेमो में दिखाया गया है, फ्लास्क एक बढ़िया विकल्प है। मूल फ्लास्क एप्लिकेशन एकल पायथन स्रोत फ़ाइल में कोड की केवल 7 पंक्तियाँ (LOC) है। अन्य पायथन वेब पुस्तकालयों (जैसे Django या पिरामिड) पर फ्लास्क का ड्रा यह है कि आप छोटे से शुरू कर सकते हैं और आवश्यकतानुसार अधिक जटिल एप्लिकेशन बना सकते हैं।
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
return "Hello World!"
if __name__ == "__main__":
app.run()
सिनात्रा (रूबी)
<ब्लॉकक्वॉट>कम से कम प्रयास के साथ रूबी में वेब एप्लिकेशन बनाने के लिए सिनात्रा एक डीएसएल है।
फ्लास्क की तरह, सिनात्रा सरल अनुप्रयोगों के लिए बहुत अच्छा है। एक रूबी स्रोत फ़ाइल में मूल सिनात्रा एप्लिकेशन केवल 4 एलओसी है। रूबी ऑन रेल्स जैसे पुस्तकालयों के बजाय फ्लास्क के समान ही सिनात्रा का उपयोग किया जाता है - आप छोटे से शुरू कर सकते हैं और आवश्यकतानुसार आवेदन का विस्तार कर सकते हैं।
require 'sinatra'
get '/hi' do
"Hello World!"
end
मार्टिनी (गोलंग)
<ब्लॉकक्वॉट>गोलंग में मॉड्यूलर वेब एप्लिकेशन/सेवाओं को जल्दी से लिखने के लिए मार्टिनी एक शक्तिशाली पैकेज है।
मार्टिनी सिनात्रा और फ्लास्क दोनों की तुलना में कुछ और बैटरी के साथ आता है लेकिन अभी भी शुरू करने के लिए बहुत हल्का है - मूल अनुप्रयोग के लिए केवल 9 एलओसी। गोलंग समुदाय द्वारा मार्टिनी की कुछ आलोचना की गई है, लेकिन अभी भी किसी भी गोलंग वेब ढांचे की उच्चतम रेटेड गिथब परियोजनाओं में से एक है। मार्टिनी के लेखक ने यहां की आलोचना का सीधा जवाब दिया। कुछ अन्य फ्रेमवर्क में रेवेल, जिन और यहां तक कि बिल्ट-इन नेट/एचटीटीपी लाइब्रेरी भी शामिल है।
package main
import "github.com/go-martini/martini"
func main() {
m := martini.Classic()
m.Get("/", func() string {
return "Hello world!"
})
m.Run()
}
बुनियादी बातों को ध्यान में रखते हुए, आइए एक ऐप बनाएं!
सेवा विवरण
बनाई गई सेवा एक बहुत ही बुनियादी ब्लॉग एप्लिकेशन प्रदान करती है। निम्नलिखित मार्गों का निर्माण किया गया है:
GET /
:ब्लॉग लौटाएं (रेंडर करने के लिए टेम्पलेट का उपयोग करके)।GET /json
:ब्लॉग सामग्री को JSON प्रारूप में लौटाएं।POST /new
:ब्लॉग में एक नई पोस्ट (शीर्षक, सारांश, सामग्री) जोड़ें।
ब्लॉग सेवा का बाहरी इंटरफ़ेस प्रत्येक भाषा के लिए बिल्कुल समान है। सादगी के लिए MongoDB को इस उदाहरण के लिए डेटा स्टोर के रूप में उपयोग किया जाएगा क्योंकि यह सेट अप करने के लिए सबसे सरल है और हमें स्कीमा के बारे में बिल्कुल भी चिंता करने की आवश्यकता नहीं है। एक सामान्य "ब्लॉग-जैसे" एप्लिकेशन में एक रिलेशनल डेटाबेस की आवश्यकता हो सकती है।
पोस्ट जोड़ें
POST /new
$ curl --form title='Test Post 1' \
--form summary='The First Test Post' \
--form content='Lorem ipsum dolor sit amet, consectetur ...' \
http://[IP]:[PORT]/new
एचटीएमएल देखें
GET /
JSON देखें
GET /json
[
{
content:"Lorem ipsum dolor sit amet, consectetur ...",
title:"Test Post 1",
_id:{
$oid:"558329927315660001550970"
},
summary:"The First Test Post"
}
]
आवेदन संरचना
प्रत्येक एप्लिकेशन को निम्नलिखित घटकों में विभाजित किया जा सकता है:
एप्लिकेशन सेटअप
- एप्लिकेशन प्रारंभ करें
- एप्लिकेशन चलाएँ
अनुरोध
- उन मार्गों को परिभाषित करें जिन पर उपयोगकर्ता डेटा का अनुरोध कर सकता है (GET)
- उन मार्गों को परिभाषित करें जिन पर उपयोगकर्ता डेटा (POST) जमा कर सकता है
प्रतिक्रिया
- JSON रेंडर करें (
GET /json
) - टेम्पलेट रेंडर करें (
GET /
)
डेटाबेस
- कनेक्शन प्रारंभ करें
- डेटा डालें
- डेटा पुनर्प्राप्त करें
आवेदन परिनियोजन
- डॉकर!
इस लेख के शेष भाग में प्रत्येक पुस्तकालय के लिए इन घटकों में से प्रत्येक की तुलना की जाएगी। उद्देश्य यह सुझाव देना नहीं है कि इनमें से एक पुस्तकालय दूसरे से बेहतर है - यह तीन उपकरणों के बीच एक विशिष्ट तुलना प्रदान करना है:
- फ्लास्क (पायथन)
- सिनात्रा (रूबी)
- मार्टिनी (गोलंग)
प्रोजेक्ट सेटअप
सभी प्रोजेक्ट docker और docker-compose का उपयोग करके बूटस्ट्रैप किए गए हैं। प्रत्येक एप्लिकेशन को हुड के नीचे कैसे बूटस्ट्रैप किया जाता है, इसमें गोता लगाने से पहले हम प्रत्येक को ठीक उसी तरह से चलाने और चलाने के लिए docker का उपयोग कर सकते हैं - docker-compose up
गंभीरता से, बस! अब प्रत्येक एप्लिकेशन के लिए एक Dockerfile
है और एक docker-compose.yml
फ़ाइल जो निर्दिष्ट करती है कि जब आप उपरोक्त आदेश चलाते हैं तो क्या होता है।
पायथन (फ्लास्क) - डॉकरफाइल
FROM python:3.4
ADD . /app
WORKDIR /app
RUN pip install -r requirements.txt
यह Dockerfile
कहते हैं कि हम एक मूल छवि से शुरू कर रहे हैं जिसमें पायथन 3.4 स्थापित है, हमारे एप्लिकेशन को /app
में जोड़ रहा है requirements.txt
. में निर्दिष्ट हमारी एप्लिकेशन आवश्यकताओं को स्थापित करने के लिए निर्देशिका और पाइप का उपयोग करना ।
रूबी (सिनात्रा)
FROM ruby:2.2
ADD . /app
WORKDIR /app
RUN bundle install
यह Dockerfile
कहता है कि हम रूबी 2.2 के साथ एक मूल छवि से शुरू कर रहे हैं, हमारे एप्लिकेशन को /app
में जोड़ रहे हैं Gemfile
. में निर्दिष्ट हमारी एप्लिकेशन आवश्यकताओं को स्थापित करने के लिए निर्देशिका और बंडलर का उपयोग करना ।
गोलांग (मार्टिनी)
FROM golang:1.3
ADD . /go/src/github.com/kpurdon/go-blog
WORKDIR /go/src/github.com/kpurdon/go-blog
RUN go get github.com/go-martini/martini && \
go get github.com/martini-contrib/render && \
go get gopkg.in/mgo.v2 && \
go get github.com/martini-contrib/binding
यह Dockerfile
कहते हैं कि हम एक मूल छवि से शुरू कर रहे हैं जिसमें गोलांग 1.3 स्थापित है, हमारे आवेदन को /go/src/github.com/kpurdon/go-blog
में जोड़ रहे हैं। निर्देशिका और go get
. का उपयोग करके हमारी सभी आवश्यक निर्भरताएं प्राप्त करना आदेश।
एप्लिकेशन को प्रारंभ/चलाएं
पायथन (फ्लास्क) - app.py
# initialize application
from flask import Flask
app = Flask(__name__)
# run application
if __name__ == '__main__':
app.run(host='0.0.0.0')
$ python app.py
रूबी (सिनात्रा) - app.rb
# initialize application
require 'sinatra'
$ ruby app.rb
गोलंग (मार्टिनी) - app.go
// initialize application
package main
import "github.com/go-martini/martini"
import "github.com/martini-contrib/render"
func main() {
app := martini.Classic()
app.Use(render.Renderer())
// run application
app.Run()
}
$ go run app.go
एक रूट परिभाषित करें (GET/POST)
पायथन (फ्लास्क)
# get
@app.route('/') # the default is GET only
def blog():
# ...
#post
@app.route('/new', methods=['POST'])
def new():
# ...
रूबी (सिनात्रा)
# get
get '/' do
# ...
end
# post
post '/new' do
# ...
end
गोलंग (मार्टिनी)
// define data struct
type Post struct {
Title string `form:"title" json:"title"`
Summary string `form:"summary" json:"summary"`
Content string `form:"content" json:"content"`
}
// get
app.Get("/", func(r render.Render) {
// ...
}
// post
import "github.com/martini-contrib/binding"
app.Post("/new", binding.Bind(Post{}), func(r render.Render, post Post) {
// ...
}
एक JSON प्रतिक्रिया प्रस्तुत करें
पायथन (फ्लास्क)
फ्लास्क एक jsonify() विधि प्रदान करता है लेकिन चूंकि सेवा MongoDB का उपयोग कर रही है, इसलिए mongodb bson उपयोगिता का उपयोग किया जाता है।
from bson.json_util import dumps
return dumps(posts) # posts is a list of dicts [{}, {}]
रूबी (सिनात्रा)
require 'json'
content_type :json
posts.to_json # posts is an array (from mongodb)
गोलंग (मार्टिनी)
r.JSON(200, posts) // posts is an array of Post{} structs
एक HTML प्रतिक्रिया प्रस्तुत करना (टेम्पलेट करना)
पायथन (फ्लास्क)
return render_template('blog.html', posts=posts)
<!doctype HTML>
<html>
<head>
<title>Python Flask Example</title>
</head>
<body>
{% for post in posts %}
<h1> {{ post.title }} </h1>
<h3> {{ post.summary }} </h3>
<p> {{ post.content }} </p>
<hr>
{% endfor %}
</body>
</html>
रूबी (सिनात्रा)
erb :blog
<!doctype HTML>
<html>
<head>
<title>Ruby Sinatra Example</title>
</head>
<body>
<% @posts.each do |post| %>
<h1><%= post['title'] %></h1>
<h3><%= post['summary'] %></h3>
<p><%= post['content'] %></p>
<hr>
<% end %>
</body>
</html>
गोलांग (मार्टिनी)
r.HTML(200, "blog", posts)
<!doctype HTML>
<html>
<head>
<title>Golang Martini Example</title>
</head>
<body>
{{range . }}
<h1>{{.Title}}</h1>
<h3>{{.Summary}}</h3>
<p>{{.Content}}</p>
<hr>
{{ end }}
</body>
</html>
डेटाबेस कनेक्शन
सभी एप्लिकेशन भाषा के लिए विशिष्ट मोंगोडब ड्राइवर का उपयोग कर रहे हैं। पर्यावरण चर DB_PORT_27017_TCP_ADDR
लिंक किए गए डॉकटर कंटेनर (डेटाबेस आईपी) का आईपी है।
पायथन (फ्लास्क)
from pymongo import MongoClient
client = MongoClient(os.environ['DB_PORT_27017_TCP_ADDR'], 27017)
db = client.blog
रूबी (सिनात्रा)
require 'mongo'
db_ip = [ENV['DB_PORT_27017_TCP_ADDR']]
client = Mongo::Client.new(db_ip, database: 'blog')
गोलंग (मार्टिनी)
import "gopkg.in/mgo.v2"
session, _ := mgo.Dial(os.Getenv("DB_PORT_27017_TCP_ADDR"))
db := session.DB("blog")
defer session.Close()
पोस्ट से डेटा डालें
पायथन (फ्लास्क)
from flask import request
post = {
'title': request.form['title'],
'summary': request.form['summary'],
'content': request.form['content']
}
db.blog.insert_one(post)
रूबी (सिनात्रा)
client[:posts].insert_one(params) # params is a hash generated by sinatra
गोलंग (मार्टिनी)
db.C("posts").Insert(post) // post is an instance of the Post{} struct
डेटा पुनर्प्राप्त करें
पायथन (फ्लास्क)
posts = db.blog.find()
रूबी (सिनात्रा)
@posts = client[:posts].find.to_a
गोलंग (मार्टिनी)
var posts []Post
db.C("posts").Find(nil).All(&posts)
एप्लिकेशन परिनियोजन (डॉकर!)
इन सभी अनुप्रयोगों को परिनियोजित करने का एक बढ़िया समाधान है docker और docker-compose का उपयोग करना।
पायथन (फ्लास्क)
डॉकरफ़ाइल
FROM python:3.4
ADD . /app
WORKDIR /app
RUN pip install -r requirements.txt
docker-compose.yml
web:
build: .
command: python -u app.py
ports:
- "5000:5000"
volumes:
- .:/app
links:
- db
db:
image: mongo:3.0.4
command: mongod --quiet --logpath=/dev/null
रूबी (सिनात्रा)
डॉकरफ़ाइल
FROM ruby:2.2
ADD . /app
WORKDIR /app
RUN bundle install
docker-compose.yml
web:
build: .
command: bundle exec ruby app.rb
ports:
- "4567:4567"
volumes:
- .:/app
links:
- db
db:
image: mongo:3.0.4
command: mongod --quiet --logpath=/dev/null
गोलंग (मार्टिनी)
डॉकरफ़ाइल
FROM golang:1.3
ADD . /go/src/github.com/kpurdon/go-todo
WORKDIR /go/src/github.com/kpurdon/go-todo
RUN go get github.com/go-martini/martini && go get github.com/martini-contrib/render && go get gopkg.in/mgo.v2 && go get github.com/martini-contrib/binding
docker-compose.yml
web:
build: .
command: go run app.go
ports:
- "3000:3000"
volumes: # look into volumes v. "ADD"
- .:/go/src/github.com/kpurdon/go-todo
links:
- db
db:
image: mongo:3.0.4
command: mongod --quiet --logpath=/dev/null
निष्कर्ष
समाप्त करने के लिए आइए एक नजर डालते हैं कि मैं क्या मानता हूं कि कुछ श्रेणियां हैं जहां प्रस्तुत पुस्तकालय खुद को एक दूसरे से अलग करते हैं।
सादगी
जबकि फ्लास्क बहुत हल्का है और स्पष्ट रूप से पढ़ता है, सिनात्रा ऐप 23 एलओसी पर तीन में से सबसे सरल है (फ्लास्क के लिए 46 और मार्टिनी के लिए 42 की तुलना में)। इन कारणों से इस श्रेणी में सिनात्रा विजेता है। हालांकि यह ध्यान दिया जाना चाहिए कि सिनात्रा की सादगी अधिक डिफ़ॉल्ट "जादू" के कारण है - उदाहरण के लिए, पर्दे के पीछे होने वाला निहित कार्य। नए उपयोगकर्ताओं के लिए यह अक्सर भ्रम पैदा कर सकता है।
सिनात्रा में "जादू" का एक विशिष्ट उदाहरण यहां दिया गया है:
params # the "request.form" logic in python is done "magically" behind the scenes in Sinatra.
और समकक्ष फ्लास्क कोड:
from flask import request
params = {
'title': request.form['title'],
'summary': request.form['summary'],
'content': request.form['content']
}
शुरुआती लोगों के लिए फ्लास्क और सिनात्रा प्रोग्रामिंग करना निश्चित रूप से सरल है, लेकिन एक अनुभवी प्रोग्रामर के लिए अन्य सांख्यिकीय रूप से टाइप की गई भाषाओं में बिताए गए समय के साथ मार्टिनी काफी सरल इंटरफ़ेस प्रदान करता है।
दस्तावेज़ीकरण
फ्लास्क दस्तावेज़ीकरण खोजने में सबसे सरल और सबसे अधिक पहुंच योग्य था। जबकि सिनात्रा और मार्टिनी दोनों ही अच्छी तरह से प्रलेखित हैं, दस्तावेज़ीकरण स्वयं उतना स्वीकार्य नहीं था। इस कारण से फ्लास्क इस श्रेणी में विजेता है।
समुदाय
फ्लास्क इस श्रेणी में विजेता है। यदि आपको मूल सेवा से अधिक कुछ चाहिए (भले ही पैडरिनो इसे सिनात्रा के शीर्ष पर प्रदान करता है) रूबी समुदाय रेल के बारे में केवल एकमात्र अच्छा विकल्प होने के बारे में हठधर्मी नहीं है। गोलंग समुदाय अभी भी एक (या कुछ) वेब ढांचे पर आम सहमति के पास नहीं है, जिसकी अपेक्षा की जा सकती है क्योंकि भाषा स्वयं इतनी छोटी है। हालाँकि, पायथन ने वेब विकास के लिए कई दृष्टिकोणों को अपनाया है, जिसमें आउट-ऑफ-द-बॉक्स पूर्ण-विशेषताओं वाले वेब एप्लिकेशन और माइक्रो-फ्रेमवर्क दृष्टिकोण के लिए फ्लास्क, बॉटल, चेरीपी और टॉरनेडो शामिल हैं।
अंतिम निर्धारण
ध्यान दें कि इस लेख का उद्देश्य किसी एक उपकरण को बढ़ावा देना नहीं था, बल्कि फ्लास्क, सिनात्रा और मार्टिनी की निष्पक्ष तुलना प्रदान करना था। इसके साथ ही, मैं फ्लास्क (पायथन) या सिनात्रा (रूबी) का चयन करूंगा। यदि आप सी या जावा जैसी भाषा से आ रहे हैं तो शायद गोलंग की सांख्यिकीय रूप से टाइप की गई प्रकृति आपको आकर्षित कर सकती है। यदि आप एक नौसिखिया हैं, तो फ्लास्क सबसे अच्छा विकल्प हो सकता है क्योंकि उठना और दौड़ना बहुत आसान है और बहुत कम डिफ़ॉल्ट "जादू" है। मेरा सुझाव है कि आप अपने प्रोजेक्ट के लिए लाइब्रेरी का चयन करते समय अपने निर्णयों में लचीले रहें।
प्रशन? प्रतिपुष्टि? कृपया नीचे टिप्पणी करें। धन्यवाद!
साथ ही, हमें बताएं कि क्या आप कुछ बेंचमार्क देखने में रुचि रखते हैं।