SlideShare una empresa de Scribd logo
1 de 32
Becoming a Polyglot
Simple API Engines in 5 Languages
Kirsten Hunter
@synedra
http://www.princesspolymath.com
Kirsten Hunter
@synedra
http://www.princesspolymath.com
Introduction
Kirsten Hunter
Kirsten Hunter
@synedra
http://www.princesspolymath.com
Kirsten Hunter
@synedra
http://www.princesspolymath.com
The Challenge
Siloed Communities
Poor Understanding of
Language Differences
Fear of the Unknown
Exclusivity
Kirsten Hunter
@synedra
http://www.princesspolymath.com
The Solution
• Simple API Project
• Mongo Backend
• Single Page Application Front End
• Identically functioning API Engines in 5
Languages
Kirsten Hunter
@synedra
http://www.princesspolymath.com
Fortune Cookie
Server
Engines use data from
mongo db
Each engine presents
full API capability
* GET
* PUT
* POST
* DELETE
Github / Docker
synedra/polyglot
c9.io
python image
clone github repo
Kirsten Hunter
@synedra
http://www.princesspolymath.com
Single Page Application
Kirsten Hunter
@synedra
http://www.princesspolymath.com
Mongo Setup
load quoteid.jsonStartup mongo
/etc/init.d/mongodb start
{
"content": "Boredom: the
desire for desires.",
"index": 1998,
"author": "Leo Tolstoy"
},
mongoimport --collection quotes --file quoteid.json --type json
jsonArray
Kirsten Hunter
@synedra
http://www.princesspolymath.com
Schema
Modeling
RAML
OpenAPI
Kirsten Hunter
@synedra
http://www.princesspolymath.com
RAML 0.8
title: Fortune Cookie
version: V1
baseUri: http://www.fortunecookieserver.com/api/v1
/quotes:
displayName: Quotes
get:
description: Get a list of quotes
queryParameters:
random:
description: Retrieve a random quote
required: false
default: false
type: boolean
responses:
200:
body:
application/json:
example: |
[
{"content":"That which does not kill us makes us stronger.",
"author":"Sun Yi",
"id":1
}
]
Kirsten Hunter
@synedra
http://www.princesspolymath.com
RAML 0.8
title: Fortune Cookie
version: V1
baseUri: http://www.fortunecookieserver.com/api/v1
/quotes:
displayName: Quotes
get:
description: Get a list of quotes
queryParameters:
random:
description: Retrieve a random quote
required: false
default: false
type: boolean
responses:
200:
body:
application/json:
example: |
[
{"content":"That which does not kill us makes us stronger.",
"author":"Sun Yi",
"id":1
}
]
Kirsten Hunter
@synedra
http://www.princesspolymath.com
RAML 0.8
title: Fortune Cookie
version: V1
baseUri: http://www.fortunecookieserver.com/api/v1
/quotes:
displayName: Quotes
get:
description: Get a list of quotes
queryParameters:
random:
description: Retrieve a random quote
required: false
default: false
type: boolean
responses:
200:
body:
application/json:
example: |
[
{"content":"That which does not kill us makes us stronger.",
"author":"Sun Yi",
"id":1
}
]
Kirsten Hunter
@synedra
http://www.princesspolymath.com
{
"swagger": "2.0",
"info": {
"title": "Fortune Cookie API",
"description": "Random quote of the day",
"version": "1.0.0"
},
"host": "api.fortunecookieserver.com",
"schemes": [
"http"
],
"basePath": "/v1",
"produces": [
"application/json"
],
"paths": {
"/quotes": {
"get": {
"summary": "Quotes",
"description": "This is a quote server.n",
"tags": [
"Quotes"
],
"responses": {
"200": {
"description": "An array of products",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/Quote"
}
}
},
Kirsten Hunter
@synedra
http://www.princesspolymath.com
{
"swagger": "2.0",
"info": {
"title": "Fortune Cookie API",
"description": "Random quote of the day",
"version": "1.0.0"
},
"host": "api.fortunecookieserver.com",
"schemes": [
"http"
],
"basePath": "/v1",
"produces": [
"application/json"
],
"paths": {
"/quotes": {
"get": {
"summary": "Quotes",
"description": "This is a quote server.n",
"tags": [
"Quotes"
],
"responses": {
"200": {
"description": "An array of products",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/Quote"
}
}
},
Kirsten Hunter
@synedra
http://www.princesspolymath.com
{
"swagger": "2.0",
"info": {
"title": "Fortune Cookie API",
"description": "Random quote of the day",
"version": "1.0.0"
},
"host": "api.fortunecookieserver.com",
"schemes": [
"http"
],
"basePath": "/v1",
"produces": [
"application/json"
],
"paths": {
"/quotes": {
"get": {
"summary": "Quotes",
"description": "This is a quote server.n",
"tags": [
"Quotes"
],
"responses": {
"200": {
"description": "An array of products",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/Quote"
}
}
},
Kirsten Hunter
@synedra
http://www.princesspolymath.com
PHP - Mongo Setup// Routes
$app->group('/api/quotes', function () {
// Setup DB connection
$mongo = new MongoClient('mongodb://localhost:27017');
$mongo->connect();
$db = $mongo->test;
$quotes = $db->selectCollection('quotes');
$this->get('', function (Request $request, Response $response, array $args) use ($quotes) {
$this->logger->info("Fetching 10 records…n");
$results = [];
foreach ($quotes->find([], ['_id' => 0])->sort(['index' => -1])->limit(10) as $quote) {
$results[] = $quote;
}
$response
->getBody()->write(json_encode($results, JSON_PRETTY_PRINT));
$newResponse = $response->withHeader(
'Content-type',
'application/json; charset=utf-8'
);
return $newResponse;
});
Kirsten Hunter
@synedra
http://www.princesspolymath.com
PHP - Route// Routes
$app->group('/api/quotes', function () {
// Setup DB connection
$mongo = new MongoClient('mongodb://localhost:27017');
$mongo->connect();
$db = $mongo->test;
$quotes = $db->selectCollection('quotes');
$this->get('', function (Request $request, Response $response, array $args) use ($quotes) {
$this->logger->info("Fetching 10 records…n");
$results = [];
foreach ($quotes->find([], ['_id' => 0])->sort(['index' => -1])->limit(10) as $quote) {
$results[] = $quote;
}
$response
->getBody()->write(json_encode($results, JSON_PRETTY_PRINT));
$newResponse = $response->withHeader(
'Content-type',
'application/json; charset=utf-8'
);
return $newResponse;
});
Kirsten Hunter
@synedra
http://www.princesspolymath.com
PHP - Static
$app->get('/', function(Request $request, Response $response, $args) {
return $response->getBody()->write('Hello World from PHP Slim');
});
$app->get('/demo', function(Request $request, Response $response, $args) {
$content = file_get_contents('../static/index.html');
return $response->getBody()->write($content);
});
Kirsten Hunter
@synedra
http://www.princesspolymath.com
Perl - Mongo Setup
use Dancer;
use Dancer::Plugin::CRUD;
use MongoDB;
my $client = MongoDB->connect();
my $db = $client->get_database('test');
my $quotes = $db->get_collection('quotes');
my $json = JSON->new->allow_nonref;
set content_type => 'application/json';
get '/' => sub{
return {message => "Hello from Perl and Dancer"};
};
set public => path(dirname(__FILE__), '..', 'static');
get "/demo/?" => sub {
send_file '/index.html'
};
get '/api/quotes' => sub {
my $response = $quotes->find()->sort({'index' => -1})->limit(10);
my @results = ();
while(my $quote = $response->next) {
push (@results,
{"content" => $quote->{'content'},
"index" => $quote->{'index'},
"author" => $quote->{'author'}
}
);
}
if (! scalar (@results)) {
status 404;
return;
}
return @results;
};
Kirsten Hunter
@synedra
http://www.princesspolymath.com
Perl - Static Files
use Dancer;
use Dancer::Plugin::CRUD;
use MongoDB;
my $client = MongoDB->connect();
my $db = $client->get_database('test');
my $quotes = $db->get_collection('quotes');
my $json = JSON->new->allow_nonref;
set content_type => 'application/json';
get '/' => sub{
return {message => "Hello from Perl and Dancer"};
};
set public => path(dirname(__FILE__), '..', 'static');
get "/demo/?" => sub {
send_file '/index.html'
};
get '/api/quotes' => sub {
my $response = $quotes->find()->sort({'index' => -1})->limit(10);
my @results = ();
while(my $quote = $response->next) {
push (@results,
{"content" => $quote->{'content'},
"index" => $quote->{'index'},
"author" => $quote->{'author'}
}
);
}
if (! scalar (@results)) {
status 404;
return;
}
return @results;
};
Kirsten Hunter
@synedra
http://www.princesspolymath.com
Perl - Routes
get '/api/quotes' => sub {
my $response = $quotes->find()->sort({'index' => -1})->limit(10);
my @results = ();
while(my $quote = $response->next) {
push (@results,
{"content" => $quote->{'content'},
"index" => $quote->{'index'},
"author" => $quote->{'author'}
}
);
}
if (! scalar (@results)) {
status 404;
return;
}
return @results;
};
Kirsten Hunter
@synedra
http://www.princesspolymath.com
Python - Mongo Setup
resp = Response(dumps(quotes, default=default),
mimetype='application/json')
return resp
def delete(self, quote_id):
print "Quote id is %s" % quote_id
try:
mongo.db.quotes.remove({
'index': int(quote_id)
})
except Exception as ve:
print ve
abort(400, str(ve))
return '', 204
def put(self, quote_id):
args = parser.parse_args()
if not (args['content'] or args['author']):
return 'Missing data', 400
existing_quote = mongo.db.quotes.find_one({"index": int(quote_id)})
args['content'] = args['content'] if args['content'] else existing_quote["content"]
args['author'] = args['author'] if args['author'] else existing_quote["author"]
try:
mongo.db.quotes.update({
'index': quote_id
},{
'$set': {
'content': args['content'],
'author': args['author']
}
}, upsert=False)
except Exception as ve:
print ve
abort(400, str(ve))
return 201
# TodoList
# shows a list of all todos, and lets you POST to add new tasks
class QuoteList(Resource):
def get(self):
quotes = mongo.db.quotes.find().sort("index", -1).limit(10)
resp = Response(dumps(quotes, default=default),
mimetype='application/json')
return resp
Kirsten Hunter
@synedra
http://www.princesspolymath.com
Python - Static
return resp
…
@app.route('/')
def hello_world():
return 'Hello from Flask!'
@app.route('/demo')
def serve_page():
return send_from_directory(STATIC_ROOT, "index.html")
abort(400, str(ve))
return '', 204
def put(self, quote_id):
args = parser.parse_args()
if not (args['content'] or args['author']):
return 'Missing data', 400
existing_quote = mongo.db.quotes.find_one({"index": int(quote_id)})
args['content'] = args['content'] if args['content'] else existing_quote["content"]
args['author'] = args['author'] if args['author'] else existing_quote["author"]
try:
mongo.db.quotes.update({
'index': quote_id
},{
'$set': {
'content': args['content'],
'author': args['author']
}
}, upsert=False)
except Exception as ve:
print ve
abort(400, str(ve))
return 201
# TodoList
# shows a list of all todos, and lets you POST to add new tasks
class QuoteList(Resource):
def get(self):
quotes = mongo.db.quotes.find().sort("index", -1).limit(10)
resp = Response(dumps(quotes, default=default),
mimetype='application/json')
return resp
def post(self):
args = parser.parse_args()
Kirsten Hunter
@synedra
http://www.princesspolymath.com
Python - Route
# shows a list of all quotes, and lets you POST to add new quotes
class QuoteList(Resource):
def get(self):
quotes = mongo.db.quotes.find().sort("index", -1).limit(10)
resp = Response(dumps(quotes, default=default),
mimetype='application/json')
return resp
def post(self):
args = parser.parse_args()
quotes = mongo.db.quotes.find().sort("index", -1).limit(1)
print quotes[0]
args["index"] = int(quotes[0]["index"]) + 1
print args
try:
mongo.db.quotes.insert(args)
except Error as ve:
abort(400, str(ve))
return 201
api.add_resource(QuoteList, '/api/quotes')
api.add_resource(Quote, '/api/quotes/<quote_id>')
Kirsten Hunter
@synedra
http://www.princesspolymath.com
Ruby - Mongo Setup
end
get '/' do
content_type :html
"Hello World from Sinatra"
end
before do
content_type 'application/json'
end
namespace "/api" do
# list all
get '/quotes' do
Quote.all.desc(:index).limit(10).to_json
end
get '/quotes/random' do
newnumber = Quote.count
random_num = rand(newnumber)
quote = Quote.find_by(index: random_num.to_i)
return status 404 if quote.nil?
quote.to_json
end
# view one
get '/quotes/:index' do
quote = Quote.find_by(index: params[:index].to_i)
return status 404 if quote.nil?
quote.to_json
end
# create
post '/quotes' do
newnumber = Quote.count + 1
@json = JSON.parse(request.body.read)
quote = Quote.new(
content: @json['content'],
author: @json['author'],
index: newnumber)
quote.save
newnumber.to_json
end
# update
put '/quotes/:index' do
Kirsten Hunter
@synedra
http://www.princesspolymath.com
end
get '/' do
content_type :html
"Hello World from Sinatra"
end
before do
content_type 'application/json'
end
namespace "/api" do
# list all
get '/quotes' do
Quote.all.desc(:index).limit(10).to_json
end
get '/quotes/random' do
newnumber = Quote.count
random_num = rand(newnumber)
quote = Quote.find_by(index: random_num.to_i)
return status 404 if quote.nil?
quote.to_json
end
# view one
get '/quotes/:index' do
quote = Quote.find_by(index: params[:index].to_i)
return status 404 if quote.nil?
quote.to_json
end
# create
post '/quotes' do
newnumber = Quote.count + 1
@json = JSON.parse(request.body.read)
quote = Quote.new(
content: @json['content'],
author: @json['author'],
index: newnumber)
quote.save
newnumber.to_json
end
# update
put '/quotes/:index' do
Ruby - Static
Kirsten Hunter
@synedra
http://www.princesspolymath.com
namespace "/api" do
# list all
get '/quotes' do
Quote.all.desc(:index).limit(10).to_json
end
get '/quotes/random' do
newnumber = Quote.count
random_num = rand(newnumber)
quote = Quote.find_by(index: random_num.to_i)
return status 404 if quote.nil?
quote.to_json
end
# view one
get '/quotes/:index' do
quote = Quote.find_by(index: params[:index].to_i)
return status 404 if quote.nil?
quote.to_json
end
# create
post '/quotes' do
newnumber = Quote.count + 1
@json = JSON.parse(request.body.read)
quote = Quote.new(
content: @json['content'],
author: @json['author'],
index: newnumber)
quote.save
newnumber.to_json
end
# update
put '/quotes/:index' do
@json = JSON.parse(request.body.read)
quote = Quote.find_by(index: params[:index].to_i)
return status 404 if quote.nil?
quote.update(
content: @json['content'],
author: @json['author']
)
quote.save
params[:index].to_json
end
Ruby - Route
Kirsten Hunter
@synedra
http://www.princesspolymath.com
app.use('/api', router);
// REST API
router.route('/quotes/random')
.get(function(req, res, next) {
var random = Math.floor(Math.random() * quotecount);
Quote.findOne({"index":random},
function (err, result) {
if (err) {
console.log(err);
res.redirect('/quotes/random');
}
res.send(result);
})
});
router.route('/quotes')
.get(function(req, res, next) {
var result = Quote.find().sort({'index': -1}).limit(10);
result.exec(function(err, quotes) {
res.send(quotes);
});
})
.post(function(req, res, next) {
if(!req.body.hasOwnProperty('content')) {
res.statusCode = 400;
return res.send('Error 400: Post syntax incorrect.');
}
quotecount = quotecount+1;
var newQuote;
if (req.body.hasOwnProperty('author')) {
newQuote = new Quote({'content': req.body.content, 'author': req.body.author, 'index': quotecount});
} else {
newQuote = new Quote({'content': req.body.content, 'index':quotecount});
}
newQuote.save(function (err, newQuote) {
if (err) return console.error(err);
res.json(quotecount);
});;
});
router.route('/quotes/:index')
.get(function(req, res, next) {
Quote.findOne({"index":req.params.index},
function (err, result) {
res.send(result);
Node - Mongo Setup
Kirsten Hunter
@synedra
http://www.princesspolymath.com
if (err) {
console.log(err);
res.redirect('/quotes/random');
}
res.send(result);
})
});
router.route('/quotes')
.get(function(req, res, next) {
var result = Quote.find().sort({'index': -1}).limit(10);
result.exec(function(err, quotes) {
res.send(quotes);
});
})
.post(function(req, res, next) {
if(!req.body.hasOwnProperty('content')) {
res.statusCode = 400;
return res.send('Error 400: Post syntax incorrect.');
}
quotecount = quotecount+1;
var newQuote;
if (req.body.hasOwnProperty('author')) {
newQuote = new Quote({'content': req.body.content, 'author': req.body.author, 'index': quotecount});
} else {
newQuote = new Quote({'content': req.body.content, 'index':quotecount});
}
newQuote.save(function (err, newQuote) {
if (err) return console.error(err);
res.json(quotecount);
});;
});
router.route('/quotes/:index')
.get(function(req, res, next) {
Quote.findOne({"index":req.params.index},
function (err, result) {
res.send(result);
});
})
.put(function(req, res, next) {
if(!req.body.hasOwnProperty('content') && (!req.body.hasOwnProperty('author'))) {
res.statusCode = 400;
return res.send('Error 400: Post syntax incorrect.');
}
var query = {'index':req.params.index};
Node - Express Static
Kirsten Hunter
@synedra
http://www.princesspolymath.com
if (err) {
console.log(err);
res.redirect('/quotes/random');
}
res.send(result);
})
});
router.route('/quotes')
.get(function(req, res, next) {
var result = Quote.find().sort({'index': -1}).limit(10);
result.exec(function(err, quotes) {
res.send(quotes);
});
})
.post(function(req, res, next) {
if(!req.body.hasOwnProperty('content')) {
res.statusCode = 400;
return res.send('Error 400: Post syntax incorrect.');
}
quotecount = quotecount+1;
var newQuote;
if (req.body.hasOwnProperty('author')) {
newQuote = new Quote({'content': req.body.content, 'author': req.body.author, 'index': quotecount});
} else {
newQuote = new Quote({'content': req.body.content, 'index':quotecount});
}
newQuote.save(function (err, newQuote) {
if (err) return console.error(err);
res.json(quotecount);
});;
});
router.route('/quotes/:index')
.get(function(req, res, next) {
Quote.findOne({"index":req.params.index},
function (err, result) {
res.send(result);
});
})
.put(function(req, res, next) {
if(!req.body.hasOwnProperty('content') && (!req.body.hasOwnProperty('author'))) {
res.statusCode = 400;
return res.send('Error 400: Post syntax incorrect.');
}
var query = {'index':req.params.index};
Node - Express Routes
Kirsten Hunter
@synedra
http://www.princesspolymath.com
Node - Hapi Static
server.route({
method : 'GET', path : '/demo/{path*}', handler : {
directory : {
path : '../static',
listing : false,
index : true
}}})});
server.route([
{
method: 'GET',
path: '/',
handler: function(request, reply) {
reply('Hello world from hapi');
}}]);
Kirsten Hunter
@synedra
http://www.princesspolymath.com
Node - Hapi Routes
server.route([
{
method: 'GET',
path: '/api/quotes/random',
handler: function(request, reply) {
var random = Math.floor(Math.random() * quotecount);
Quote.findOne({"index":random},
function (err, result) {
reply(result);
})
}
},
Kirsten Hunter
@synedra
http://www.princesspolymath.com
Questions?
http://www.princesspolymath.com
Kirsten Hunter
@synedra
http://www.princesspolymath.com

Más contenido relacionado

Destacado

Designing irresistible APIs
Designing irresistible APIsDesigning irresistible APIs
Designing irresistible APIsKirsten Hunter
 
Becoming a Polyglot Programmer Through the Eyes of a Freelance Musician
Becoming a Polyglot Programmer Through the Eyes of a Freelance MusicianBecoming a Polyglot Programmer Through the Eyes of a Freelance Musician
Becoming a Polyglot Programmer Through the Eyes of a Freelance Musiciankickinbahk
 
Design Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et PimpleDesign Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et PimpleHugo Hamon
 
Symfony2 - Un Framework PHP 5 Performant
Symfony2 - Un Framework PHP 5 PerformantSymfony2 - Un Framework PHP 5 Performant
Symfony2 - Un Framework PHP 5 PerformantHugo Hamon
 
Prototyping in the cloud
Prototyping in the cloudPrototyping in the cloud
Prototyping in the cloudKirsten Hunter
 
Designing for developers
Designing for developersDesigning for developers
Designing for developersKirsten Hunter
 
Symfony2 en pièces détachées
Symfony2 en pièces détachéesSymfony2 en pièces détachées
Symfony2 en pièces détachéesHugo Hamon
 
API 101 Workshop from APIStrat Conference
API 101 Workshop from APIStrat ConferenceAPI 101 Workshop from APIStrat Conference
API 101 Workshop from APIStrat ConferenceKirsten Hunter
 
The History of PHPersistence
The History of PHPersistenceThe History of PHPersistence
The History of PHPersistenceHugo Hamon
 
Speed up your developments with Symfony2
Speed up your developments with Symfony2Speed up your developments with Symfony2
Speed up your developments with Symfony2Hugo Hamon
 
This stuff is cool, but...HOW CAN I GET MY COMPANY TO DO IT?
This stuff is cool, but...HOW CAN I GET MY COMPANY TO DO IT?This stuff is cool, but...HOW CAN I GET MY COMPANY TO DO IT?
This stuff is cool, but...HOW CAN I GET MY COMPANY TO DO IT?Mark Heckler
 
Monitor the quality of your Symfony projects
Monitor the quality of your Symfony projectsMonitor the quality of your Symfony projects
Monitor the quality of your Symfony projectsHugo Hamon
 
Développeurs, cachez-moi ça ! (Paris Web 2011)
Développeurs, cachez-moi ça ! (Paris Web 2011)Développeurs, cachez-moi ça ! (Paris Web 2011)
Développeurs, cachez-moi ça ! (Paris Web 2011)Hugo Hamon
 

Destacado (20)

Designing irresistible APIs
Designing irresistible APIsDesigning irresistible APIs
Designing irresistible APIs
 
Becoming a Polyglot Programmer Through the Eyes of a Freelance Musician
Becoming a Polyglot Programmer Through the Eyes of a Freelance MusicianBecoming a Polyglot Programmer Through the Eyes of a Freelance Musician
Becoming a Polyglot Programmer Through the Eyes of a Freelance Musician
 
Polyglot
PolyglotPolyglot
Polyglot
 
Design Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et PimpleDesign Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et Pimple
 
Symfony2 - Un Framework PHP 5 Performant
Symfony2 - Un Framework PHP 5 PerformantSymfony2 - Un Framework PHP 5 Performant
Symfony2 - Un Framework PHP 5 Performant
 
Liberating your data
Liberating your dataLiberating your data
Liberating your data
 
Prototyping in the cloud
Prototyping in the cloudPrototyping in the cloud
Prototyping in the cloud
 
Liberating your data
Liberating your dataLiberating your data
Liberating your data
 
Designing for developers
Designing for developersDesigning for developers
Designing for developers
 
Api 101
Api 101Api 101
Api 101
 
Facebook appsincloud
Facebook appsincloudFacebook appsincloud
Facebook appsincloud
 
Symfony2 en pièces détachées
Symfony2 en pièces détachéesSymfony2 en pièces détachées
Symfony2 en pièces détachées
 
API 101 Workshop from APIStrat Conference
API 101 Workshop from APIStrat ConferenceAPI 101 Workshop from APIStrat Conference
API 101 Workshop from APIStrat Conference
 
API First
API FirstAPI First
API First
 
Quantifying fitness
Quantifying fitnessQuantifying fitness
Quantifying fitness
 
The History of PHPersistence
The History of PHPersistenceThe History of PHPersistence
The History of PHPersistence
 
Speed up your developments with Symfony2
Speed up your developments with Symfony2Speed up your developments with Symfony2
Speed up your developments with Symfony2
 
This stuff is cool, but...HOW CAN I GET MY COMPANY TO DO IT?
This stuff is cool, but...HOW CAN I GET MY COMPANY TO DO IT?This stuff is cool, but...HOW CAN I GET MY COMPANY TO DO IT?
This stuff is cool, but...HOW CAN I GET MY COMPANY TO DO IT?
 
Monitor the quality of your Symfony projects
Monitor the quality of your Symfony projectsMonitor the quality of your Symfony projects
Monitor the quality of your Symfony projects
 
Développeurs, cachez-moi ça ! (Paris Web 2011)
Développeurs, cachez-moi ça ! (Paris Web 2011)Développeurs, cachez-moi ça ! (Paris Web 2011)
Développeurs, cachez-moi ça ! (Paris Web 2011)
 

Más de Kirsten Hunter

Quantifying your-fitness
Quantifying your-fitnessQuantifying your-fitness
Quantifying your-fitnessKirsten Hunter
 
Designing irresistible apis
Designing irresistible apisDesigning irresistible apis
Designing irresistible apisKirsten Hunter
 
Designing irresistible apis
Designing irresistible apisDesigning irresistible apis
Designing irresistible apisKirsten Hunter
 
API 101 - Understanding APIs.
API 101 - Understanding APIs.API 101 - Understanding APIs.
API 101 - Understanding APIs.Kirsten Hunter
 
Demystifying REST - SFRails meetup
Demystifying REST - SFRails meetupDemystifying REST - SFRails meetup
Demystifying REST - SFRails meetupKirsten Hunter
 
PHP Architect Virtual Cloud summit
PHP Architect Virtual Cloud summitPHP Architect Virtual Cloud summit
PHP Architect Virtual Cloud summitKirsten Hunter
 
Social Marketing with LinkedIn
Social Marketing with LinkedInSocial Marketing with LinkedIn
Social Marketing with LinkedInKirsten Hunter
 
Creating Professional Applications with the LinkedIn API
Creating Professional Applications with the LinkedIn APICreating Professional Applications with the LinkedIn API
Creating Professional Applications with the LinkedIn APIKirsten Hunter
 

Más de Kirsten Hunter (13)

Polyglot copy
Polyglot copyPolyglot copy
Polyglot copy
 
Quantifying your-fitness
Quantifying your-fitnessQuantifying your-fitness
Quantifying your-fitness
 
Designing irresistible apis
Designing irresistible apisDesigning irresistible apis
Designing irresistible apis
 
Designing irresistible apis
Designing irresistible apisDesigning irresistible apis
Designing irresistible apis
 
API 101 - Understanding APIs.
API 101 - Understanding APIs.API 101 - Understanding APIs.
API 101 - Understanding APIs.
 
Demystifying REST - SFRails meetup
Demystifying REST - SFRails meetupDemystifying REST - SFRails meetup
Demystifying REST - SFRails meetup
 
Rest schema design
Rest schema designRest schema design
Rest schema design
 
Successful developers
Successful developersSuccessful developers
Successful developers
 
Demystifying REST
Demystifying RESTDemystifying REST
Demystifying REST
 
PHP Architect Virtual Cloud summit
PHP Architect Virtual Cloud summitPHP Architect Virtual Cloud summit
PHP Architect Virtual Cloud summit
 
Social Marketing with LinkedIn
Social Marketing with LinkedInSocial Marketing with LinkedIn
Social Marketing with LinkedIn
 
LinkedIn Everywhere
LinkedIn EverywhereLinkedIn Everywhere
LinkedIn Everywhere
 
Creating Professional Applications with the LinkedIn API
Creating Professional Applications with the LinkedIn APICreating Professional Applications with the LinkedIn API
Creating Professional Applications with the LinkedIn API
 

Último

The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsRoshan Dwivedi
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024The Digital Insurer
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Paola De la Torre
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...gurkirankumar98700
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilV3cube
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024The Digital Insurer
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 

Último (20)

The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of Brazil
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 

Polyglot

  • 1. Becoming a Polyglot Simple API Engines in 5 Languages Kirsten Hunter @synedra http://www.princesspolymath.com
  • 3. Kirsten Hunter @synedra http://www.princesspolymath.com The Challenge Siloed Communities Poor Understanding of Language Differences Fear of the Unknown Exclusivity
  • 4. Kirsten Hunter @synedra http://www.princesspolymath.com The Solution • Simple API Project • Mongo Backend • Single Page Application Front End • Identically functioning API Engines in 5 Languages
  • 5. Kirsten Hunter @synedra http://www.princesspolymath.com Fortune Cookie Server Engines use data from mongo db Each engine presents full API capability * GET * PUT * POST * DELETE Github / Docker synedra/polyglot c9.io python image clone github repo
  • 7. Kirsten Hunter @synedra http://www.princesspolymath.com Mongo Setup load quoteid.jsonStartup mongo /etc/init.d/mongodb start { "content": "Boredom: the desire for desires.", "index": 1998, "author": "Leo Tolstoy" }, mongoimport --collection quotes --file quoteid.json --type json jsonArray
  • 9. Kirsten Hunter @synedra http://www.princesspolymath.com RAML 0.8 title: Fortune Cookie version: V1 baseUri: http://www.fortunecookieserver.com/api/v1 /quotes: displayName: Quotes get: description: Get a list of quotes queryParameters: random: description: Retrieve a random quote required: false default: false type: boolean responses: 200: body: application/json: example: | [ {"content":"That which does not kill us makes us stronger.", "author":"Sun Yi", "id":1 } ]
  • 10. Kirsten Hunter @synedra http://www.princesspolymath.com RAML 0.8 title: Fortune Cookie version: V1 baseUri: http://www.fortunecookieserver.com/api/v1 /quotes: displayName: Quotes get: description: Get a list of quotes queryParameters: random: description: Retrieve a random quote required: false default: false type: boolean responses: 200: body: application/json: example: | [ {"content":"That which does not kill us makes us stronger.", "author":"Sun Yi", "id":1 } ]
  • 11. Kirsten Hunter @synedra http://www.princesspolymath.com RAML 0.8 title: Fortune Cookie version: V1 baseUri: http://www.fortunecookieserver.com/api/v1 /quotes: displayName: Quotes get: description: Get a list of quotes queryParameters: random: description: Retrieve a random quote required: false default: false type: boolean responses: 200: body: application/json: example: | [ {"content":"That which does not kill us makes us stronger.", "author":"Sun Yi", "id":1 } ]
  • 12. Kirsten Hunter @synedra http://www.princesspolymath.com { "swagger": "2.0", "info": { "title": "Fortune Cookie API", "description": "Random quote of the day", "version": "1.0.0" }, "host": "api.fortunecookieserver.com", "schemes": [ "http" ], "basePath": "/v1", "produces": [ "application/json" ], "paths": { "/quotes": { "get": { "summary": "Quotes", "description": "This is a quote server.n", "tags": [ "Quotes" ], "responses": { "200": { "description": "An array of products", "schema": { "type": "array", "items": { "$ref": "#/definitions/Quote" } } },
  • 13. Kirsten Hunter @synedra http://www.princesspolymath.com { "swagger": "2.0", "info": { "title": "Fortune Cookie API", "description": "Random quote of the day", "version": "1.0.0" }, "host": "api.fortunecookieserver.com", "schemes": [ "http" ], "basePath": "/v1", "produces": [ "application/json" ], "paths": { "/quotes": { "get": { "summary": "Quotes", "description": "This is a quote server.n", "tags": [ "Quotes" ], "responses": { "200": { "description": "An array of products", "schema": { "type": "array", "items": { "$ref": "#/definitions/Quote" } } },
  • 14. Kirsten Hunter @synedra http://www.princesspolymath.com { "swagger": "2.0", "info": { "title": "Fortune Cookie API", "description": "Random quote of the day", "version": "1.0.0" }, "host": "api.fortunecookieserver.com", "schemes": [ "http" ], "basePath": "/v1", "produces": [ "application/json" ], "paths": { "/quotes": { "get": { "summary": "Quotes", "description": "This is a quote server.n", "tags": [ "Quotes" ], "responses": { "200": { "description": "An array of products", "schema": { "type": "array", "items": { "$ref": "#/definitions/Quote" } } },
  • 15. Kirsten Hunter @synedra http://www.princesspolymath.com PHP - Mongo Setup// Routes $app->group('/api/quotes', function () { // Setup DB connection $mongo = new MongoClient('mongodb://localhost:27017'); $mongo->connect(); $db = $mongo->test; $quotes = $db->selectCollection('quotes'); $this->get('', function (Request $request, Response $response, array $args) use ($quotes) { $this->logger->info("Fetching 10 records…n"); $results = []; foreach ($quotes->find([], ['_id' => 0])->sort(['index' => -1])->limit(10) as $quote) { $results[] = $quote; } $response ->getBody()->write(json_encode($results, JSON_PRETTY_PRINT)); $newResponse = $response->withHeader( 'Content-type', 'application/json; charset=utf-8' ); return $newResponse; });
  • 16. Kirsten Hunter @synedra http://www.princesspolymath.com PHP - Route// Routes $app->group('/api/quotes', function () { // Setup DB connection $mongo = new MongoClient('mongodb://localhost:27017'); $mongo->connect(); $db = $mongo->test; $quotes = $db->selectCollection('quotes'); $this->get('', function (Request $request, Response $response, array $args) use ($quotes) { $this->logger->info("Fetching 10 records…n"); $results = []; foreach ($quotes->find([], ['_id' => 0])->sort(['index' => -1])->limit(10) as $quote) { $results[] = $quote; } $response ->getBody()->write(json_encode($results, JSON_PRETTY_PRINT)); $newResponse = $response->withHeader( 'Content-type', 'application/json; charset=utf-8' ); return $newResponse; });
  • 17. Kirsten Hunter @synedra http://www.princesspolymath.com PHP - Static $app->get('/', function(Request $request, Response $response, $args) { return $response->getBody()->write('Hello World from PHP Slim'); }); $app->get('/demo', function(Request $request, Response $response, $args) { $content = file_get_contents('../static/index.html'); return $response->getBody()->write($content); });
  • 18. Kirsten Hunter @synedra http://www.princesspolymath.com Perl - Mongo Setup use Dancer; use Dancer::Plugin::CRUD; use MongoDB; my $client = MongoDB->connect(); my $db = $client->get_database('test'); my $quotes = $db->get_collection('quotes'); my $json = JSON->new->allow_nonref; set content_type => 'application/json'; get '/' => sub{ return {message => "Hello from Perl and Dancer"}; }; set public => path(dirname(__FILE__), '..', 'static'); get "/demo/?" => sub { send_file '/index.html' }; get '/api/quotes' => sub { my $response = $quotes->find()->sort({'index' => -1})->limit(10); my @results = (); while(my $quote = $response->next) { push (@results, {"content" => $quote->{'content'}, "index" => $quote->{'index'}, "author" => $quote->{'author'} } ); } if (! scalar (@results)) { status 404; return; } return @results; };
  • 19. Kirsten Hunter @synedra http://www.princesspolymath.com Perl - Static Files use Dancer; use Dancer::Plugin::CRUD; use MongoDB; my $client = MongoDB->connect(); my $db = $client->get_database('test'); my $quotes = $db->get_collection('quotes'); my $json = JSON->new->allow_nonref; set content_type => 'application/json'; get '/' => sub{ return {message => "Hello from Perl and Dancer"}; }; set public => path(dirname(__FILE__), '..', 'static'); get "/demo/?" => sub { send_file '/index.html' }; get '/api/quotes' => sub { my $response = $quotes->find()->sort({'index' => -1})->limit(10); my @results = (); while(my $quote = $response->next) { push (@results, {"content" => $quote->{'content'}, "index" => $quote->{'index'}, "author" => $quote->{'author'} } ); } if (! scalar (@results)) { status 404; return; } return @results; };
  • 20. Kirsten Hunter @synedra http://www.princesspolymath.com Perl - Routes get '/api/quotes' => sub { my $response = $quotes->find()->sort({'index' => -1})->limit(10); my @results = (); while(my $quote = $response->next) { push (@results, {"content" => $quote->{'content'}, "index" => $quote->{'index'}, "author" => $quote->{'author'} } ); } if (! scalar (@results)) { status 404; return; } return @results; };
  • 21. Kirsten Hunter @synedra http://www.princesspolymath.com Python - Mongo Setup resp = Response(dumps(quotes, default=default), mimetype='application/json') return resp def delete(self, quote_id): print "Quote id is %s" % quote_id try: mongo.db.quotes.remove({ 'index': int(quote_id) }) except Exception as ve: print ve abort(400, str(ve)) return '', 204 def put(self, quote_id): args = parser.parse_args() if not (args['content'] or args['author']): return 'Missing data', 400 existing_quote = mongo.db.quotes.find_one({"index": int(quote_id)}) args['content'] = args['content'] if args['content'] else existing_quote["content"] args['author'] = args['author'] if args['author'] else existing_quote["author"] try: mongo.db.quotes.update({ 'index': quote_id },{ '$set': { 'content': args['content'], 'author': args['author'] } }, upsert=False) except Exception as ve: print ve abort(400, str(ve)) return 201 # TodoList # shows a list of all todos, and lets you POST to add new tasks class QuoteList(Resource): def get(self): quotes = mongo.db.quotes.find().sort("index", -1).limit(10) resp = Response(dumps(quotes, default=default), mimetype='application/json') return resp
  • 22. Kirsten Hunter @synedra http://www.princesspolymath.com Python - Static return resp … @app.route('/') def hello_world(): return 'Hello from Flask!' @app.route('/demo') def serve_page(): return send_from_directory(STATIC_ROOT, "index.html") abort(400, str(ve)) return '', 204 def put(self, quote_id): args = parser.parse_args() if not (args['content'] or args['author']): return 'Missing data', 400 existing_quote = mongo.db.quotes.find_one({"index": int(quote_id)}) args['content'] = args['content'] if args['content'] else existing_quote["content"] args['author'] = args['author'] if args['author'] else existing_quote["author"] try: mongo.db.quotes.update({ 'index': quote_id },{ '$set': { 'content': args['content'], 'author': args['author'] } }, upsert=False) except Exception as ve: print ve abort(400, str(ve)) return 201 # TodoList # shows a list of all todos, and lets you POST to add new tasks class QuoteList(Resource): def get(self): quotes = mongo.db.quotes.find().sort("index", -1).limit(10) resp = Response(dumps(quotes, default=default), mimetype='application/json') return resp def post(self): args = parser.parse_args()
  • 23. Kirsten Hunter @synedra http://www.princesspolymath.com Python - Route # shows a list of all quotes, and lets you POST to add new quotes class QuoteList(Resource): def get(self): quotes = mongo.db.quotes.find().sort("index", -1).limit(10) resp = Response(dumps(quotes, default=default), mimetype='application/json') return resp def post(self): args = parser.parse_args() quotes = mongo.db.quotes.find().sort("index", -1).limit(1) print quotes[0] args["index"] = int(quotes[0]["index"]) + 1 print args try: mongo.db.quotes.insert(args) except Error as ve: abort(400, str(ve)) return 201 api.add_resource(QuoteList, '/api/quotes') api.add_resource(Quote, '/api/quotes/<quote_id>')
  • 24. Kirsten Hunter @synedra http://www.princesspolymath.com Ruby - Mongo Setup end get '/' do content_type :html "Hello World from Sinatra" end before do content_type 'application/json' end namespace "/api" do # list all get '/quotes' do Quote.all.desc(:index).limit(10).to_json end get '/quotes/random' do newnumber = Quote.count random_num = rand(newnumber) quote = Quote.find_by(index: random_num.to_i) return status 404 if quote.nil? quote.to_json end # view one get '/quotes/:index' do quote = Quote.find_by(index: params[:index].to_i) return status 404 if quote.nil? quote.to_json end # create post '/quotes' do newnumber = Quote.count + 1 @json = JSON.parse(request.body.read) quote = Quote.new( content: @json['content'], author: @json['author'], index: newnumber) quote.save newnumber.to_json end # update put '/quotes/:index' do
  • 25. Kirsten Hunter @synedra http://www.princesspolymath.com end get '/' do content_type :html "Hello World from Sinatra" end before do content_type 'application/json' end namespace "/api" do # list all get '/quotes' do Quote.all.desc(:index).limit(10).to_json end get '/quotes/random' do newnumber = Quote.count random_num = rand(newnumber) quote = Quote.find_by(index: random_num.to_i) return status 404 if quote.nil? quote.to_json end # view one get '/quotes/:index' do quote = Quote.find_by(index: params[:index].to_i) return status 404 if quote.nil? quote.to_json end # create post '/quotes' do newnumber = Quote.count + 1 @json = JSON.parse(request.body.read) quote = Quote.new( content: @json['content'], author: @json['author'], index: newnumber) quote.save newnumber.to_json end # update put '/quotes/:index' do Ruby - Static
  • 26. Kirsten Hunter @synedra http://www.princesspolymath.com namespace "/api" do # list all get '/quotes' do Quote.all.desc(:index).limit(10).to_json end get '/quotes/random' do newnumber = Quote.count random_num = rand(newnumber) quote = Quote.find_by(index: random_num.to_i) return status 404 if quote.nil? quote.to_json end # view one get '/quotes/:index' do quote = Quote.find_by(index: params[:index].to_i) return status 404 if quote.nil? quote.to_json end # create post '/quotes' do newnumber = Quote.count + 1 @json = JSON.parse(request.body.read) quote = Quote.new( content: @json['content'], author: @json['author'], index: newnumber) quote.save newnumber.to_json end # update put '/quotes/:index' do @json = JSON.parse(request.body.read) quote = Quote.find_by(index: params[:index].to_i) return status 404 if quote.nil? quote.update( content: @json['content'], author: @json['author'] ) quote.save params[:index].to_json end Ruby - Route
  • 27. Kirsten Hunter @synedra http://www.princesspolymath.com app.use('/api', router); // REST API router.route('/quotes/random') .get(function(req, res, next) { var random = Math.floor(Math.random() * quotecount); Quote.findOne({"index":random}, function (err, result) { if (err) { console.log(err); res.redirect('/quotes/random'); } res.send(result); }) }); router.route('/quotes') .get(function(req, res, next) { var result = Quote.find().sort({'index': -1}).limit(10); result.exec(function(err, quotes) { res.send(quotes); }); }) .post(function(req, res, next) { if(!req.body.hasOwnProperty('content')) { res.statusCode = 400; return res.send('Error 400: Post syntax incorrect.'); } quotecount = quotecount+1; var newQuote; if (req.body.hasOwnProperty('author')) { newQuote = new Quote({'content': req.body.content, 'author': req.body.author, 'index': quotecount}); } else { newQuote = new Quote({'content': req.body.content, 'index':quotecount}); } newQuote.save(function (err, newQuote) { if (err) return console.error(err); res.json(quotecount); });; }); router.route('/quotes/:index') .get(function(req, res, next) { Quote.findOne({"index":req.params.index}, function (err, result) { res.send(result); Node - Mongo Setup
  • 28. Kirsten Hunter @synedra http://www.princesspolymath.com if (err) { console.log(err); res.redirect('/quotes/random'); } res.send(result); }) }); router.route('/quotes') .get(function(req, res, next) { var result = Quote.find().sort({'index': -1}).limit(10); result.exec(function(err, quotes) { res.send(quotes); }); }) .post(function(req, res, next) { if(!req.body.hasOwnProperty('content')) { res.statusCode = 400; return res.send('Error 400: Post syntax incorrect.'); } quotecount = quotecount+1; var newQuote; if (req.body.hasOwnProperty('author')) { newQuote = new Quote({'content': req.body.content, 'author': req.body.author, 'index': quotecount}); } else { newQuote = new Quote({'content': req.body.content, 'index':quotecount}); } newQuote.save(function (err, newQuote) { if (err) return console.error(err); res.json(quotecount); });; }); router.route('/quotes/:index') .get(function(req, res, next) { Quote.findOne({"index":req.params.index}, function (err, result) { res.send(result); }); }) .put(function(req, res, next) { if(!req.body.hasOwnProperty('content') && (!req.body.hasOwnProperty('author'))) { res.statusCode = 400; return res.send('Error 400: Post syntax incorrect.'); } var query = {'index':req.params.index}; Node - Express Static
  • 29. Kirsten Hunter @synedra http://www.princesspolymath.com if (err) { console.log(err); res.redirect('/quotes/random'); } res.send(result); }) }); router.route('/quotes') .get(function(req, res, next) { var result = Quote.find().sort({'index': -1}).limit(10); result.exec(function(err, quotes) { res.send(quotes); }); }) .post(function(req, res, next) { if(!req.body.hasOwnProperty('content')) { res.statusCode = 400; return res.send('Error 400: Post syntax incorrect.'); } quotecount = quotecount+1; var newQuote; if (req.body.hasOwnProperty('author')) { newQuote = new Quote({'content': req.body.content, 'author': req.body.author, 'index': quotecount}); } else { newQuote = new Quote({'content': req.body.content, 'index':quotecount}); } newQuote.save(function (err, newQuote) { if (err) return console.error(err); res.json(quotecount); });; }); router.route('/quotes/:index') .get(function(req, res, next) { Quote.findOne({"index":req.params.index}, function (err, result) { res.send(result); }); }) .put(function(req, res, next) { if(!req.body.hasOwnProperty('content') && (!req.body.hasOwnProperty('author'))) { res.statusCode = 400; return res.send('Error 400: Post syntax incorrect.'); } var query = {'index':req.params.index}; Node - Express Routes
  • 30. Kirsten Hunter @synedra http://www.princesspolymath.com Node - Hapi Static server.route({ method : 'GET', path : '/demo/{path*}', handler : { directory : { path : '../static', listing : false, index : true }}})}); server.route([ { method: 'GET', path: '/', handler: function(request, reply) { reply('Hello world from hapi'); }}]);
  • 31. Kirsten Hunter @synedra http://www.princesspolymath.com Node - Hapi Routes server.route([ { method: 'GET', path: '/api/quotes/random', handler: function(request, reply) { var random = Math.floor(Math.random() * quotecount); Quote.findOne({"index":random}, function (err, result) { reply(result); }) } },