playframework-intro
-
Upload
alberto-souza -
Category
Technology
-
view
592 -
download
0
description
Transcript of playframework-intro
O MÍNIMO SOBRE MIM
ALBERTO SOUZAInstrutor e desenvolvedor pela .Caelum
Escritor do , usuário forte doPlay :) e commiter do VRaptor4.
Livro PlayFramework na prática
SAINDO DO ZERO COM O PLAYFRAMEWORKNÃO VOU GARANTIR QUE É FÁCIL COMO DIZEM POR AÍ
/ alots.wordpress.com @alberto_souza
MÍNIMO PARA RODAR O PRIMEIRO EXEMPLO
DOWNLOAD DO SDK
CRIANDO UM NOVO PROJETOplay new agendatech
ENTRANDO NO CONSOLE DO PLAYplay
IMPORTAR PARA O ECLIPSEeclipse
SUBIR O SERVIDOR~run
EXEMPLO DE ACESSOhttp://localhost:9000/eventos
QUEM TRATA?
ARQUIVO DE ROTAS!
GET /eventos controllers.EventosController.lista()
# Map static resources from the /public folder to the /assets URL pathGET /assets/*file controllers.Assets.at(path="/public", file)
package controllers;
import play.mvc.*;
public class EventosController extends Controller {
public static Result lista() { List<Evento> instrutores = Eventos.paraAcontecer(); return //tem que ir para a view }
}
public class EventosController extends Controller {
public static Result lista() { List<Evento> instrutores = Eventos.paraAcontecer(); return ok(views.html.eventos.lista.render(aprovados)); }
}
ISSO MESMO, INVOCAMOS UM MÉTODO QUENOS RETORNA A VIEW!
@(lista: List[Evento])
@for(evento <- lista){ @evento.getNome() }
ROTAS E VIEWS VIRAM CLASSES!
E QUANDO TIVER UMA ALTERAÇÃO?
MEXA LIVREMENTE QUE O PLAY FICAATUALIZANDO :)
DECISÃO SOBRE TECNOLOGIASJá decidiram algumas, vamos só olhar rapidamente
PERSISTÊNCIAEbeanJPA
public class EventosController extends Controller {
public static Result index() { List<Evento> eventos = Ebean.find(Evento.class).findList(); List<Evento> eventos = JPA.em().ah...UmaFormaFacil() return ok(view.instrutores.html.index.render(eventos)); }
}
REFLEXÃO SOBRE MÉTODOS ESTÁTICOS
MANTER ESTADO NO CONTROLLER? QUAL OMOTIVO?
VOLTANDO PARA AS TECNOLOGIAS
PRECISAVAM DE UMA VIEW QUE FOSSE EMSCALA
PARA A VIEW, TWIRL
@(eventos:List[Evento])
@if(flash().get("sucesso")!=null){ <span class="msg_sucesso">@flash().get("sucesso")</span>}<ul> @for(evento <- eventos) { @detalhe_lista(evento) }</ul>
O AGENDATECH PRECISA TUITAR SOBRE OSEVENTOS
AKKA PARA TAREFAS ASSÍNCRONAS
ActorRef actor = SystemActor.apply(SendTwitterActor.class); actor.tell(evento,null);
NECESSÁRIO PEGAR FOTOS LEGAIS SOBRE OEVENTO
API PRONTA PARA REQUESTS EXTERNOS
WSRequestHolder requester = WS.url("https://api.instagram.com/v1/tags/qcon2014/..."); requester.get();
E QUAL SERVIDOR VAMOS USAR PARADEPLOYAR?
NETTY COMO SERVIDOR HTTPE A ESPECIFICAÇÃO DE SERVLETS?
RAZÕES PARA NÃO SEGUIR A SPECNão precisar ficar criando adapter para as implementaçõesComo lidar com as respostas assíncronas?
MEGA VANTAGENS(REATIVO)PELO MENOS NA MINHA OPINIÃO
TUDO ASSÍNCRONO
VOLTANDO AO ASSUNTO SOBRE REQUISIÇÕESPARA SERVIÇOS EXTERNOS
public static Result ultimasFotos(String hashtag){ WSRequestHolder requester = WS.url("https://api.instagram.com/v1/tags/"+hashtag+"/...");
return ok(requester.get().get().getBody());}
E SE O INSTAGRAM ESTIVER LERDO?
NÃO QUEREMOS SEGURAR A THREAD!
public static Promise<Result> ultimasFotos(String hashtag){ WSRequestHolder requester = WS.url("https://api.instagram.com/v1/tags/"+hashtag+"/...");
Promise<Response> esperandoAResposta = requester.get(); esperandoAResposta.map(response -> ok(response.getBody())); }
ESSA É UMA DAS CHAVES DO SUCESSOPARA SUA FELICIDADE, PODE NÃO SER SUFICIENTE
COLOCANDO MAIS SERVIDORESESCALONAMENTO HORIZONTAL
E O USUÁRIO LOGADO FICA ONDE?
NO CLIENTESTATELESS PARA A VITÓRIA
SEM OBJETOS COMPLEXOS NA SESSION
//não compila! session().put("infoDoUsuario",objetoUsuario);
//agora sim session().put("infoDoUsuario",algumaChaveDoUsuario);
COLOCAR VÁRIOS SERVIDORES FICOU FÁCILEXEMPLO HAPROXY
backend servers balance roundrobin
option httpclose option redispatch
server play1 127.0.0.1:8081 maxconn 32 server play2 127.0.0.1:8082 maxconn 32
SEMPRE QUE UM EVENTO É APROVADO,ATUALIZA A HOME
COMO FAZER?
MODO ANTIGOPINGS DE TEMPOS EM TEMPOS NO SERVIDOR
JEITO MAIS MODERNO
SERVER-SENT EVENTSREATIVO MAIS UMA VEZ!
AGORA BASTA FAZER O REGISTRO
var feed = new EventSource('@routes.AtualizaHomeController.registra())');
feed.addEventListener('message',handlerDoEvento, false);
PUSH NOTIFICATIONS
object AtualizaHomeController extends Controller {
val (chatOut, chatChannel) = Concurrent.broadcast[JsonNode] def registra() = Action { Ok.feed(chatOut &> EventSource()) .as("text/event-stream") }}
E COMO PUSHAR INFORMAÇÕES?
AtualizaHomeController.chatChannel().push(Json.toJson(eventoAprovado));
FECHANDO!
GERANDO UMA DISTRIBUIÇÃOplay dist
DEPLOYunzip agendatech.zip
deploy/bin/agendatech
ALGUMAS EMPRESAS QUE JÁ USAMCourseraLinkedinKlout
LIVRO:
BLOG:
bit.ly/1hV0NMm
alots.wordpress.com
OBRIGADO! / Alberto Souza @alberto_souza