O documento apresenta uma introdução ao desenvolvimento de aplicações na plataforma Google App Engine usando a linguagem Python. Em três frases ou menos, o documento explica como iniciar um projeto simples no App Engine, mapeia URLs para código Python e armazena e consulta dados no banco de dados do App Engine.
2. Proposta
Apresentar de forma simples,
prática e ao alcance de todos uma
alternativa para a criação de
aplicativos na web escaláveis.
http://slideshare.net/chesterbr
8. Dilema da Hospedagem
Enquanto o site não fizer sucesso,
vou ter que custear a hospedagem
Quando ele crescer e meu provedor não
aguentar, vou ter que mudar de provedor
(e talvez de tecnologia)
Quanto isso vai custar?
9. Dilema da Arquitetura
Projetar uma arquitetura para escalar
exige tempo e skills, que poderiam ser
aplicados na aplicação em si (em
particular no início), mas deixar isso pra
depois pode gerar um problema difícil
11. Equilíbrio
Crie seu aplicativo web rapidamente e
a custo zero. Com alguns cuidados, ele
vai se adaptar a volumes de tráfego
maiores e o custo de hospedagem será
proporcional a este aumento.
12. Obstáculos
O App Engine não é completamente
diferente de outras arquiteturas, mas é
preciso aprender coisas novas
Nossa proposta hoje é ver essas
coisas novas na prática
15. Java
É uma opção para quem já conhece ela
(ou C#), mas muita coisa vai ter que
ser feita do “jeito App Engine”
(e não é lá muito popular hoje em dia...)
17. Go
Criada pelo próprio Google, é boa em
tarefas que exigem muita CPU (é
compilada e com tipos estáticos), mas o
suporte ainda é experimental* e você
vai ter pouca companhia
* eles mesmos alertam: http://code.google.com/appengine/docs/
22. Ingredientes
● Google App Engine SDK para Python
● Seu editor de textos favorito
● Internet (para colocar no ar)
(opcional: Eclipse + plugin do App Engine)
http://code.google.com/appengine/downloads.html
23. SDK (Launcher) no Windows
http://code.google.com/appengine/downloads.html
24. SDK (Launcher) no Mac
http://code.google.com/appengine/downloads.html
28. app.yaml
Descreve o seu aplicativo para os
servidores do Google (nome, versão,
linguagem), associando os endereços
(ex.: “/”, “/noticias”) com o código
45. main.py “sério”
from google.appengine.ext import webapp
from google.appengine.ext.webapp import util
class MainHandler(webapp.RequestHandler):
def get(self):
self.response.out.write('Hello world!')
def main():
application = webapp.WSGIApplication(
[('/', MainHandler)],
debug=True)
util.run_wsgi_app(application)
if __name__ == '__main__':
main()
46. webapp
É a biblioteca (framework) que mapeia
(através de um objeto WSGIApplication)
cada caminho (ou grupo deles) para a
classe RequestHandler apropriada
48. Recuperando a notícia
...
class NoticiaHandler(webapp.RequestHandler):
def get(self, id_not):
# id_not contém o item entre
# parênteses em '/noticia/(w+)'
# ex.: /noticia/123 => id_not=123
noticia = dao.busca_noticia(id_not)
# montando o html com os dados:
html = template.render('/noticia.html',
noticia)
self.response.out.write(noticia)
...
50. Parâmetros e REST
...
class AlgumHandler(webapp.RequestHandler):
def get(self):
# parâmetros de formulário (GET, POST):
p = self.request.get('nome_parametro')
# Outros verbos HTTP (i.e., REST):
def post(self):
...
def delete(self):
...
...
51. Alternativas
O webapp é minimalista, mas se isso
não agradar, o App Engine suporta
outros frameworks populares
http://www.franciscosouza.com.br/tag/frameworks/
54. Bancos Relacionais
Têm implementações maduras, facilitam
operações robustas (ACID), mapeiam
(mais-ou-menos) com classes/objetos,
performam bem em servidor único e
(quase) todo mundo sabe usar SQL
mas...
55. Bancos Relacionais
...é difícil paralelizar sem afetar o
aplicativo e/ou abrir mão de algumas
dessas vantagens, o que tem levado à
busca de novas alternativas
57. Baseada no Bigtable, que é
“Um mapa ordenado esparso, distribuído,
persistente e multidimensional. O mapa é
indexado por chave de linha, chave de
coluna e data/hora; cada valor no mapa é
um array não-interpretado de bytes”
http://research.google.com/archive/bigtable-osdi06.pdf
58. Na prática
Vamos usar uma estrutura mais simples,
na qual o aplicativo vai cuidar de mais
coisas (ex.: consistência de dados), mas
o sistema poderá escalar facilmente
usando a estrutura do Google
59. Boa notícia
O App Engine reduz esse trabalho com
classes que encapsulam o Datastore na
forma de “entidades” e permitem até
consultar em estilo SQL (GQL)
(só tome cuidado com as diferenças)
60. Exemplo
...
class Noticia(db.Model):
id = db.IntegerProperty(required=True)
titulo = db.StringProperty(required=True)
texto = db.StringProperty(required=True)
editoria = db.StringProperty(required=True,
choices=set(['politica', 'esportes',
'informatica']))
data_criacao = db.DateTimeProperty(
auto_now=True)
data_publicacao = db.DateTimeProperty()
autor = db.UserProperty()
avaliacao = db.IntegerProperty()
acessos = db.IntegerProperty()
...
61. Cadastrando (put)
...
noticia = Noticia(
id = 123,
titulo = 'SOPA foi pro vinagre!',
texto = 'bla bla bla bla',
editoria = 'politica')
noticia.put()
...
62. Consulta (query)
...
# Montando a query
q = Noticia.all()
q.filter("editoria =", "esportes")
q.order("-data_publicacao")
# Executando a query
noticias = q.fetch(10)
for noticia in noticias:
print noticia.titulo
...
63. Consulta (query) com GQL
...
# Montando a query
q = db.GqlQuery("SELECT * FROM Noticia " +
"WHERE editoria = :1" +
"ORDER BY data_publicacao DESC",
"esportes")
# Executando a query (não mudou nada!)
noticias = q.fetch(10)
for noticia in noticias:
print noticia.titulo
...
64. Índices
Todas as consultas são baseadas em
índices definidos no index.yaml (mas
criados automaticamente à medida que
você testa o site no servidor local)
(sim, vale dar uma espiada no arquivo)
65. Restrições
Como as buscas usam índices, existem
algumas restrições. Por exemplo,
desigualdades (<, <=, >=, >, !=) só podem
afetar um campo por consulta.
http://bit.ly/y3xtkk (Documentação: Restrições)
67. Memcache
Alguns dados são muito mais acessados
que outros (working set), e o AppEngine
disponbiliza o Memcache para manter
esses dados em RAM
68. Memcache
...
def busca_noticia(self, id):
cache = memcache.Client()
noticia = cache.get(id)
if noticia is None:
result = Noticia.all().filter("id =",
int(id)).fetch(1)
if result:
noticia = result[0]
cache.add(id, noticia)
return noticia
...
(não esqueça do cache.delete() se os dados mudarem)
82. O poder é de vocês!
É preciso estudar e experimentar, mas
o App Engine está ao alcance de todos.
Basta começar!
http://code.google.com/intl/pt-BR/appengine/docs/
84. Créditos e Licenciamento
Esta apresentação está disponível para uso e reuso
sob os termos da licença Creative Commons “by-nc” 3.0,
observadas as exceções abaixo
Fotos e ilustrações são em sua maioria logomarcas dos produtos e
projetos referenciados (inclusos sob premissa de “fair use”) e ilustrações
de uso supostamente livre cuja autoria foi mencionada sempre que
possível (correções são bem-vindas). Tais elementos são de propriedade
de seus autores, e não estão cobertos pela licença acima, não havendo
qualquer relação deles com o autor