Aaron Benton é um arquiteto experiente, especializado em soluções criativas para desenvolver aplicativos móveis inovadores. Ele tem mais de 10 anos de experiência em desenvolvimento de pilha completa, incluindo ColdFusion, SQL, NoSQL, JavaScript, HTML e CSS. Atualmente, Aaron é Arquiteto de Aplicativos da Shop.com em Greensboro, Carolina do Norte, e é um Campeão da comunidade do Couchbase.
Para nossa última postagem na seção Falsa vamos explorar como podemos aproveitar Falsa + Servidor Couchbase + Gateway de sincronização para colocar nosso ambiente local em funcionamento para o desenvolvimento móvel. Faremos isso usando Docker e docker-compose. Isenção de responsabilidade: não sou de forma alguma um especialista em Docker, este é apenas um exemplo do que fiz para configurar rapidamente um ambiente de desenvolvimento e um conjunto de dados.
Docker
Usaremos dois contêineres do Docker, um para Servidor Couchbase e um para Gateway de sincronização. Poderíamos definir um arquivo docker-compose.yaml que simplesmente extraísse do couchbase:latest e do couchbase/sync-gateway:latest, mas ainda haveria a necessidade de configuração manual e queremos poder automatizar o máximo possível para o nosso aplicativo. Para fazer isso, precisaremos criar nossos próprios contêineres a partir de ambos, adicionando nossos próprios scripts e configurações.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
./doca-compor.yaml versão: '2' serviços: falso-couchbase: construir: contexto: ./.doca/couchbase/ nome_do_contêiner: falso-couchbase portos: - "8091-8094:8091-8094" - "11210:11210" volumes: - ./:/aplicativo falso-sincronização: construir: contexto: ./.doca/sincronização-portal/ nome_do_contêiner: falso-porta de sincronização depende_de: - falso-couchbase portos: - "4984-4985:4984-4985" volumes: - ./:/aplicativo |
Nosso arquivo docker-compose.yaml está primeiro criando um contêiner no Dockerfile a partir de ./.docker/couchbase/Dockerfile, que tem a seguinte aparência.
1 2 3 4 5 6 7 8 9 10 |
./.doca/couchbase/Dockerfile # comece com o couchbase DE couchbase:mais recente # copie o script de configuração CÓPIA roteiros/configurar-nó.sh /optar/couchbase # execute o script configure-node.sh CMD ["/opt/couchbase/configure-node.sh"] |
Esse Dockerfile está realmente fazendo apenas duas coisas: copiando um script de configuração e executando esse script. O script configure-node.sh tem a seguinte aparência.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
./.doca/couchbase/roteiros/configurar-nó.sh definir -m /ponto de entrada.sh couchbase-servidor & eco 'Waiting 20 seconds for Couchbase service to start' (Aguardando 20 segundos para o serviço Couchbase iniciar) dormir 20 # configurar o cluster eco "Configurando o cluster /optar/couchbase/caixa/couchbase-cli agrupamento-inicial -c localhost:8091 --agrupamento-nome de usuário=Administrador --agrupamento-senha=senha --agrupamento-porto=8091 --agrupamento-tamanho de rams=500 --serviço=dados # criar o balde de comércio eletrônico eco 'Criando um balde de comércio eletrônico' /optar/couchbase/caixa/couchbase-cli balde-criar -c localhost:8091 -u Administrador -p senha --balde=comércio eletrônico --balde-despejo-política=fullEviction --balde-tipo=base de membrana --balde-prioridade=alta --ativar-índice-réplica=0 --balde-porto=11211 --ativar-descarga=1 --balde-réplica=1 --balde-tamanho de rams=200 eco 'O servidor Couchbase está pronto' fg 1 |
O script configure-node.sh está fazendo algumas coisas:
- Aguardando o início do serviço Couchbase para que ele possa ser configurado
- Inicialização da configuração do cluster
- Criação do nosso balde de comércio eletrônico
O contêiner do Couchbase já foi criado; o próximo contêiner que precisa ser criado é o contêiner do Sync Gateway. Por padrão, o contêiner do Sync Gateway usa o bucket do gateway de sincronização somente de memória da morsa. Precisaremos atualizar essa configuração fornecendo nosso próprio arquivo sync-gateway.json para que possamos atualizar as configurações de armazenamento e acesso. Por fim, o contêiner do Sync Gateway expõe apenas a porta 4984, que é a porta pública. Como isso é para fins de desenvolvimento, vamos expor a porta 4985, que é a porta do administrador.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
./.doca/sincronização-portal/Dockerfile # Comece com o gateway de sincronização básico DE couchbase/sincronização-portal:mais recente # Copie o sync-gateway.json para o contêiner CÓPIA sincronização-portal.json /optar/portais de sincronização/sincronização-portal.json # Criar volume para que os dados sejam mantidos CORRER mkdir -p /optar/portais de sincronização/dados # Ponto de entrada de cópia CÓPIA roteiros/ponto de entrada.sh / PONTO DE ENTRADA ["/entrypoint.sh"] # Copie o script de configuração CÓPIA roteiros/configurar-nó.sh /optar/sincronização_portal # Configure o Sync Gateway e inicie-o CMD ["/opt/sync_gateway/configure-node.sh"] # porta 4984: porta pública # porta 4985: porta de administração EXPOSIÇÃO 4984 4985 ./.doca/sincronização-portal/sincronização-portal.json { "interface": "0.0.0.0:4984", "adminInterface": "0.0.0.0:4985", "log": ["CRUD+", "REST+", "Mudanças+", "Anexar+"], "CORS": { "Origem":[ "http://localhost:8000", "*" ], "LoginOrigin":[ "http://localhost:8000", "*" ], "Headers" (Cabeçalhos):["Content-Type"], "MaxAge": 1728000 }, "bancos de dados": { "Comércio eletrônico": { "servidor": "http://fakeit-couchbase:8091", "bucket" (balde): "Comércio eletrônico", "usuários": { "CONVIDADO": { "desativado": falso } }, "sync": "function(doc, oldDoc) { channel(doc.channels); }" } } } ./.doca/sincronização-portal/roteiros/configurar-nó.sh #!/bin/bash definir -m eco 'Waiting 20 seconds for Couchbase service to start and warm up' (Aguardando 20 segundos para o serviço Couchbase iniciar e aquecer) dormir 20 eco "Iniciando o serviço Sync Gateway /ponto de entrada.sh portais de sincronização /optar/portais de sincronização/sincronização-portal.json eco 'O Couchbase Sync Gateway está pronto' |
Novamente, isso é apenas para fins de desenvolvimento. Você nunca deve permitir o acesso de qualquer lugar à sua adminInterface ou habilitar CONVIDADO acesso ao seu gateway de sincronização, a menos que haja um bom motivo para isso.
A estrutura do nosso aplicativo agora é a seguinte:
Agora que configuramos nossos contêineres do Docker e definimos nosso arquivo docker-compose.yaml, precisamos criar e iniciar os contêineres. Para isso, executamos o seguinte comando no diretório de aplicativos:
1 |
doca-compor para cima -d |
Observação: Para fins do screencast, o parâmetro -d para executar os contêineres no modo desanexado é omitido.
Modelos
Nossos contêineres já foram iniciados; a próxima coisa que precisamos fazer antes de gerar nosso conjunto de dados é atualizar os modelos para dar suporte ao atributo channels.
1 |
usuários.yaml |
Esse modelo só será sincronizado com canais específicos do usuário.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
nome: Usuários tipo: objeto chave: _id dados: min: 1000 máximo: 2000 insumos: ./países.json propriedades: _id: tipo: string descrição: O documento id construído por o prefixo "user_" e o usuários id dados: post_build: `usuário_${este.user_id}` canais: tipo: matriz dados: post_build: | retorno [ `canal-usuário-${este.user_id}` ]; tipo de documento: tipo: string descrição: O documento tipo dados: valor: "usuário" ... produtos.yaml |
Apenas por diversão, publicaremos esse modelo em um canal global no qual todos os nossos usuários estarão inscritos.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
nome: Produtos tipo: objeto chave: _id dados: min: 500 máximo: 1000 insumos: - ./categorias.csv pre_build: globais.current_category = falsificador.aleatório.arrayElement(insumos.categorias); propriedades: _id: tipo: string descrição: O documento id dados: post_build: `produto_${este.product_id}` canais: tipo: matriz dados: construir: | retorno [ `canal-produtos` ]; tipo de documento: tipo: string descrição: O documento tipo dados: valor: produto ... pedidos.yaml |
Esse modelo só será sincronizado com canais específicos do usuário.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
nome: Pedidos tipo: objeto chave: _id dados: dependências: - produtos.yaml - usuários.yaml min: 5000 máximo: 6000 propriedades: _id: tipo: string descrição: O documento id dados: post_build: `ordem_${este.order_id}` canais: tipo: matriz dados: construir: | retorno [ `canal-usuário-${este.user_id}` ]; tipo de documento: tipo: string descrição: O documento tipo dados: valor: "ordem" ... |
Agora que nossos modelos foram atualizados para oferecer suporte a canais, podemos gerar nosso conjunto de dados aleatórios e enviá-lo para Servidor Couchbase através do Gateway de sincronização API REST. Nós informamos Falsa para fazer isso usando o seguinte comando:
1 |
falso sincronização-portal --servidor http://localhost:4984 --bucket ecommerce --verbose models/* |
Para fins de desenvolvimento, permitimos o acesso de convidados ao nosso Gateway de sincronização. No entanto, se o acesso de convidados estiver desativado, você ainda poderá usar Falsa especificando um nome de usuário e uma senha para um usuário existente usando o seguinte comando:
1 |
falso sincronização-portal --servidor http://localhost:4984 --bucket ecommerce --username YOURUSERNAME --password YOURPASSWORD --verbose models/* |
Antes da saída do conjunto de dados gerado, Falsa será autenticado no Gateway de sincronização para recuperar as informações necessárias da sessão.
Testes
A próxima coisa que precisamos fazer é criar um usuário de gateway de sincronização para que possamos sincronizar seus documentos localmente. Para esse teste, vamos pegar um documento de usuário aleatório do nosso modelo Users e criar um usuário a partir desse documento. Neste exemplo, será user_1001, e criaremos o usuário usando o comando curl:
1 2 3 4 5 6 |
enrolar --silencioso --show-erro \ -H "Content-Type: application/json; charset=UTF-8" \ -H "Content-type: application/json" \ -X PUT \ -d '{"name": "Domenic81", "password": "pgid_Tubn0qoEtZ", "admin_channels":["channel-user-1001", "channel-products"]}' \ 'http://localhost:4985/ecommerce/_user/Domenic81' |
Aplicativo
Criamos um pequeno VueJS projeto que utiliza PouchDB para se conectar ao Sync Gateway e extrair os documentos de um usuário autenticado. Nosso aplicativo mostrará apenas os diferentes tipos de documentos disponíveis, seus IDs e conteúdo.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
// registrar o componente vue highlight.js Vue.uso(VueHighlightJS) // criar banco de dados local de comércio eletrônico var db = novo PouchDB('local_ecommerce', { auto_compactação: verdadeiro, revs_limit: 3 }); // criar banco de dados de comércio eletrônico remoto var banco de dados remoto = novo PouchDB('http://localhost:4984/ecommerce/', { autenticação: { nome de usuário: 'Domenic81', senha: 'pgid_Tubn0qoEtZ' }, pular_configuração: verdadeiro }); // mesclar o banco de dados remoto com o banco de dados local PouchDB.sincronização(db, banco de dados remoto, { ao vivo: verdadeiro, tentar novamente: verdadeiro }) var aplicativo = novo Vue({ el: '#app', dados: { tipo_atual: '', itens: [], id: '', atual: JSON.stringify({}), tipos: [], }, assistir: { id(id) { se (id) { db.obter(id).então((atual) => este.atual = JSON.stringify(atual, nulo, 2)) } }, tipo_atual(tipo) { este.id = '' // atualizar o item atual para que fique em branco este.atual = JSON.stringify({}) // quando `current_type` for alterado, atualize a lista de itens com a lista de tipos atuais este.updateItems(tipo) .então(() => { se (!este.id) { este.id = este.itens[0] } }) } }, métodos: { updateItems(tipo) { retorno db.consulta('ecommerce/by_doc_type', { chave: tipo, reduzir: falso }) .então((resultado) => { este.itens = resultado.linhas.mapa((item) => item.id) }) }, removeStyle(el) { setTimeout(() => { el.estilo = '' }, 1000) } }, criado() { // criar a visualização a ser consultada var ddoc = { _id: '_design/ecommerce', visualizações: { por_tipo_doc: { mapa: função(doc) { se (doc.tipo de documento) { emitir(doc.tipo de documento); } }.toString(), reduzir: '_count' } } } db.colocar(ddoc) // documento de design criado // chamar o índice da visualização do documento de design imediatamente para acionar uma construção .então(() => db.consulta('ecommerce/by_doc_type', { limite: 0 })) .captura((erro) => { // não há problema se isso falhar e retornar um conflito de documentos, isso significa apenas que ele não precisa ser criado se (erro.status !== 409) { lançar erro; } }) // obter todos os tipos de documentos disponíveis .então(() => db.consulta('ecommerce/by_doc_type', { reduzir: verdadeiro, grupo: verdadeiro })) .então((tipos) => { este.tipos = tipos.linhas.mapa((tipo) => tipo.chave) este.tipo_atual = este.tipos[0] }) } }) |
O aplicativo de amostra completo pode ser visualizado em https://github.com/bentonam/fakeit-couchbase-mobile-example
Conclusão
Ao longo desta série, você viu como Falsa pode usar modelos YAML simples, gerar grandes quantidades de dados falsos e enviar esses dados para vários destinos diferentes. Confira o repositório, solicitações pull são bem-vindas, pois estamos sempre buscando melhorias e aprimoramentos para tornar a ferramenta mais útil para a comunidade. Também gostaria de aproveitar este momento para agradecer àqueles que fizeram contribuições para o projeto. A versão 1.0 não teria sido lançada sem a ajuda de Tyler Benton (@tjbenton21), também Trevor Brindle (@VinceKerrazzi), Jessica Kennedy (@mistersender), Adam Burdette (@RavenStorms619) e Brant Burnett (@btburnett3)
Anterior
- FakeIt Série 1 de 5: Geração de dados falsos
- FakeIt Série 2 de 5: Dados compartilhados e dependências
- Série FakeIt 3 de 5: Modelos Lean por meio de definições
- FakeIt Série 4 de 5: Trabalhando com dados existentes