Linguagens e Ambientes de Programação (2017/2018)



Teórica 22 (24/mai/2018)

XML e seu processamento em JavaScript.
JSON e MongoDB.
Scripting do lado do servidor - Node.js.
Toolkits e frameworks para a Web.
Exemplo dum framework para a Web - Express.js.



XML

XML (eXtensible Markup Language) é uma linguagem que permite representar informação de forma estruturada. Nos sistemas de informação atuais, o XML é imensamente usado, tanto para representar informação armazenada nos servidores, como para representar informação transferidas entre servidores.

Olhando para um documento XML, o aspeto geral é semelhante ao duma página Web (documento HTML). No entanto há importantes diferenças entre os dois formatos:

Em todo o caso, o formato HTML é um caso particular do formato XML, se esquecermos o detalhe do formato HTML sem um pouco menos rígido sintaticamente.

Para exemplificar, eis um pequeno documento XML com alguma informação sobre uma senhora chamada Alice e os seus filhos:

Neste exemplo são usadas apenas duas marcas: <person> e <children>. Quando as marcas são bem escolhidas, o documento XML torna-se autoexplicativo. Você deverá conseguir responder a estas perguntas: Qual a idade de Alice? Quantos filhos tem? Qual o nome e idade dos filhos? Ela tem algum neto?

De forma geral, um documento XML tem a estrutura duma árvore n-ária. A parte do texto correspondente à árvore completa ou qualquer subárvore chama-se um elemento XML.

Sintaticamente, cada elemento XML começa com a abertura duma marca, por exemplo, <person>, e termina com o fecho desta mesma marca, </person>. A abertura duma marca pode, opcionalmente, incluir alguns atributos com os valores correspondentes, como neste exemplo <person gender='M'>. Finalmente, entre a abertura e o fecho duma marca, encontra-se a conteúdo do elemento, que consiste em texto simples com subelementos XML intercalados. A parte de texto simples é tradicionalmente chamada de PCDATA. No exemplo da Alice, o conteúdo do elemento principal consiste no seguinte: o segmento de PCDATA "Alice"; em seguida, um subelemento a descrever os filhos de Alice; finalmente, o segmento de PCDATA "35 anos de idade".

Um elemento sem conteúdo, como <children></children> pode ser abreviado <children/>.

Observemos agora um documento XML grande, contendo uma famosa comédia escrita por William Shakespeare: A Midsummer Night's Dream.

Tecnologias associadas ao XML

Há um grande número de tecnologias associadas ao XML. Eis algumas:

Processamento de XML em JavaScript

Quando, a resposta a um pedido AJAX vem em XML temos de saber processar o documento recebido. A forma de processar XML é idêntica à do processamento de HTML. Está aqui o essencial do que é preciso saber: The XML DOM.

Eis um pequeno exemplo que ilustra tudo o que é preciso saber se quisermos processar um documento XML sem o alterar:

Código do exemplo:


JSON e MongoDB

JSON (JavaScript Object Notation) é outro formato que permite representar informação de forma estruturada. Tem o mesmo poder expressivo do XML, mas é mais simples.

O formato JSON é independente de qualquer linguagem de programação, mas usa as mesmas convenções sintáticas dos objetos literais do JavaScript. Cada objeto JSON é constituido por uma coleção de pares etiqueta/valor e as sequências são representadas por arrays.

Eis um exemplo em XML

e a respestiva tradução em JSON, feita neste site:

O sistema de base de dados MongoDB guarda documentos em formato JSON, permitindo indexar por quaisquer campos, mesmo que estejam muito aninhados no interior de subobjetos.

A naturalidade da modelação dos dados e o seu poder de indexação têm tornado o MongoDB bastante popular (apesar de tudo está em 4º lugar atrás de concorrente bem mais poderosos).

O MongoDB é um "document-oriented database system" e a facilidade e informalidade da sua utilização é bem-vinda em muitas aplicações Web. Contudo, se a base de dados tiver uma grande quantidade de relações e de normalização, então deverá ser preferivel usar uma base de dados relacional clássica.


Scripting do lado do servidor - Node.js

Como se disse na aula anterior, em 1993 foram introduzidos novos protocolos que passaram a permitir maior dinâmismo do lado do servidor, em particular, a possibilidade de gerar dinamicamente páginas HTML. Nessa altura a programação do lado do servidor começou a ser feita essencialmente em Perl e C, mas rapidamente começaram a aparecer e a ser usadas novas linguagens. Exemplos de linguagens usadas atualmente do lado do servidor: PHP, Java, ASP, Python, Ruby, Scala, TCL, JavaScript.

Um desenvolvimento relativamente recente, foi o aparecimento do Node.js. Trata-se dum interpretador de JavaScript que vem com uma biblioteca que o torna apto a ser usado do lado do servidor. Foi criado em 2009 por Ryan Dahl. Tem tido uma adoção rápida pela comunidade da programação para a Web.

Baseia-se na ideia de usar o modelo de eventos, já conhecido do lado do cliente, também do lado do servidor. Cada pedido que chega é considerado um evento e é tratado assincronamente. Tal como no caso do cliente, existe uma thread dos eventos que executa continuamente um ciclo que retira e processa os eventos guardados numa fila de espera. Os eventos são tratados sequencialmente e enquanto não terminar o tratamento dum evento não se inicia o tratamento do seguinte.

