{"id":13033,"date":"2022-04-11T08:56:35","date_gmt":"2022-04-11T15:56:35","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=13033"},"modified":"2025-06-13T21:25:00","modified_gmt":"2025-06-14T04:25:00","slug":"build-a-python-microservice-with-couchbase-part-2","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/pt\/build-a-python-microservice-with-couchbase-part-2\/","title":{"rendered":"Crie um microsservi\u00e7o Python com o Couchbase - Parte 2"},"content":{"rendered":"<p>Em <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/build-a-python-microservice-with-couchbase-part-1\/\" target=\"_blank\" rel=\"noopener\">a primeira parte desta s\u00e9rie<\/a>Em nosso artigo sobre o Couchbase, discutimos os motivadores por tr\u00e1s da cria\u00e7\u00e3o de microsservi\u00e7os e por que o Couchbase \u00e9 o reposit\u00f3rio de dados perfeito para ser usado em uma arquitetura de microsservi\u00e7o. Com sua natureza sem estado, ele pode ser implantado em qualquer lugar e dimensionado horizontalmente conforme necess\u00e1rio. Embora seja poss\u00edvel escrever um microsservi\u00e7o em qualquer linguagem, para se adequar a um fluxo de trabalho \u00e1gil em que \u00e9 necess\u00e1rio fornecer funcionalidade rapidamente, voc\u00ea deve escolher uma linguagem conhecida pela maioria dos desenvolvedores e que permita um desenvolvimento r\u00e1pido. Como Python e JavaScript s\u00e3o duas linguagens populares, qualquer uma delas seria uma boa op\u00e7\u00e3o. Nesta s\u00e9rie de blogs, vamos nos concentrar em Python.<\/p>\n<h2>Considera\u00e7\u00f5es sobre o desempenho distribu\u00eddo<\/h2>\n<p>Os requisitos de desempenho dos aplicativos s\u00e3o importantes, mas \u00e0s vezes s\u00e3o dif\u00edceis de quantificar. Um exemplo simples \u00e9 um relat\u00f3rio que \u00e9 executado em X horas; no entanto, ele deve ser executado em Y minutos devido a requisitos comerciais. Esse exemplo \u00e9 f\u00e1cil de quantificar e fornece uma meta clara de melhoria. Quando voc\u00ea tem uma arquitetura geograficamente distribu\u00edda, se um componente puder suportar X solicita\u00e7\u00f5es por segundo, isso n\u00e3o significa nada. Considerando o n\u00famero de vari\u00e1veis em uma arquitetura geograficamente <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/distributed-applications\/\">aplicativo distribu\u00eddo<\/a>Se voc\u00ea n\u00e3o tiver uma solu\u00e7\u00e3o, precisa dar um passo atr\u00e1s e come\u00e7ar com algo que possa quantificar; por exemplo, voc\u00ea quer que um aplicativo para smartphone carregue totalmente em X segundos ou que uma p\u00e1gina da Web carregue totalmente em Y segundos. Em seguida, trabalhe de tr\u00e1s para frente para ver o que \u00e9 necess\u00e1rio para que isso aconte\u00e7a.<\/p>\n<h2>Considera\u00e7\u00f5es sobre o desempenho do microsservi\u00e7o Python<\/h2>\n<p>Ao criar um microsservi\u00e7o em Python, voc\u00ea tem algumas op\u00e7\u00f5es a considerar antes de come\u00e7ar a codificar. Voc\u00ea pode escrever todo o seu pr\u00f3prio c\u00f3digo Python para criar o servi\u00e7o ou usar uma estrutura de API Python, como Flask ou FastAPI. Em <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/build-a-python-microservice-with-couchbase-part-1\/\" target=\"_blank\" rel=\"noopener\">a primeira parte desta s\u00e9rie<\/a>Na se\u00e7\u00e3o \"C\u00f3digo completo\", forneci um exemplo da primeira op\u00e7\u00e3o. Chamarei essa op\u00e7\u00e3o de \"c\u00f3digo completo\". Nesta segunda parte da s\u00e9rie, apresentarei uma implementa\u00e7\u00e3o do servi\u00e7o simples de perfil de usu\u00e1rio usando FastAPI. Escolhi o FastAPI em vez do Flask para este blog porque a maioria o considera mais r\u00e1pido, e achei que seria divertido experiment\u00e1-lo.<\/p>\n<p>Mas, primeiro, vamos nos concentrar em nosso exemplo original de \"c\u00f3digo completo\". Usamos a fun\u00e7\u00e3o <em>Servidor HTTPS<\/em> para criar um servidor Web b\u00e1sico para responder \u00e0s nossas chamadas de API. Para nossa API, decidimos usar caminhos (em vez de par\u00e2metros ou publica\u00e7\u00e3o de um corpo JSON), pois \u00e9 r\u00e1pido e f\u00e1cil de analisar. Nossa API simples de perfil de usu\u00e1rio n\u00e3o precisa fornecer muita coisa - apenas alguns m\u00e9todos para procurar um perfil de usu\u00e1rio e obter os dados. Inclu\u00ed op\u00e7\u00f5es de pesquisa por <em>ID<\/em>, <em>Apelido<\/em> ou <em>Nome de usu\u00e1rio<\/em>. Na vida real, os requisitos variam de acordo com a forma como o aplicativo upstream \u00e9 projetado.<\/p>\n<p>O programa de c\u00f3digo completo tem duas \u00e1reas l\u00f3gicas: o c\u00f3digo que \u00e9 executado uma vez e o c\u00f3digo executado para cada solicita\u00e7\u00e3o, ou seja, a fun\u00e7\u00e3o do_GET. Por conveni\u00eancia, n\u00e3o vamos nos concentrar no c\u00f3digo de execu\u00e7\u00e3o limitada, mas na fun\u00e7\u00e3o do_GET e em suas fun\u00e7\u00f5es sat\u00e9lite. Com a fun\u00e7\u00e3o <em>Servidor HTTPS<\/em> essa fun\u00e7\u00e3o ser\u00e1 chamada com cada solicita\u00e7\u00e3o. O caminho da solicita\u00e7\u00e3o estar\u00e1 na classe e poder\u00e1 ser acessado por meio de <em>self.path<\/em> e os cabe\u00e7alhos est\u00e3o em <em>self.headers<\/em>. Se estiver apenas come\u00e7ando a usar Python, <em>aut\u00f4nomo<\/em> \u00e9 assim em Java - ele faz refer\u00eancia \u00e0 inst\u00e2ncia de chamada da classe.<\/p>\n<p>O servi\u00e7o precisar\u00e1 iterar o conte\u00fado da string de caminho para que possa fazer a pesquisa apropriada e retornar os dados. Gra\u00e7as \u00e0 beleza do design nativo do JSON do Couchbase, n\u00e3o precisamos fazer muita coisa, se \u00e9 que precisamos fazer alguma coisa, com os dados antes de envi\u00e1-los. Portanto, vamos nos concentrar em como inspecionar o caminho. O Python tem muitas op\u00e7\u00f5es integradas para processamento de strings que permitem que voc\u00ea escreva um c\u00f3digo bonito, mas n\u00e3o necessariamente o c\u00f3digo mais r\u00e1pido. Python \u00e9 uma linguagem interpretada (\u00e9 executada diretamente a partir da fonte), portanto, as declara\u00e7\u00f5es fazem diferen\u00e7a.<\/p>\n<p>Vamos dar uma olhada em duas op\u00e7\u00f5es para o processamento de strings de caminho - o <em>come\u00e7a com<\/em> e <em>dividir<\/em> m\u00e9todos.<\/p>\n<pre class=\"decode-attributes:false lang:python decode:true\">% python3 -m timeit -s 'text=\"\/api\/v1\/id\/4\"' 'text.startswith(\"\/api\/v1\/id\/\")'\r\n2000000 loops, best of 5: 111 nsec per loop\r\n\r\n% python3 -m timeit -s 'text=\"\/api\/v1\/id\/4\"' 'text.split(\"\/\")[-1]'\r\n1000000 loops, best of 5: 205 nsec per loop<\/pre>\n<p>A divis\u00e3o \u00e9 mais cara, mas teremos de faz\u00ea-la, portanto, seria melhor faz\u00ea-la apenas uma vez. Assim, podemos evitar chamar qualquer outra coisa usando o array retornado da divis\u00e3o em vez de <em>come\u00e7a com<\/em>.<\/p>\n<pre class=\"decode-attributes:false lang:python decode:true\">% python3 -m timeit -s 'True if 1 == 5 else False'\r\n50000000 loops, best of 5: 6.07 nsec per loop<\/pre>\n<p>As instru\u00e7\u00f5es condicionais s\u00e3o r\u00e1pidas, portanto, embora possa n\u00e3o parecer bonito, faremos uma \u00fanica divis\u00e3o e, em seguida, criaremos um <em>if...elif...else<\/em> para iterar pelo caminho. Escreveremos fun\u00e7\u00f5es auxiliares curtas para fazer uma consulta ou obter um valor-chave e retornar os dados JSON ao solicitante com o m\u00ednimo de processamento.<\/p>\n<p>Al\u00e9m disso, para tornar nosso microsservi\u00e7o seguro, adicionaremos um token de portador. Usar\u00edamos algo como o OAuth com tokens Bearer e JWT em um ambiente real. Para o nosso exemplo, simplificaremos muito isso e adicionaremos uma cole\u00e7\u00e3o ao nosso esquema com um token fixo. O servi\u00e7o consultar\u00e1 esse token na inicializa\u00e7\u00e3o e responder\u00e1 somente \u00e0s solicita\u00e7\u00f5es que fornecerem esse token como um token de portador. Por fim, se necess\u00e1rio, adicionaremos um caminho de verifica\u00e7\u00e3o de integridade que responde com um <em>HTTP 200<\/em> para sabermos que nosso servi\u00e7o \u00e9 saud\u00e1vel.<\/p>\n<pre class=\"decode-attributes:false lang:python decode:true\"> \u00a0\u00a0 def do_GET(self):\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 path_vector = self.path.split('\/')\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 path_vector_length = len(path_vector)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if path_vector_length == 5 and path_vector[3] == 'id':\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if not self.v1_check_auth_token(self.headers):\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 self.unauthorized()\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 request_parameter = path_vector[4]\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 records = self.v1_get_by_id('user_data', request_parameter)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 self.v1_responder(records)<\/pre>\n<h2>Cont\u00eaineres do microsservi\u00e7o Python<\/h2>\n<p>Decidi usar o Kubernetes para testar o servi\u00e7o, ent\u00e3o tive que criar cont\u00eaineres com as v\u00e1rias implementa\u00e7\u00f5es da API. H\u00e1 um cont\u00eainer Python publicado que pode ser usado como base. Alguns pr\u00e9-requisitos do sistema operacional ter\u00e3o de ser instalados antes dos pacotes Python necess\u00e1rios. O cont\u00eainer Python \u00e9 baseado no Debian, portanto os pacotes de pr\u00e9-requisitos podem ser instalados com o APT. Em seguida <em>tubula\u00e7\u00e3o<\/em> pode ser chamado para instalar os pacotes Python necess\u00e1rios. A porta do servi\u00e7o precisar\u00e1 ser exposta e, por fim, o servi\u00e7o poder\u00e1 ser executado da mesma forma que seria executado na linha de comando. Para colocar o servi\u00e7o em um cont\u00eainer, ele precisar\u00e1 de uma modifica\u00e7\u00e3o adicional para oferecer suporte a vari\u00e1veis de ambiente, pois esse \u00e9 o m\u00e9todo preferido para passar par\u00e2metros para um cont\u00eainer.<\/p>\n<p>Este \u00e9 um exemplo do Dockerfile para o servi\u00e7o de c\u00f3digo completo:<\/p>\n<pre class=\"decode-attributes:false lang:sh decode:true\">FROM python:3.9-bullseye\r\nRUN apt update\r\nRUN apt install elpa-magit -y\r\nRUN apt install git-all python3-dev python3-pip python3-setuptools cmake build-essential libssl-dev -y\r\nWORKDIR \/usr\/src\/app\r\nADD . \/usr\/src\/app\r\nRUN pip install --no-cache-dir -r requirements.txt\r\nEXPOSE 8080\r\nCMD .\/micro-svc-demo.py\r\nThe service can then be run passing the parameters through the environment:\r\ndocker run -d --name microservice \\\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 -p 8080:8080 \\\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 -e COUCHBASE_HOST=$COUCHBASE_HOST \\\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 -e COUCHBASE_USER=$COUCHBASE_USER \\\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 -e COUCHBASE_PASSWORD=$COUCHBASE_PASS \\\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 -e COUCHBASE_BUCKET=$COUCHBASE_BUCKET \\\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 testsvc<\/pre>\n<h2>FastAPI<\/h2>\n<p>H\u00e1 algum tempo, a WSGI (Web Server Gateway Interface) foi criada para estruturas da Web em Python. Ela permitiu que um desenvolvedor se concentrasse apenas na cria\u00e7\u00e3o de aplicativos da Web, em vez de todas as outras tarefas de n\u00edvel inferior necess\u00e1rias em um servidor da Web. Esse padr\u00e3o foi estendido para a ASGI (Asynchronous Server Gateway Interface), que oferece suporte \u00e0 programa\u00e7\u00e3o Python ass\u00edncrona e, portanto, \u00e9 adequada para aplicativos sem estado, como APIs REST.<\/p>\n<p><a href=\"https:\/\/www.uvicorn.org\/\" target=\"_blank\" rel=\"noopener\">Uvic\u00f3rnio<\/a> \u00e9 uma implementa\u00e7\u00e3o de servidor Web ASGI para Python, e o FastAPI se integra ao Uvicron para criar uma plataforma de desenvolvimento r\u00e1pido de API. Decidi usar isso para criar uma segunda implementa\u00e7\u00e3o de API para comparar com a vers\u00e3o completa do c\u00f3digo. Como ele oferece suporte total ao Python ass\u00edncrono, tamb\u00e9m funciona bem com o Couchbase Python SDK, que oferece suporte total \u00e0 programa\u00e7\u00e3o ass\u00edncrona.<\/p>\n<p>O uso dessa estrutura acelera o desenvolvimento porque \u00e9 necess\u00e1rio muito menos c\u00f3digo do que a vers\u00e3o de c\u00f3digo completo. Algumas fun\u00e7\u00f5es para se conectar ao Couchbase s\u00e3o necess\u00e1rias, mas, al\u00e9m disso, os m\u00e9todos de aplicativos decorados s\u00e3o usados para interagir com a inst\u00e2ncia da FastAPI chamando segmentos m\u00ednimos de c\u00f3digo para buscar e retornar dados. Assim como na vers\u00e3o de c\u00f3digo completo, o servi\u00e7o se conecta ao Couchbase uma vez e usa os m\u00e9todos de coleta resultantes para obter dados. Os <em>no evento<\/em> \u00e9 usado na inicializa\u00e7\u00e3o para se conectar ao Couchbase, recuperar o token de autentica\u00e7\u00e3o e definir todas as vari\u00e1veis necess\u00e1rias.<\/p>\n<pre class=\"decode-attributes:false lang:python decode:true\">@app.on_event(\"startup\")\r\nasync def service_init():\r\n\u00a0\u00a0\u00a0 key_id = '1'\r\n\u00a0\u00a0\u00a0 cluster[1] = await get_cluster()\r\n\u00a0\u00a0\u00a0 collections['service_auth'] = await get_collection(cluster[1], 'service_auth')\r\n\u00a0\u00a0\u00a0 doc_id = f\"service_auth:{key_id}\"\r\n\u00a0\u00a0\u00a0 result = await collections['service_auth'].lookup_in(doc_id, [SD.get('token')])\r\n\u00a0\u00a0\u00a0 auth_token[1] = result.content_as[str](0)\r\n\u00a0\u00a0\u00a0 collections['user_data'] = await get_collection(cluster[1], 'user_data')\r\n\u00a0\u00a0\u00a0 collections['user_images'] = await get_collection(cluster[1], 'user_images')<\/pre>\n<p>Depois que as a\u00e7\u00f5es de inicializa\u00e7\u00e3o s\u00e3o conclu\u00eddas, fun\u00e7\u00f5es curtas para cada caminho de solicita\u00e7\u00e3o poss\u00edvel s\u00e3o invocadas por meio de chamadas de m\u00e9todo do aplicativo. O par\u00e2metro path \u00e9 extra\u00eddo do caminho e passado para a fun\u00e7\u00e3o, juntamente com uma depend\u00eancia da fun\u00e7\u00e3o para verificar o token de autentica\u00e7\u00e3o. Com essa implementa\u00e7\u00e3o, somente vari\u00e1veis de ambiente s\u00e3o usadas para passar par\u00e2metros de conex\u00e3o.<\/p>\n<pre class=\"decode-attributes:false lang:python decode:true\">@app.get(\"\/api\/v1\/id\/{document}\", response_model=Profile)\r\nasync def get_by_id(document: str, authorized: bool = Depends(verify_token)):\r\n\u00a0\u00a0\u00a0 if authorized:\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 profile = await get_profile(collection=collections['user_data'], collection_name='user_data', document=document)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 return profile<\/pre>\n<p>O cont\u00eainer para essa implementa\u00e7\u00e3o pode usar a mesma base que a vers\u00e3o completa do c\u00f3digo e instalar as mesmas depend\u00eancias; no entanto, ele ter\u00e1 alguns requisitos adicionais de pacotes Python e o servi\u00e7o ser\u00e1 chamado por meio do Uvicorn.<\/p>\n<pre class=\"decode-attributes:false lang:python decode:true\">FROM python:3.9-bullseye\r\nRUN apt update\r\nRUN apt install elpa-magit -y\r\nRUN apt install git-all python3-dev python3-pip python3-setuptools cmake build-essential libssl-dev -y\r\nWORKDIR \/usr\/src\/app\r\nADD . \/usr\/src\/app\r\nRUN pip install --no-cache-dir -r requirements.txt\r\nEXPOSE 8080\r\nCMD uvicorn service:app --host 0.0.0.0 --port 8080<\/pre>\n<h2>Configura\u00e7\u00e3o do Node.js para testar pontos de extremidade<\/h2>\n<p>A publica\u00e7\u00e3o do blog \u00e9 sobre Python, mas seria \u00fatil ter uma compara\u00e7\u00e3o n\u00e3o-Python para a API, portanto, para isso, decidi usar o Node.js; ele \u00e9 ass\u00edncrono e funciona bem com APIs. A implementa\u00e7\u00e3o do Node.js usa o m\u00f3dulo Express para criar um servidor Web e, de forma semelhante \u00e0 FastAPI, usa o m\u00f3dulo <em>app.get<\/em> para todos os caminhos compat\u00edveis. Ele chama uma fun\u00e7\u00e3o para verificar primeiro o token de autentica\u00e7\u00e3o e, se for bem-sucedido, chama uma fun\u00e7\u00e3o para obter os dados solicitados.<\/p>\n<pre class=\"decode-attributes:false lang:python decode:true\">app.get('\/api\/v1\/nickname\/:nickname', checkToken, getRESTAPINickname);\r\napp.get('\/api\/v1\/username\/:username', checkToken, getRESTAPIUsername);\r\napp.get('\/api\/v1\/id\/:id', checkToken, getRESTAPIId);\r\napp.get('\/api\/v1\/picture\/record\/:id', checkToken, getRESTAPIPictureId);\r\napp.get('\/api\/v1\/picture\/raw\/:id', checkToken, getRESTAPIImageData);\r\napp.get('\/healthz', getHealthCheckPage);<\/pre>\n<p>H\u00e1 um m\u00f3dulo para as fun\u00e7\u00f5es do Couchbase localizado em um arquivo JavaScript, e as fun\u00e7\u00f5es para as chamadas de API compat\u00edveis tamb\u00e9m est\u00e3o em m\u00f3dulos em arquivos JavaScript separados. Como no Python, h\u00e1 um cont\u00eainer do Node que \u00e9 usado como base e o utilit\u00e1rio NPM mant\u00e9m as depend\u00eancias e inicia o servi\u00e7o.<\/p>\n<pre class=\"decode-attributes:false lang:sh decode:true\">FROM node:16.14.2\r\nWORKDIR \/app\r\nADD . \/app\r\nRUN rm -rf \/app\/node_modules\r\nRUN npm install -g npm@latest\r\nRUN npm install\r\nEXPOSE 8080\r\nCMD npm start<\/pre>\n<h2>Kubernetes para fazer o spinup do Couchbase de forma aut\u00f4noma<\/h2>\n<p>Como mencionado anteriormente, o Kubernetes foi escolhido para testar as implementa\u00e7\u00f5es de servi\u00e7o. Isso permitiu testes acelerados devido \u00e0 capacidade de implantar e dimensionar rapidamente os servi\u00e7os para diferentes cen\u00e1rios de teste. H\u00e1 duas op\u00e7\u00f5es para usar o Couchbase com o Kubernetes. O Operador Aut\u00f4nomo do Couchbase pode ser usado para implantar o Couchbase no ambiente do Kubernetes, ou o servi\u00e7o pode se conectar a um cluster externo. O servi\u00e7o foi testado com um cluster externo que foi implantado no mesmo VPC de nuvem. Todos os n\u00f3s estavam na mesma regi\u00e3o de nuvem, e os n\u00f3s do cluster do Couchbase e os n\u00f3s do Kubernetes foram implantados em zonas de disponibilidade para simular o que provavelmente seria visto em uma implanta\u00e7\u00e3o no mundo real.<\/p>\n<p><a href=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2022\/04\/image001.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-13035\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2022\/04\/image001.png\" alt=\"Using Kubernetes to test Couchbase implementations\" width=\"953\" height=\"753\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image001.png 953w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image001-300x237.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image001-768x607.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image001-20x16.png 20w\" sizes=\"auto, (max-width: 953px) 100vw, 953px\" \/><\/a><\/p>\n<p>Tr\u00eas arquivos YAML de implanta\u00e7\u00e3o foram criados para implantar as tr\u00eas implementa\u00e7\u00f5es. Cada YAML de implanta\u00e7\u00e3o cria um namespace para o servi\u00e7o. Ele usa um segredo para a senha do Couchbase. O servi\u00e7o \u00e9 implantado com 4 r\u00e9plicas inicialmente. Como \u00e9 um microsservi\u00e7o sem estado, ele pode ser ampliado e reduzido conforme necess\u00e1rio. O tr\u00e1fego \u00e9 direcionado para o servi\u00e7o com um balanceador de carga. Como o ambiente Kubernetes usado foi integrado a um provedor de nuvem, cada implanta\u00e7\u00e3o tamb\u00e9m provisionou um balanceador de carga de nuvem para o servi\u00e7o.<\/p>\n<pre class=\"decode-attributes:false lang:js decode:true\">apiVersion: v1\r\nkind: Namespace\r\nmetadata:\r\n\u00a0 name: demopy\r\n---\r\napiVersion: v1\r\nkind: Secret\r\nmetadata:\r\n\u00a0 name: demopy-secrets\r\n\u00a0 namespace: demopy\r\ntype: Opaque\r\ndata:\r\n\u00a0 adminPassword: aBcDeFgH=\r\n---\r\napiVersion: apps\/v1\r\nkind: Deployment\r\nmetadata:\r\n\u00a0 name: demopy\r\n\u00a0 namespace: demopy\r\nspec:\r\n\u00a0 replicas: 4\r\n\u00a0 selector:\r\n\u00a0\u00a0\u00a0 matchLabels:\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0app: demopy\r\n\u00a0 strategy:\r\n\u00a0\u00a0\u00a0 type: RollingUpdate\r\n\u00a0\u00a0\u00a0 rollingUpdate:\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 maxUnavailable: 25%\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 maxSurge: 1\r\n\u00a0 template:\r\n\u00a0\u00a0\u00a0 metadata:\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 labels:\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 app: demopy\r\n\u00a0\u00a0\u00a0 spec:\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 containers:\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 - name: demopy\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 image: mminichino\/demopy:1.0.5\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 imagePullPolicy: Always\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ports:\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 - name: app-port\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 containerPort: 8080\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 env:\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 - name: COUCHBASE_HOST\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 value: 1.2.3.4\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 - name: COUCHBASE_USER\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 value: Administrator\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 - name: COUCHBASE_PASSWORD\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 valueFrom:\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 secretKeyRef:\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 name: demopy-secrets\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 key: adminPassword\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 - name: COUCHBASE_BUCKET\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 value: sample_app\r\n---\r\napiVersion: v1\r\nkind: Service\r\nmetadata:\r\n\u00a0 name: demopy-service\r\n\u00a0 namespace: demopy\r\n\u00a0 labels:\r\n\u00a0\u00a0\u00a0 app: demopy\r\nspec:\r\n\u00a0 selector:\r\n\u00a0\u00a0\u00a0 app: demopy\r\n\u00a0 ports:\r\n\u00a0 - name: http\r\n\u00a0\u00a0\u00a0 port: 8080\r\n\u00a0\u00a0\u00a0 targetPort: 8080\r\n\u00a0 type: LoadBalancer<\/pre>\n<p>Usando os arquivos YAML de implanta\u00e7\u00e3o, o servi\u00e7o pode ser implantado e dimensionado conforme necess\u00e1rio com a CLI do Kubernetes. Opcionalmente, se esse fosse um ambiente de produ\u00e7\u00e3o real, ferramentas como dimensionamento autom\u00e1tico e balanceamento de carga avan\u00e7ado poderiam ser usadas para controlar e acessar a implanta\u00e7\u00e3o.<\/p>\n<pre class=\"decode-attributes:false lang:sh decode:true\">$ kubectl apply -f demopy.yaml\r\n$ kubectl scale deployment --replicas=8 demopy -n demopy<\/pre>\n<h2>Resultados de desempenho do cluster<\/h2>\n<p>Antes de testar os servi\u00e7os, o cluster do Couchbase foi testado a partir do cluster do Kubernetes para criar uma linha de base. Foi usada a carga de trabalho B do YCSB (que \u00e9 principalmente de valor-chave <em>obter<\/em> opera\u00e7\u00f5es) e produziu 156.094 opera\u00e7\u00f5es\/s. O teste de API foi feito com o Apache JMeter. A chamada de API de ID foi usada para manter a simplicidade, e o gerador de n\u00fameros aleat\u00f3rios do JMeter foi aproveitado para criar execu\u00e7\u00f5es de teste em perfis de usu\u00e1rios aleat\u00f3rios. O cen\u00e1rio de teste foi limitado por tempo, com um tempo de execu\u00e7\u00e3o de tr\u00eas minutos, em que geraria carga irrestrita contra o servi\u00e7o de balanceador de carga solicitando perfis de usu\u00e1rio aleat\u00f3rios sem aumento (a carga foi constante durante toda a dura\u00e7\u00e3o do teste).<\/p>\n<p><a href=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2022\/04\/image003.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-13037 size-large\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2022\/04\/image003-1024x646.png\" alt=\"Setting REST service thread groups with JMeter\" width=\"900\" height=\"568\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image003-1024x646.png 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image003-300x189.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image003-768x485.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image003-20x13.png 20w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image003-1320x833.png 1320w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image003.png 1431w\" sizes=\"auto, (max-width: 900px) 100vw, 900px\" \/><\/a><a href=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2022\/04\/image005.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-13038\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2022\/04\/image005-1024x607.png\" alt=\"Testing REST service endpointswith JMeter\" width=\"900\" height=\"533\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image005-1024x607.png 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image005-300x178.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image005-768x455.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image005-20x12.png 20w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image005-1320x782.png 1320w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image005.png 1431w\" sizes=\"auto, (max-width: 900px) 100vw, 900px\" \/><\/a><\/p>\n<p>Para o primeiro conjunto de testes, os par\u00e2metros de teste do JMeter permaneceram inalterados, e o que variou foi a escala das tr\u00eas implementa\u00e7\u00f5es de API. Os testes come\u00e7aram com 4 pods para cada implementa\u00e7\u00e3o e foram ampliados para 8 e, finalmente, 16 pods. Todas as implementa\u00e7\u00f5es escalonaram a taxa de transfer\u00eancia \u00e0 medida que os pods eram escalonados na implementa\u00e7\u00e3o.<\/p>\n<p><a href=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2022\/04\/image008.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-13039\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2022\/04\/image008.jpg\" alt=\"Couchbase Python performance results - requests\/sec\" width=\"469\" height=\"300\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image008.jpg 469w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image008-300x192.jpg 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image008-20x13.jpg 20w\" sizes=\"auto, (max-width: 469px) 100vw, 469px\" \/><\/a><\/p>\n<p>O Node.js foi o que se saiu melhor com essa estrat\u00e9gia de teste, pois teve a menor lat\u00eancia m\u00e9dia. Um milissegundo n\u00e3o \u00e9 muita lat\u00eancia, nem 12 milissegundos. Mas com um n\u00famero fixo de threads de gerador criando mais de 1 milh\u00e3o de solicita\u00e7\u00f5es em tr\u00eas minutos, os milissegundos t\u00eam um efeito cumulativo. No entanto, lembre-se de que este \u00e9 um teste extremo. Esses s\u00e3o apenas pontos de dados. O que foi surpreendente foi que o servi\u00e7o Python de c\u00f3digo completo acompanhou o ritmo da implementa\u00e7\u00e3o da FastAPI.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-13040 size-full\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2022\/04\/image010.jpg\" alt=\"Couchbase Python performance results - latency\" width=\"469\" height=\"310\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image010.jpg 469w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image010-300x198.jpg 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image010-20x13.jpg 20w\" sizes=\"auto, (max-width: 469px) 100vw, 469px\" \/><\/p>\n<p>Como o primeiro cen\u00e1rio de teste demonstrou que as implementa\u00e7\u00f5es de c\u00f3digo completo do Python e da FastAPI eram dimension\u00e1veis, a segunda rodada de testes dimensionou o n\u00famero de threads de solicita\u00e7\u00e3o com um n\u00famero fixo de 32 pods de servi\u00e7o. Com esse cen\u00e1rio de teste, os servi\u00e7os baseados em Python puderam ser dimensionados para quase 10.000 solicita\u00e7\u00f5es por segundo.<a href=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2022\/04\/image012.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-13041 size-full\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2022\/04\/image012.jpg\" alt=\"Couchbase Python performance results - request thread scale\" width=\"469\" height=\"334\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image012.jpg 469w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image012-300x214.jpg 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image012-20x14.jpg 20w\" sizes=\"auto, (max-width: 469px) 100vw, 469px\" \/><\/a><\/p>\n<h2>Conclus\u00f5es<\/h2>\n<p>Acho que o Python \u00e9 uma excelente op\u00e7\u00e3o para servi\u00e7os de carga moderada. Com todos os testes realizados, os n\u00f3s do cluster do Kubernetes tinham ampla CPU e mem\u00f3ria dispon\u00edveis, portanto, havia bastante espa\u00e7o para dimensionar o servi\u00e7o conforme necess\u00e1rio. Para implementa\u00e7\u00f5es que exigem escala maci\u00e7a com a menor lat\u00eancia, o Node.js pode ser uma op\u00e7\u00e3o melhor. O Couchbase oferece suporte a todas as linguagens predominantes, portanto, assim como consegui codificar facilmente tr\u00eas implementa\u00e7\u00f5es de microsservi\u00e7o, qualquer pessoa pode usar v\u00e1rias linguagens e estruturas e integrar o Couchbase com facilidade.<\/p>\n<h3>Pr\u00f3ximo<\/h3>\n<p>Na pr\u00f3xima publica\u00e7\u00e3o desta s\u00e9rie do blog, falarei sobre a gera\u00e7\u00e3o de dados de teste aleat\u00f3rios para o esquema de microsservi\u00e7o. Aqui est\u00e3o os links para os recursos mencionados nesta postagem:<\/p>\n<ul>\n<li><a href=\"https:\/\/www.couchbase.com\/blog\/pt\/build-a-python-microservice-with-couchbase-part-1\/\" target=\"_blank\" rel=\"noopener\">Crie um microsservi\u00e7o Python com o Couchbase - Parte 1<\/a><\/li>\n<li>Parte 2 - C\u00f3digo-fonte do microsservi\u00e7o para o perfil do usu\u00e1rio\n<ul>\n<li><a href=\"https:\/\/github.com\/mminichino\/user-profile-demo\">https:\/\/github.com\/mminichino\/user-profile-demo<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/mminichino\/user-profile-demo-fastapi\">https:\/\/github.com\/mminichino\/user-profile-demo-fastapi<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/mminichino\/node-user-profile-demo\">https:\/\/github.com\/mminichino\/node-user-profile-demo<\/a><\/li>\n<\/ul>\n<\/li>\n<li><a href=\"https:\/\/cloud.couchbase.com\/\">Oferta do Capella Couchbase Cloud<\/a><\/li>\n<li><a href=\"https:\/\/www.couchbase.com\/blog\/pt\/products\/cloud\/kubernetes\/\">Operador aut\u00f4nomo do Couchbase<\/a><\/li>\n<\/ul>\n<h3>Fato engra\u00e7ado aleat\u00f3rio<\/h3>\n<p>Os c\u00f3digos de resposta HTTP s\u00e3o definidos de acordo com a especifica\u00e7\u00e3o do protocolo. O intervalo 400 \u00e9 reservado para situa\u00e7\u00f5es em que o erro parece ter sido causado pelo cliente. O HTTP 418 \u00e9 o erro \"I'm a teapot\" (Sou um bule de ch\u00e1) e a especifica\u00e7\u00e3o afirma que o c\u00f3digo de resposta de erro do cliente \"I'm a teapot\" (Sou um bule de ch\u00e1) indica que o servidor se recusa a preparar caf\u00e9 porque \u00e9, permanentemente, um bule de ch\u00e1. Uma combina\u00e7\u00e3o de caf\u00e9 e bule que esteja temporariamente sem caf\u00e9 deve retornar 503.\"<\/p>","protected":false},"excerpt":{"rendered":"<p>In the first installment of this series, we discussed the drivers behind creating microservices, and why Couchbase is the perfect datastore to use with a microservice architecture. With their stateless nature, they can be deployed anywhere and horizontally scaled as [&hellip;]<\/p>","protected":false},"author":81015,"featured_media":13042,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1816,9139,2201],"tags":[2103,9548],"ppma_author":[9550],"class_list":["post-13033","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-couchbase-server","category-python","category-tools-sdks","tag-microservices","tag-service-oriented-architecture"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.8 (Yoast SEO v25.8) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Build A Python Microservice With Couchbase \u2013 Part 2<\/title>\n<meta name=\"description\" content=\"Learn to build fully-scalable microservices using Python and Couchbase Autonomous Operator? Test the API with JMeter and Node.js.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.couchbase.com\/blog\/pt\/build-a-python-microservice-with-couchbase-part-2\/\" \/>\n<meta property=\"og:locale\" content=\"pt_BR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Build A Python Microservice With Couchbase \u2013 Part 2\" \/>\n<meta property=\"og:description\" content=\"Learn to build fully-scalable microservices using Python and Couchbase Autonomous Operator? Test the API with JMeter and Node.js.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/pt\/build-a-python-microservice-with-couchbase-part-2\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2022-04-11T15:56:35+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-06-14T04:25:00+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/build-a-microservice-api-with-python-and-couchbase-scaled.jpeg\" \/>\n\t<meta property=\"og:image:width\" content=\"2560\" \/>\n\t<meta property=\"og:image:height\" content=\"1709\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Michael Minichino\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Michael Minichino\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"11 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/build-a-python-microservice-with-couchbase-part-2\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/build-a-python-microservice-with-couchbase-part-2\/\"},\"author\":{\"name\":\"Michael Minichino\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/15ea6a51d53d4739913c98d25a8d7e77\"},\"headline\":\"Build A Python Microservice With Couchbase \u2013 Part 2\",\"datePublished\":\"2022-04-11T15:56:35+00:00\",\"dateModified\":\"2025-06-14T04:25:00+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/build-a-python-microservice-with-couchbase-part-2\/\"},\"wordCount\":2218,\"commentCount\":1,\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/build-a-python-microservice-with-couchbase-part-2\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/build-a-microservice-api-with-python-and-couchbase-scaled.jpeg\",\"keywords\":[\"microservices\",\"service-oriented architecture\"],\"articleSection\":[\"Couchbase Server\",\"Python\",\"Tools &amp; SDKs\"],\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/build-a-python-microservice-with-couchbase-part-2\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/build-a-python-microservice-with-couchbase-part-2\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/build-a-python-microservice-with-couchbase-part-2\/\",\"name\":\"Build A Python Microservice With Couchbase \u2013 Part 2\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/build-a-python-microservice-with-couchbase-part-2\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/build-a-python-microservice-with-couchbase-part-2\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/build-a-microservice-api-with-python-and-couchbase-scaled.jpeg\",\"datePublished\":\"2022-04-11T15:56:35+00:00\",\"dateModified\":\"2025-06-14T04:25:00+00:00\",\"description\":\"Learn to build fully-scalable microservices using Python and Couchbase Autonomous Operator? Test the API with JMeter and Node.js.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/build-a-python-microservice-with-couchbase-part-2\/#breadcrumb\"},\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/build-a-python-microservice-with-couchbase-part-2\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/build-a-python-microservice-with-couchbase-part-2\/#primaryimage\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/build-a-microservice-api-with-python-and-couchbase-scaled.jpeg\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/build-a-microservice-api-with-python-and-couchbase-scaled.jpeg\",\"width\":2560,\"height\":1709,\"caption\":\"Building a microservice API with Couchbase and Python\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/build-a-python-microservice-with-couchbase-part-2\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.couchbase.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Build A Python Microservice With Couchbase \u2013 Part 2\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"name\":\"The Couchbase Blog\",\"description\":\"Couchbase, the NoSQL Database\",\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"pt-BR\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"width\":218,\"height\":34,\"caption\":\"The Couchbase Blog\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/15ea6a51d53d4739913c98d25a8d7e77\",\"name\":\"Michael Minichino\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/ed87fc8ff8aedc56f9872fbd77382f29\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/03\/Screen-Shot-2022-03-28-at-12.40.06-PM.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/03\/Screen-Shot-2022-03-28-at-12.40.06-PM.png\",\"caption\":\"Michael Minichino\"},\"url\":\"https:\/\/www.couchbase.com\/blog\/pt\/author\/michael-minichino\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Crie um microsservi\u00e7o Python com o Couchbase - Parte 2","description":"Learn to build fully-scalable microservices using Python and Couchbase Autonomous Operator? Test the API with JMeter and Node.js.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.couchbase.com\/blog\/pt\/build-a-python-microservice-with-couchbase-part-2\/","og_locale":"pt_BR","og_type":"article","og_title":"Build A Python Microservice With Couchbase \u2013 Part 2","og_description":"Learn to build fully-scalable microservices using Python and Couchbase Autonomous Operator? Test the API with JMeter and Node.js.","og_url":"https:\/\/www.couchbase.com\/blog\/pt\/build-a-python-microservice-with-couchbase-part-2\/","og_site_name":"The Couchbase Blog","article_published_time":"2022-04-11T15:56:35+00:00","article_modified_time":"2025-06-14T04:25:00+00:00","og_image":[{"width":2560,"height":1709,"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/build-a-microservice-api-with-python-and-couchbase-scaled.jpeg","type":"image\/jpeg"}],"author":"Michael Minichino","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Michael Minichino","Est. reading time":"11 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/build-a-python-microservice-with-couchbase-part-2\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/build-a-python-microservice-with-couchbase-part-2\/"},"author":{"name":"Michael Minichino","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/15ea6a51d53d4739913c98d25a8d7e77"},"headline":"Build A Python Microservice With Couchbase \u2013 Part 2","datePublished":"2022-04-11T15:56:35+00:00","dateModified":"2025-06-14T04:25:00+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/build-a-python-microservice-with-couchbase-part-2\/"},"wordCount":2218,"commentCount":1,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/build-a-python-microservice-with-couchbase-part-2\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/build-a-microservice-api-with-python-and-couchbase-scaled.jpeg","keywords":["microservices","service-oriented architecture"],"articleSection":["Couchbase Server","Python","Tools &amp; SDKs"],"inLanguage":"pt-BR","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/build-a-python-microservice-with-couchbase-part-2\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/build-a-python-microservice-with-couchbase-part-2\/","url":"https:\/\/www.couchbase.com\/blog\/build-a-python-microservice-with-couchbase-part-2\/","name":"Crie um microsservi\u00e7o Python com o Couchbase - Parte 2","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/build-a-python-microservice-with-couchbase-part-2\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/build-a-python-microservice-with-couchbase-part-2\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/build-a-microservice-api-with-python-and-couchbase-scaled.jpeg","datePublished":"2022-04-11T15:56:35+00:00","dateModified":"2025-06-14T04:25:00+00:00","description":"Learn to build fully-scalable microservices using Python and Couchbase Autonomous Operator? Test the API with JMeter and Node.js.","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/build-a-python-microservice-with-couchbase-part-2\/#breadcrumb"},"inLanguage":"pt-BR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/build-a-python-microservice-with-couchbase-part-2\/"]}]},{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.couchbase.com\/blog\/build-a-python-microservice-with-couchbase-part-2\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/build-a-microservice-api-with-python-and-couchbase-scaled.jpeg","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/build-a-microservice-api-with-python-and-couchbase-scaled.jpeg","width":2560,"height":1709,"caption":"Building a microservice API with Couchbase and Python"},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/build-a-python-microservice-with-couchbase-part-2\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Build A Python Microservice With Couchbase \u2013 Part 2"}]},{"@type":"WebSite","@id":"https:\/\/www.couchbase.com\/blog\/#website","url":"https:\/\/www.couchbase.com\/blog\/","name":"Blog do Couchbase","description":"Couchbase, o banco de dados NoSQL","publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"pt-BR"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"Blog do Couchbase","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","width":218,"height":34,"caption":"The Couchbase Blog"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/15ea6a51d53d4739913c98d25a8d7e77","name":"Michael Minichino","image":{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/ed87fc8ff8aedc56f9872fbd77382f29","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/03\/Screen-Shot-2022-03-28-at-12.40.06-PM.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/03\/Screen-Shot-2022-03-28-at-12.40.06-PM.png","caption":"Michael Minichino"},"url":"https:\/\/www.couchbase.com\/blog\/pt\/author\/michael-minichino\/"}]}},"authors":[{"term_id":9550,"user_id":81015,"is_guest":0,"slug":"michael-minichino","display_name":"Michael Minichino","avatar_url":{"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/03\/Screen-Shot-2022-03-28-at-12.40.06-PM.png","url2x":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/03\/Screen-Shot-2022-03-28-at-12.40.06-PM.png"},"author_category":"","last_name":"Minichino","first_name":"Michael","job_title":"","user_url":"","description":"Michael Minichino is a Principal Solutions Engineer at Couchbase"}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/13033","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/users\/81015"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/comments?post=13033"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/13033\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/media\/13042"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/media?parent=13033"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/categories?post=13033"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/tags?post=13033"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/ppma_author?post=13033"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}