O Couchbase Mobile pode torná-lo 100 vezes mais produtivo. Da mesma forma que o O Ruby on Rails revolucionou a maneira como pensamos sobre serviços da Web Ao oferecer uma maneira concisa de modelar aplicativos Web baseados em REST e servidores de APIs, a função de sincronização no coração do Couchbase Sync Gateway pode revolucionar a maneira como você gerencia os dados de aplicativos móveis.
Já se foi o tempo em que se escrevia à mão em servidores de API e código de cliente REST móvel. Você nunca terá de volta aquelas horas dedicadas ao tratamento de erros de operação de rede, mas pelo menos isso não precisa acontecer novamente.
Com um banco de dados local no telefone (algo baseado em JSON pode ser preferível ao Core Data ou SQLite, já que estamos em 2014), pode ser tão simples quanto pedir a um objeto de modelo para salvar a si mesmo. Independentemente de o telefone estar no modo avião, em uma conexão 3G com excesso de assinaturas ou conectado a uma rede Wi-Fi de alto desempenho, o usuário nunca verá uma diferença na capacidade de resposta.
Agora, se ao menos houvesse uma maneira de obter o desempenho e a confiabilidade dos primeiros dados locais, sem abrir mão das partes boas da nuvem. Com um banco de dados local com capacidade de sincronização, as alterações podem ser sincronizadas automaticamente com a nuvem, sem que você precise escrever uma tonelada de código de rede. Isso pode simplificar radicalmente os aplicativos de clientes móveis, mas a borda é apenas a metade da história. Quando os dados chegam à nuvem, algo precisa decidir se as alterações são válidas ou se devem ser rejeitadas. A nuvem também é responsável por decidir quem pode ver o quê.
Em uma arquitetura de dados remota tradicional (do tipo que confunde seu aplicativo móvel com chamadas de rede), a validação de atualização e o controle de acesso de leitura são aplicados pelo servidor de aplicativos da Web, que normalmente é um código personalizado com um relacionamento ad-hoc com vários serviços e bancos de dados de back-end. Estamos acostumados a escrever servidores de API dessa forma, mas isso não significa que temos que gostar disso.
Em vez de uma abordagem cara em que cada ponto de extremidade REST requer código personalizado, o Sync Gateway fala o protocolo de sincronização do Couchbase Mobile e fornece sua própria abstração concisa para validação, controle de acesso e roteamento de dados. Isso significa que, em vez de escrever um servidor que gasta a maior parte de sua lógica na tradução entre a entrada do usuário e as operações e consultas do banco de dados, você pode simplesmente especificar o comportamento desejado e deixar que o Sync Gateway cuide dos detalhes.
No Sync Gateway, o comportamento personalizado do aplicativo é expresso em uma função JavaScript que oferece controle simples, mas refinado, sobre os dados. Para obter detalhes consulte a documentação da função de sincronizaçãoPor enquanto, mostrarei apenas um e depois descreverei como ele funciona.
Aqui está a função de sincronização do nosso aplicativo de exemplo, o ToDo Lite. Você pode Saiba mais sobre o código móvel do ToDo Lite em nosso portal do desenvolvedor. O mesmo backend suporta o iOS, Androide PhoneGap versões.
Se (doc.type == "task") {
Se (!doc.list_id) {
throw({forbidden : "Os itens devem ter um list_id"})
}
requireAccess("list-"+doc.list_id);
channel("list-"+doc.list_id);
} else if (doc.type == "list") {
channel("list-"+doc._id);
Se (!doc.owner) {
throw({forbidden : "A lista deve ter um proprietário"})
}
se (oldDoc) {
requireUser(oldDoc.owner)
}
access(doc.owner, "list-"+doc._id);
Se (Array.isArray(doc.members)) {
access(doc.members, "list-"+doc._id);
}
} else if (doc.type == "profile") {
channel("profiles");
var user = doc._id.substring(doc._id.indexOf(":")+1);
Se (user !== doc.user_id) {
throw({forbidden : "Profile user_id must match docid : " + user + " : " + doc.user_id})
}
requireUser(user);
access(user, "profiles");
}
}
Vamos analisar um pouco de cada vez e ver como podemos encaixar a maior parte do que o servidor de aplicativos Web REST faz em uma página de código.
A função de sincronização é executada em cada mutação de forma independente e recebe dois argumentos: a versão proposta do documento e a versão anterior do documento, se houver. A versão anterior é útil para validar coisas como, por exemplo, se a pessoa que está fazendo a alteração é a proprietária do documento ou se o seu aplicativo exige que determinados campos do documento sejam imutáveis.
Se (!doc.list_id) {
throw({forbidden : "Os itens devem ter um list_id"})
}
requireAccess("list-"+doc.list_id);
channel("list-"+doc.list_id);
Esse bloco é executado se o documento representar uma tarefa individual no ToDo Lite. Ele exige que o documento tenha um campo list_id e que o usuário que está atualizando ou criando a tarefa tenha acesso a essa lista. Se a validação for aprovada, o documento será encaminhado a um canal para essa lista. Na próxima vez que alguém que tenha acesso à lista se conectar, ele sincronizará a tarefa atualizada.
channel("list-"+doc._id);
Esta seção trata dos metadados associados a uma lista. A chamada para "channel" encaminhará os metadados da lista para o canal associado à lista (supondo que as validações deste documento sejam aprovadas).
throw({forbidden : "A lista deve ter um proprietário"})
}
se (oldDoc) {
requireUser(oldDoc.owner)
}
As validações para documentos de lista são simples: todas as listas devem ter um proprietário, e as listas só podem ser atualizadas por seu proprietário. (Observe que podemos expressar as validações e o roteamento em qualquer ordem - se a validação falhar, qualquer outra chamada dessa invocação da função de sincronização não terá efeito).
Se (Array.isArray(doc.members)) {
access(doc.members, "list-"+doc._id);
}
A última coisa que queremos fazer com o documento de metadados da lista é usá-lo para conceder acesso para que as pessoas certas possam ler no canal da lista. A primeira chamada para "access" garante que o proprietário da lista possa sincronizar itens dessa lista de tarefas. Na segunda chamada, é passada uma matriz de membros, concedendo a cada um deles acesso à lista. Essas concessões de acesso também afetarão quem pode escrever tarefas na lista, devido à chamada para "requireAccess" que fizemos no primeiro bloco dessa função.
channel("profiles");
O bloco final da função de sincronização do ToDo Lite é responsável por garantir que a lista de usuários do aplicativo esteja disponível para cada usuário, de modo que os usuários possam selecionar uns aos outros como membros de listas. A primeira linha de código nesse bloco encaminha os documentos de perfil do usuário para o canal "profiles".
Se (user !== doc.user_id) {
throw({forbidden : "Profile user_id must match docid : " + user + " : " + doc.user_id})
}
requireUser(user);
A validação de perfis garante que o documento atenda a um requisito de esquema (o ID do documento deve corresponder ao nome de usuário de seu criador). Ela também impede que qualquer pessoa edite o perfil de outra pessoa.
A última linha de código pode ser enganosamente simples. Ela concede ao usuário acesso ao canal "profiles". Isso significa que, quando um novo usuário cria seu próprio perfil, o sistema reage dando a ele acesso de leitura ao perfil de todos os outros usuários por meio do canal "profiles".
}
}
Este tour de uma função de sincronização de exemplo mostra a maioria (mas não todas) das ferramentas que ela oferece. Você pode imaginar quanto código seria necessário para escrever um servidor de API REST que aplicasse regras semelhantes. Muito mais. E resolver o problema da sincronização off-line ainda estaria em sua lista de tarefas.
Então, você será 100 vezes mais produtivo com o Couchbase Mobile?
Além disso, toda a pilha é de código aberto e está disponível sob a licença Apache 2!
\"100x menos código!\" não faz sentido: http://timesless.com/
Em minha postagem no G+ com link para cá (https://plus.google.com/+Aliak... ) Recebi os seguintes comentários:
* É importante destacar a diferença com outras opções possíveis (parse.com foi mencionado)
* e que a formatação do blog poderia ser melhorada, especialmente em celulares
Alguns dos comentários no Reddit foram de que esse artigo não descrevia suficientemente o problema que estava sendo resolvido. Escrevi um artigo para tentar resolver esse ponto: http://tleyden.github.io/blog/…