Apetece criticar o uso do modelo de eventos do lado do servidor argumentando que o tratamento dum pedido pode ser demorado - realmente pode envolver a consulta duma base de dados ou o carregamento dum ficheiro grande, por exemplo. Mas isso não é problema no caso do Node.js porque ele tem o cuidado de lançar em threads auxiliares as operações de biblioteca mais demoradas, gastando pouco tempo na thread dos eventos. Por outras palavras, muitas das operações da biblioteca do Node.js funcionam de forma assíncrona. As threads auxiliares, ao terminarem, geram elas mesmo eventos de finalização que permitem ao programador aceder ao resultado da operação e prosseguir com mais ações. No exemplo abaixo, o método de biblioteca readFile faz o carregamento integral do ficheiro cujo nome é passado no primeiro argumento. O últmo argumento dereadFile é a função que fará o tratamento do reaultado da leitura quando o evento de finalização ocorrer.

Como já se disse na aula anterior, o uso de lógica assíncrona tem consequências dramáticas no estilo de programação! Nos programas clássicos, o programa consegue controlar todo o fluxo de execução de forma estrita. Na programação assíncrona, escreve-se código para reagir a eventos e não há possibilidade de controlar o fluxo de execução geral. Vamos ver um exemplo.

Exemplo - Servidor de ficheiros escrito em Node.js

Primeiro mostramos o código HTML do lado do browser. Vamos testar o servidor na mesma máquina do browser e por isso usamos o domínio "localhost". Escolhemos a porta 8080 por uma questão de tradição. Note que o formulário imediatamente abaixo só funcionará com o servidor estiver ativo, algo que só acontecerá durante a própria aula. Código: Agora o script do lado do servidor. O código é suficientemente autoexplicativo, mas pode ser necessário consultar a documentação de alguns objetos de biblioteca (http, url, path, fs). Para correr o script, basta dar o comando nodejs fileserver.js do lado so servidor e usar o URL http://localhost:8080/file?q=myfile.html do lado do browser.

Agora o código do servidor. Note que o servidor HTTP é criado no último bloco de código e ativado usando o método listen. Repare também que há duas funções que funcionam assincronamente: fs.exists e fs.readFile.


Toolkits e framework para a Web

No mundo da programação Web, a nomenclatura usada para descrever coleções de código relacionado e reutilizável é muito fluida, mas vamos tentar introduzir aqui alguns termos, mais ou menos consensuais quando usados em determinados contextos: De todas estas variantes, os frameworks possuem a curva de aprendizagem mais longa. O investimento de tempo tem de ser razoavelmente grande. Não admira: é preciso conhecer todas as abstrações usadas pelo criador do framework e o nosso código tem de se submeter a essas abstrações, implementando especializações delas. Contudo, depois de aprendido o framework, há vantagens no nível de produtividade e na qualidade das aplicações escritas.

Exemplo dum frameworks para a Web - Express.js

Introdução

Para dar uma ideia de como o uso dum framework pode tornar mais expedita a escrita dum site Web, vamos usar o framework Express.js (de momento, talvez o mais popular para Node.js) e este excelente tutorial desenvolvido por Krasimir Tsonev em 2013. Para consulta, está também aqui a documentação da API do Express.js.

Para começar, uma descrição rápida do site pretendido. O site deve permitir ao utilizador aceder a diversos tipos de informação, nas categorias "Blog", "Services", "Carrers", "Contacts". Deve também haver um painel de controlo protegido por password, para o administrador poder introduzir nova informação. É tudo.

Note que a forma essencial de usar diretamente o Node.js já foi apresentada atrás. No entanto, dentro dum framework o uso do Node.js é indireto: em muitas situações, trabalha-se a um nível de abstração mais elevado e parte da tarefa de programação consistem em configurar coisas, por exemplo especificando qual o código que deve correr em resposta a um pedido envolvendo um URL particular.

Instalação

Você é aconselhado a fazer uma instalação efetiva para ganhar um pouco de experiência e poder testar a aplicação.

Assumimos que estamos a trabalhar num sistema Linux com suporte para o sistema de instalação de pacotes apt, por exemplo Ubuntu ou Debian.

Passo 1 - Garantir que se tem a última versão do Node.js instalada e atualizar o gestor de pacotes npm do JavaScript.

Passo 2 - Instalar o sistema de comunicações seguras Kerberos, o sistema de base de dados MongoDB, o framework Express.js e o o sistema de testes unitários jasmine-node. Note que o MongoDB é grande, ficando a ocupar cerca de 1GB no disco.

Passo 3 - Descarregar e instalar a aplicação já escrita:

Passo 4 - Lançar a aplicação. Numa consola fazer:

Passo 5 - Para usar a aplicação de forma normal:

Para usar a aplicação em modeo de administrador: Para aceder ao painel de diagnósticos do MongoDB:

Padrão arquitectural MVC

Como é tipico de muitas aplicações Web, esta aplicação também usa o padrão arquitectural Modelo-Visualizador-Controlado (Model-View-Controller).

O padrão arquitectural MVC decompõe uma aplicação em três partes: (1) gestão dos dados, (2) lógica e (3) interface com o utilizador. Esta decomposição ajuda a tornar o programa mais compreensível e mais fácil de manter a longo prazo.

Eis alguma informação sobre os Modelos, Controladores e Visualizadores da nossa aplicação:

Geração automática

Como é habitual nestes fremeworks, o Express.js permite gerar o "esqueleto" duma aplicação, já com diversas coisas programadas e configuradas. No caso da nossa aplicação, o comando que Krasimir usou para criar o esqueleto da aplicação foi este: Depois Krasimir instalou as biblitecas de que a aplicação depende usando o comando: O conteúdo do ficheiro /package.json ficou o seguinte: Para correr a aplicação vazia, fazer: e o seguinte link - http://localhost:3000 - permite ver o que a aplicação vazia faz.

Para aprender mais sobre este exemplo, agora só mesmo estudando o tutorial, consultando ocasionalmente a documentação da API do Express.js.



#70