<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Natalia Venditto</title>
    <description>The latest articles on DEV Community by Natalia Venditto (@anfibiacreativa).</description>
    <link>https://dev.to/anfibiacreativa</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F150849%2F94915d8e-c192-49b4-b7c0-d200392636be.jpg</url>
      <title>DEV Community: Natalia Venditto</title>
      <link>https://dev.to/anfibiacreativa</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/anfibiacreativa"/>
    <language>en</language>
    <item>
      <title>Lightweight, portable and secure Wasm runtimes and their use cases.</title>
      <dc:creator>Natalia Venditto</dc:creator>
      <pubDate>Fri, 15 Dec 2023 14:11:04 +0000</pubDate>
      <link>https://dev.to/anfibiacreativa/lightweight-portable-and-secure-wasm-runtimes-and-their-use-cases-ama</link>
      <guid>https://dev.to/anfibiacreativa/lightweight-portable-and-secure-wasm-runtimes-and-their-use-cases-ama</guid>
      <description>&lt;h2&gt;
  
  
  Why is JavaScript so popular?
&lt;/h2&gt;

&lt;p&gt;With 16 million developers estimated, JavaScript is a pretty popular language. We sometimes attribute that to its high-level nature, and the fact that you just need a browser and a text editor, and you can write a small program or a lengthy app, and see the result right away. &lt;/p&gt;

&lt;p&gt;The so-called feedback loop is immediate; we can see the results of code execution right away. &lt;/p&gt;

&lt;p&gt;There is no need to compile it -or at least you don't need to intervene in the compilation as a developer-. Of course, modern frontend setups and build tools come equipped with transpilation systems, bundling and packaging, and a lot of ahead of time processes like static analysis, but in essence, you can run JavaScript from a text file with a browser only.&lt;/p&gt;

&lt;h2&gt;
  
  
  JavaScript needs no compilation...but, does it?
&lt;/h2&gt;

&lt;p&gt;For a program written in JavaScript to run, each instruction goes through the following JIT (just in time) flow. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;the parser or JS engine generates an Abstract Syntax Tree (AST), which is a hyerarchy of nodes,&lt;/li&gt;
&lt;li&gt;which the interpreter reads and &lt;/li&gt;
&lt;li&gt;generates high-level binary code or byte code from, for&lt;/li&gt;
&lt;li&gt;the compiler to finally generate the machine code -or low level binary- that may be optimised as instructions for a specific CPU architecture.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ecf0wnPs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/coqkylmyn4alhop7ba40.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ecf0wnPs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/coqkylmyn4alhop7ba40.png" alt="JavaScript execution" width="800" height="438"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This cycle of execution, uses the client's (be it desktop or mobile) resources.&lt;/p&gt;

&lt;h2&gt;
  
  
  Client-side dynamics
&lt;/h2&gt;

&lt;p&gt;Until very recently, and ever since libraries like jQuery and JavaScript frameworks like AngularJS, Ember, Backbone emerged and became so popular, around 2009, almost everything dynamic happened on the client-side. In addition to the interpretation of JavaScript during execution, to offer good performance, the stars had to align:  the requested data had to be distributed -served from the cache of a CDN- to avoid high latency, the user connection had to be fast, and they needed to be on a high-end, high-capacity terminal.&lt;/p&gt;

&lt;p&gt;In reality, we don’t know the user’s system capacity at any time. And that’s a hindrance.&lt;/p&gt;

&lt;h2&gt;
  
  
  We try to prevent exhausting end-user terminal resources
&lt;/h2&gt;

&lt;p&gt;In theory, if we ran lower level code, we would be using less resources. That's more than a theory. Go to this video where I demonstrate &lt;a href="https://pagefind.app/"&gt;Pagefind&lt;/a&gt;, written in Rust and compiled to Wasm as target, as a static app that ingests and indexes HTML documents and runs super efficient search queries, all client-side.&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://www.youtube.com/watch?t=967&amp;amp;v=znMeeexyj_c&amp;amp;feature=youtu.be" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--jMh4FpxB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.ytimg.com/vi/znMeeexyj_c/maxresdefault.jpg" height="450" class="m-0" width="800"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://www.youtube.com/watch?t=967&amp;amp;v=znMeeexyj_c&amp;amp;feature=youtu.be" rel="noopener noreferrer" class="c-link"&gt;
          Portable, secure, and lightweight: Wasm runtimes and their use-cases by Natalia Venditto - YouTube
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          WebAssembly, a super lightweight binary compilation target has been around for a while. But it's only now taking off, amidst additional enhancements, like WA...
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://res.cloudinary.com/practicaldev/image/fetch/s--neuEwGnQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://www.youtube.com/s/desktop/e1f38dd5/img/favicon.ico" width="16" height="16"&gt;
        youtube.com
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  Going lower, to reach higher
&lt;/h2&gt;

&lt;p&gt;That's Wasm. A (web) standard binary instructions compilation target that runs on the browser, implementing a system of imports and exports. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6wNZkzng--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8edwzd290jhl6w02pu62.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6wNZkzng--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8edwzd290jhl6w02pu62.png" alt="Wasm imports and exports" width="800" height="373"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You literally write the code in the language you prefer, and given the toolchain is in place -and it's in (experimental or preview) place for JavaScript, with teams working on it, like for example &lt;a href="https://github.com/bytecodealliance/jco"&gt;JCO&lt;/a&gt;- you can compile with Wasm as target.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SI6nsgWe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xdeltzjnvew653kpxlp0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SI6nsgWe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xdeltzjnvew653kpxlp0.png" alt="Wasm toolchain" width="800" height="413"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://microfrontend.dev/web-standards/micro-frontends-webassembly/"&gt;Learn more about Wasm&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  At the edge of the cloud
&lt;/h2&gt;

&lt;p&gt;We have seen how we can run Wasm on the browser to attain a high level of performance with low bandwidth cost, client-side. But what about server-side or in an isomorphic way?&lt;/p&gt;

&lt;p&gt;Cloud technologies -and emerging JavaScript meta-frameworks- allow us to render, cache, and then rehydrate dynamic parts of a (server rendered) static page based on rules, cookies or headers and other composability strategies. &lt;/p&gt;

&lt;p&gt;This allows us to build dynamic experiences with a &lt;code&gt;backend for frontend&lt;/code&gt; approach, preventing the execution of JavaScript to happen client-side, with the unavoidable performance degradation.&lt;/p&gt;

&lt;h2&gt;
  
  
  And where does this compute or execution run?
&lt;/h2&gt;

&lt;p&gt;On serverless functions, we can run it on Node.js as runtime on a host built specifically for that purpose. Yet this serverless environments that run at the heart of data-centers, have some drawbacks. They experience something known as cold-start: a mix of the time necessary for the runtime to start, load dependencies, execute the function, and the latency imposed by the physical distance between the server and the end-user terminal.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lighter runtimes
&lt;/h2&gt;

&lt;p&gt;How can we spin lighter runtimes in the cloud, at the edge of the network? Intuitively we know that edge means we're closer to the user, and we can reduce latency. But how do we run lower level code, which is faster and more lightweight, and hence more performant, on a non-browser environment?&lt;/p&gt;

&lt;p&gt;We can do that also server-side, -or on non-browser environments- with WASI enabled Wasm. If WebAssembly is a compilation target that uses a system of imports and exports to enable access to APIs from the Web Platform using the browser as execution engine-, WASI is a POSIX compatible system interface that enables that imports and exports strategy to exist where the browser is not part of the host.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Fy6UNJEy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zgb0a9l9389kjrk7ipnn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Fy6UNJEy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zgb0a9l9389kjrk7ipnn.png" alt="WASI enabled Wasm" width="800" height="399"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This enables the ultimate level of portability of a sandboxed runtime, from frontend to backend, to a myriad of systems and devices.&lt;/p&gt;

&lt;p&gt;Don't read me say it, see me at it!&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://www.youtube.com/watch?t=1298&amp;amp;v=znMeeexyj_c&amp;amp;feature=youtu.be" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--jMh4FpxB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.ytimg.com/vi/znMeeexyj_c/maxresdefault.jpg" height="450" class="m-0" width="800"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://www.youtube.com/watch?t=1298&amp;amp;v=znMeeexyj_c&amp;amp;feature=youtu.be" rel="noopener noreferrer" class="c-link"&gt;
          Portable, secure, and lightweight: Wasm runtimes and their use-cases by Natalia Venditto - YouTube
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          WebAssembly, a super lightweight binary compilation target has been around for a while. But it's only now taking off, amidst additional enhancements, like WA...
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://res.cloudinary.com/practicaldev/image/fetch/s--neuEwGnQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://www.youtube.com/s/desktop/e1f38dd5/img/favicon.ico" width="16" height="16"&gt;
        youtube.com
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Here are the slides for the conference talk I based this article on, &lt;a href="https://slides.com/anfibiacreativa/wasm-runtimes-portable-secure-lightweight/fullscreen"&gt;https://slides.com/anfibiacreativa/wasm-runtimes-portable-secure-lightweight/fullscreen&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Micro-frontends and beyond: composable frontend applications</title>
      <dc:creator>Natalia Venditto</dc:creator>
      <pubDate>Tue, 25 Apr 2023 10:12:34 +0000</pubDate>
      <link>https://dev.to/playfulprogramming/micro-frontends-and-beyond-composable-frontend-applications-3j0f</link>
      <guid>https://dev.to/playfulprogramming/micro-frontends-and-beyond-composable-frontend-applications-3j0f</guid>
      <description>&lt;p&gt;Hi folks! It's been a while I don't post here, and there is a reason why. Besides being quite busy with work, back in December last year I decided to use part of my vacation to start a website to publish all I've learned over the years about web development, cloud development and architecture. You can visit it at &lt;a href="https://www.microfrontend.dev" rel="noopener noreferrer"&gt;microfrontend.dev&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  My journey with micro-frontends
&lt;/h2&gt;

&lt;p&gt;I started experimenting with optimized and performant patterns and architectures to ship enhanced frontend applications, when I was a frontend technical lead for a large enterprise platform operating globally. We were maintaining its legacy version, and at some point, we decided to migrate. That's when I started my transition from developer and lead developer to architect. There was a lot going on: we were also moving from on-prem to the cloud. We were shipping a new platform to a new market. The team was growing from 10 to over a hundred. We were maintaining 3 legacy and a brand new code base, dozens of projects mapping to respective business units, and hundreds of localized websites, and we wanted to do it in the most efficient way for the stakeholders, the developers involved, and overall, the end-users. We also had external teams collaborating. It was not an easy endeavour, and I shared part of that adventure in a post that's been one of the most popular I've written in this platform &lt;a href="https://dev.to/this-is-learning/micro-frontends-my-lessons-learned-1pcp"&gt;Micro frontends: my lessons learned&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The motivation to build a website about micro-frontends
&lt;/h2&gt;

&lt;p&gt;I spent most of 2020 and 2021 writing and doing public speaking online and on-site, about micro-frontend architectures, and later on, when I joined MongoDB as an architect, about data and how to connect the dots between data sources and the application layer, in the cloud. I visited multiple podcasts, too, and tried to spread as much of my knowledge, gained through experience designing, building and shipping to production, composable architectures in the cloud  over serverless and event-driven components.&lt;/p&gt;

&lt;p&gt;You can access some of that content here, under &lt;a href="https://microfrontend.dev/resources/" rel="noopener noreferrer"&gt;Content created by me&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But that wasn't enough. I wanted to write a book.&lt;/p&gt;

&lt;p&gt;I thought that writing a book would be beneficial for my career. I realized -and still think that it is the case- only published authors are somewhat taken seriously. Especially if you're a woman, it takes you a lot more effort to get visibility and for your opinions and research to be taken seriously.&lt;/p&gt;

&lt;p&gt;But writing a book demands you subscribe to a publishers schedule. And I was already plenty busy and meeting deadlines at work; it didn't appear to be feasible. Especially after joining Microsoft to lead the e2e DX for JavaScript on Azure.&lt;/p&gt;

&lt;p&gt;This is when I decided to publish a website.&lt;/p&gt;

&lt;h2&gt;
  
  
  If I don't have time for a book, I'll make it a website
&lt;/h2&gt;

&lt;p&gt;And that's how microfrontend.dev was born. Not before my good friend &lt;a href="https://wassim.dev" rel="noopener noreferrer"&gt;Wassim&lt;/a&gt; bought a domain for me.&lt;/p&gt;

&lt;p&gt;Shipping my knowledge and opinions as a website makes them accessible to everyone. And I do believe that's a good thing. &lt;/p&gt;

&lt;p&gt;I have debated open-sourcing it, but I would like for the &lt;a href="https://microfrontend.dev/backlog/" rel="noopener noreferrer"&gt;backlog&lt;/a&gt; to be completed first. I can't believe it went live for the first time on the 6th of January, and we're already almost in May.&lt;/p&gt;

&lt;p&gt;Ever since, it has been visited by people from over 70 countries and hundreds of cities. I hope it's helping folks get a better understanding of some of the technologies, patterns, mechanisms and frameworks explored. I have a lot of pending topics to address, and I hope I find time soon to continue to develop it, improve it and expand on those topics and more.&lt;/p&gt;

&lt;p&gt;If you find it useful, please visit it, share it with others, leave a comment here. Do you have topics you would love for me to add? Let me know!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;For publishers: I may still be interested in writing that book. Especially now I have most of it put together ;)&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  More on the subject of composable architectures
&lt;/h2&gt;

&lt;p&gt;If you visit my website and want to know more, I will be speaking at the &lt;a href="https://www.oreilly.com/live-events/software-architecture-superstream-frontend-architectures/0636920089139/?_gl=1*1jrylwn*_ga*MjA3OTU2MTY3Ni4xNjgwMjg5Mzk5*_ga_092EL089CH*MTY4MTIzNjQ1NC4zLjEuMTY4MTIzNjUzMi40My4wLjA." rel="noopener noreferrer"&gt;O'Reilly Architecture Superstream&lt;/a&gt; on the 31st of May, precisely on this subject. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;As a woman in technologies and a web software architect who's always been interested in innovating, disrupting, finding new ways to architect frontend applications with performance and user experience in mind, and bring professional frontend development closer to everyone, it was very exciting to get an invitation to participate and share my ideas at such a prestigious event&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;I wish you all a great week, and hope to hear from you soon!&lt;/p&gt;

&lt;p&gt;Tiny edit: if you want to get more tech content from me around JavaScript, TypeScript, VSCode, Azure... 🙏 me on twitter (I still don't have a BlueSky...) &lt;a href="https://twitter.com/AnfibiaCreativa" rel="noopener noreferrer"&gt;https://twitter.com/AnfibiaCreativa&lt;/a&gt;&lt;/p&gt;

</description>
      <category>microfrontends</category>
      <category>frontend</category>
      <category>webdev</category>
      <category>cloud</category>
    </item>
    <item>
      <title>Bases de datos: operar con la base de datos - parte 2</title>
      <dc:creator>Natalia Venditto</dc:creator>
      <pubDate>Thu, 25 Aug 2022 11:54:06 +0000</pubDate>
      <link>https://dev.to/anfibiacreativa/bases-de-datos-operar-con-la-base-de-datos-parte-2-13b0</link>
      <guid>https://dev.to/anfibiacreativa/bases-de-datos-operar-con-la-base-de-datos-parte-2-13b0</guid>
      <description>&lt;p&gt;En la entrada anterior aprendimos cómo crear una base de datos y una colección, y también empezamos a trabajar con la base de datos usando las operaciones CRUD para crear documentos. &lt;/p&gt;

&lt;p&gt;Al final de la entrada, les recomendé utilizar el comando &lt;code&gt;mongoimport&lt;/code&gt; de las herramientas de base de datos, para importar un set o conjunto de datos más extenso, y así poder trabajar con MQL de manera más compleja. &lt;/p&gt;

&lt;p&gt;Si no lo hicieron, les recomiendo ir a la entrada 3 y seguir las instrucciones.&lt;/p&gt;

&lt;h2&gt;
  
  
  Operaciones CRUD para leer documentos
&lt;/h2&gt;

&lt;p&gt;Hoy vamos a aprender a usar MQL, el lenguaje de consultas de MongoDB para, justamente, consultar nuestra base de datos de &lt;code&gt;redtatuaje&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Como aprendimos en la entrada anterior, vamos a usar la terminal para conectar a nuestro servidor local, y usar la base de datos deseada y colección, deseadas.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--k84IfYVD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e2jye1asf1x50k4nuyrk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--k84IfYVD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e2jye1asf1x50k4nuyrk.png" alt="conectar a mongodb servidor local" width="800" height="689"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Operación CRUD findOne()
&lt;/h3&gt;

&lt;p&gt;Lo primero que vamos a hacer es inspeccionar cualquier documento de la base de datos, de manera aleatoria, solo para ver qué estructura tiene un documento.&lt;/p&gt;

&lt;p&gt;Lo haremos ejecutando primero, como aprendimos antes, &lt;code&gt;show collections&lt;/code&gt; para ver qué colecciones tenemos disponibles y asegurarnos que hemos importado correctamente los datos, para poder seguir las indicaciones de esta entrada. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jLpmRGg2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/npgwpf2c3t5ofvnspqyj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jLpmRGg2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/npgwpf2c3t5ofvnspqyj.png" alt="mostrar las colecciones mongodb" width="800" height="76"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;y luego ejecutando&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;db.artistas.findOne()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--t2ca2Ppo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/le2nq6exbt52meze6mkz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--t2ca2Ppo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/le2nq6exbt52meze6mkz.png" alt="mongodb metodo findOne() " width="800" height="689"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;findOne()&lt;/code&gt; devuelve el primer documento que encuentra, que satisface un determinado criterio de consulta, es decir, el primero a partir del orden natural en el que se encuentran los documentos. Si la colección tiene un límite de algún tipo (generalmente en MB), entonces el orden natural corresponde al orden de inserción. En este caso vemos que devuelve el correspondiente al &lt;code&gt;artist_id: 743&lt;/code&gt; correspondiente al &lt;code&gt;name: "Alex Holt"&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Parámetros opcionales de &lt;code&gt;findOne()&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;El método findOne() acepta que se le pasen dos argumentos &lt;strong&gt;opcionales&lt;/strong&gt; para determinar ese criterio. Por ejemplo, podemos decir&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;db.artistas.findOne(query, projection)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;la consulta en sí, y una condición de proyección.&lt;/p&gt;

&lt;p&gt;Si vemos la imagen anterior, podemos comprobar que para el artista de id 743, la propiedad &lt;code&gt;owns_studio&lt;/code&gt;, tiene el valor &lt;code&gt;Yes&lt;/code&gt;. Podemos pedir a MongoDB que nos devuelva el primero por orden natural, para que ese valor sea &lt;code&gt;No&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;db.artistas.findOne({ "owns_studio": "No"})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FiPUxqjq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3eyh234dzrt8ogmkdelo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FiPUxqjq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3eyh234dzrt8ogmkdelo.png" alt="findOne() pasandole una consulta" width="800" height="686"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;En cuyo caso, como podemos ver, el id de artista es ahora &lt;code&gt;701&lt;/code&gt;, correspondiente a la artista de &lt;code&gt;name: "Sue King"&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Proyección de consultas (Projection)
&lt;/h2&gt;

&lt;p&gt;Pero hemos dicho que este método además aceptaba un segundo parámetro adicional, de proyección. ¿Qué significa eso?&lt;/p&gt;

&lt;p&gt;MongoDB siempre va a devolver los campos de un documento que se encuentran proyectados. Por defecto, todos los campos están proyectados, o sea tienen el valor de proyección a 1 o &lt;code&gt;true&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;1 u otros valores diferentes de 0 y true, especifican inclusión en la proyección&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Sin embargo, si explícitamente proyectamos un campo, solo se devolverá ese campo junto con el valor del &lt;code&gt;_id&lt;/code&gt;, que solo se excluye si se pone su valor de proyección explícitamente a 0 o &lt;code&gt;false&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Veamos un ejemplo&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;db.artistas.findOne({ "owns_studio": "No"}, {"owns_studio": 1, "name": 1})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8IjpwY23--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gt919sdy3l89f5akupc7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8IjpwY23--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gt919sdy3l89f5akupc7.png" alt="findOne() con consulta y proyección " width="800" height="684"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Si queremos omitir el valor del campo &lt;code&gt;_id&lt;/code&gt;, le tenemos que pasar 0 explícitamente (o &lt;code&gt;false&lt;/code&gt;)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;db.artistas.findOne({ "owns_studio": "No"}, {"owns_studio": 1, "name": 1, "_id": 0})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BQc8Ueln--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2pnxcuz0l0cvgpwmkhew.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BQc8Ueln--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2pnxcuz0l0cvgpwmkhew.png" alt="exluir el _id en la proyección Mongodb" width="800" height="258"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Vamos a ver a estudiar &lt;code&gt;Projection&lt;/code&gt; más adelante en la serie con más profundidad, ya que hay muchísimas más formas de proyectar, y formas especiales para datos más complejos, como los datos anidados, o los arreglos.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Operación CRUD find()
&lt;/h3&gt;

&lt;p&gt;Hasta ahora, como pedíamos MongoDB encontrar uno, o findOne(), siempre devolvía solo uno...Pero, ¿qué pasa cuando queremos una lista?&lt;/p&gt;

&lt;p&gt;Entonces debemos ejecutar&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;db.artistas.find()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pero espera...¿Qué ha pasado? ¿Nos ha devuelto los 1000 documentos que habíamos importado a la colección?&lt;/p&gt;

&lt;p&gt;No. Este método devuelve un &lt;code&gt;cursor&lt;/code&gt;, que es una referencia a un conjunto de resultados que devuelve una consulta, y que se pueden iterar. Es decir, podemos ver más de lo que hay en el cursor y luego acceder al documento que deseamos.&lt;/p&gt;

&lt;p&gt;Por defecto el cursor para find() nos muestra 101 resultados siempre que no se exceda el máximo tamaño de documento, que es de 16MB (como ya vimos en la entrada 1 de la serie) y una de las formas de obtener más es ejecutando &lt;code&gt;it&lt;/code&gt;, como vemos en la imagen.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qpzn3qUm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e0vnenc3jxdwq6gl1wgw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qpzn3qUm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e0vnenc3jxdwq6gl1wgw.png" alt="iterar el cursor en mongoDB" width="800" height="679"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;También podemos asignar el cursor a una variable (¡recordemos que estamos en un REPL completamente funcional!) y utilizar algunos de sus métodos. Por ejemplo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;tatuadores&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;artistas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;owns_studio&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Yes&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tatuadores&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hasNext&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
  &lt;span class="nf"&gt;printjson&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tatuadores&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aquí estamos usando los métodos &lt;code&gt;hasNext()&lt;/code&gt; que evalúa si hay más documentos que satisfagan la consulta, en el cursor, y utilizamos el método &lt;code&gt;next()&lt;/code&gt;, para iterarlos mientras &lt;code&gt;hasNext()&lt;/code&gt; devuelva &lt;code&gt;true&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Otros métodos del cursor son &lt;code&gt;forEach()&lt;/code&gt;, &lt;code&gt;toArray()&lt;/code&gt; y &lt;code&gt;objsLeftInBatch()&lt;/code&gt;, que nos dice cuántos objetos hay en el batch, después de ejecutar una iteración (o conjunto) devuelto.&lt;/p&gt;

&lt;p&gt;Podemos también utilizar el método &lt;code&gt;isExhausted()&lt;/code&gt; para comprobar que realmente no existen más objetos o documentos, en el cursor.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Recordemos que cada documento mapea a un objeto.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Una lista completa de métodos del cursor, se pueden encontrar &lt;a href="https://www.mongodb.com/docs/manual/reference/method/js-cursor/"&gt;aquí&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Cuando se usaba &lt;code&gt;find()&lt;/code&gt; con las versiones anteriores de la consola, se solía concatenar el método &lt;code&gt;pretty()&lt;/code&gt;, para que los resultados en el cursor se mostrasen formateados. En &lt;code&gt;mongosh&lt;/code&gt;, &lt;code&gt;pretty()&lt;/code&gt; se ejecuta por defecto.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Veamos un ejemplo de usar &lt;code&gt;forEach()&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;tatuadores&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;artistas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;owns_studio&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Yes&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;tatuadores&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;tatuador&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tatuador&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;payment_method&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Credit Card Only&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="nf"&gt;printjson&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tatuador&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Limitar el cursor a una cantidad específica de resultados en el batch
&lt;/h3&gt;

&lt;p&gt;En una base de datos muy grande, con documentos de tamaño muy pequeño, podríamos tener demasiada cantidad de objetos devueltos. Si queremos limitarlos de manera explicita para aumentar el rendimiento, podemos usar el método &lt;code&gt;limit()&lt;/code&gt;, de esta manera.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;db.artistas.find({"payment_method" : "Credit Card Only"}).limit(5)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Más información sobre el método &lt;code&gt;limit()&lt;/code&gt; se encuentra &lt;a href="https://www.mongodb.com/docs/manual/reference/method/cursor.limit/#mongodb-method-cursor.limit"&gt;aquí&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Parámetros opcionales de &lt;code&gt;find()&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;Find también acepta la configuración de dos parámetros opcionales: la consulta y la proyección.&lt;/p&gt;

&lt;h2&gt;
  
  
  Consultas complejas con operadores de consulta
&lt;/h2&gt;

&lt;p&gt;Vamos a empezar a realizar consultas más complejas, utilizando los operadores de comparación. En otras entradas exploraremos los lógicos, de elemento, de evaluación, de array y geoespaciales. Y por supuesto, haremos una entrada específica sobre proyección.&lt;/p&gt;

&lt;p&gt;¡Empecemos!&lt;/p&gt;

&lt;h3&gt;
  
  
  Encontrar un valor equivalente al pasado en la consulta: operador &lt;code&gt;$eq&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Este operador nos permite consultar la base de datos para encontrar todos los documentos que tienen un valor especifico que equivale al que se pasa. Por ejemplo, vamos a buscar todos los artistas que no tienen estudio propio.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Vamos a limitar las consultas siempre a 5 para reducir el tiempo de respuesta, pero eso no es un requerimiento.&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;db.artistas.find({ "owns_studio": { $eq: "No" } }).limit(5)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;El formato de la consulta es:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{ &amp;lt;campo&amp;gt;: { $eq: &amp;lt;valor&amp;gt; } }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Podemos decir que esto es equivalente a realizar esta consulta&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;db.artistas.find({ "owns_studio": "No" }).limit(5)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;sin embargo, al usar operadores, los podemos combinar o usar operadores lógicos, para consultas más complejas, como veremos mientras progresemos.&lt;/p&gt;

&lt;h3&gt;
  
  
  Encontrar un valor más grande que el valor pasado: operador &lt;code&gt;$gt&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Este operador nos permite encontrar los documentos para los cuales el valor del campo pasado, es más grande que el especificado. En este caso, todos los artistas con un identificador más grande que 500&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;db.artistas.find({ "artist_id": { $gt: 500 } }).limit(5)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;El formato de la consulta es:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{ &amp;lt;campo&amp;gt;: { $gt: &amp;lt;valor&amp;gt; } }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Igualmente podemos encontrar valores más grandes o iguales al valor pasado, con &lt;code&gt;$gte&lt;/code&gt;, más pequeños con &lt;code&gt;$lt&lt;/code&gt;, o más pequeños o iguales al valor pasado, con &lt;code&gt;$lte&lt;/code&gt;. La sintaxis es la misma.&lt;/p&gt;

&lt;h3&gt;
  
  
  Encontrar todos los valores diferentes a: operador &lt;code&gt;$ne&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;ne&lt;/code&gt; vendría a significar &lt;code&gt;not equal&lt;/code&gt;, o &lt;code&gt;no igual&lt;/code&gt;. Lo usamos para encontrar todos los documentos cuyo valor no es igual al pasado.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;db.artistas.find({ "artist_id": { $ne: 500 } }).limit(5)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Por supuesto que no necesariamente estamos haciendo comparaciones numéricas. Estamos comparando valores literales. Por lo cual, podemos pasar cualquier tipo.&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;db.artistas.find({ "name": { $ne: "Cordelia Swanson" } }).limit(5)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Y esto es cierto para las comparaciones de arriba, también. Por ejemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;db.artistas.find({ "country": { $lt: "PE" } }).limit(5)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Donde devolverá todos los valores más pequeños que "PE" como código de país, en orden alfabético.&lt;/p&gt;

&lt;h2&gt;
  
  
  Comparar fechas con operadores de comparación
&lt;/h2&gt;

&lt;p&gt;También los podemos usar para las fechas. Por ejemplo, si queremos encontrar a todos los artistas que se unieron a la plataforma hace un año o más, lo haríamos así:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;db.artistas.find({ "joined_network": { $lte: new Date("2021-08-12") } }).limit(5)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Excluir resultados que contengan un valor en un campo array: operador &lt;code&gt;$nin&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Este operador &lt;code&gt;not in&lt;/code&gt;, nos permite excluir objetos del cursor, sí contienen un cierto valor en un campo de tipo arreglo. &lt;/p&gt;

&lt;p&gt;Por ejemplo, supongamos que queremos filtrar a todos los artistas que se dedican a los estilos &lt;code&gt;geometric&lt;/code&gt; y &lt;code&gt;realism&lt;/code&gt;, de nuestro cursor de resultados.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;db.artistas.find({ "styles": { $nin: ["geometric", "realism"] } }).limit(10)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;$nin&lt;/code&gt; también puede usarse para excluir del cursor los documentos &lt;strong&gt;que no contienen&lt;/strong&gt; un cierto campo. &lt;/p&gt;

&lt;p&gt;Más información sobre este operador de condición, se encuentra en &lt;a href="https://www.mongodb.com/docs/manual/reference/operator/query/nin/#mongodb-query-op.-nin"&gt;la documentación&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  MQL en el mongosh vs. operar con un driver
&lt;/h2&gt;

&lt;p&gt;No se debe confundir los métodos de operación de MQL en la consola de MongoDB, con los métodos que provean los diferentes drivers cuando se está escribiendo una aplicación.&lt;/p&gt;

&lt;p&gt;Muchos de estos drivers (o software intermedio) crean capas de abstracción para simplificar la combinación de operadores, y es posible que ofrezcan diferentes métodos para operar con la base de datos.&lt;/p&gt;

&lt;p&gt;En la próxima entrada, vamos a usar operadores lógicos. ¡Hasta entonces!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Gracias especiales a &lt;a class="mentioned-user" href="https://dev.to/wassimchegham"&gt;@wassimchegham&lt;/a&gt; que siempre me revisa los screenshots y a &lt;a class="mentioned-user" href="https://dev.to/dfreniche"&gt;@dfreniche&lt;/a&gt; al que le pedí peer review, y me contesto "RIGHT NAO!" &amp;lt;3&lt;/em&gt;&lt;/p&gt;

</description>
      <category>basesdedatos</category>
      <category>mongodb</category>
      <category>mql</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Bases de datos: operar con la base de datos - parte 1</title>
      <dc:creator>Natalia Venditto</dc:creator>
      <pubDate>Wed, 03 Aug 2022 17:58:36 +0000</pubDate>
      <link>https://dev.to/anfibiacreativa/bases-de-datos-operar-con-la-base-de-datos-parte-1-25h7</link>
      <guid>https://dev.to/anfibiacreativa/bases-de-datos-operar-con-la-base-de-datos-parte-1-25h7</guid>
      <description>&lt;p&gt;En las entradas anteriores hablamos del modelo de documento y del particionamiento de bases de datos distribuidas, que corresponden a ese modelo. ¡Llegó el momento de trabajar un poco con las mismas! &lt;/p&gt;

&lt;h2&gt;
  
  
  Pre-requisitos
&lt;/h2&gt;

&lt;p&gt;Para poder experimentar deberán tener instalado &lt;a href="https://www.mongodb.com/try/download/community" rel="noopener noreferrer"&gt;MongoDB Community Server&lt;/a&gt; y las herramientas de terminal y extensiones necesarias. Pueden ir a la primera entrada de esta serie, para encontrar indicaciones. También pueden instalar &lt;a href="https://www.mongodb.com/products/compass" rel="noopener noreferrer"&gt;Compass&lt;/a&gt;, la herramienta gratuita de Interfaz Gráfica Visual de MongoDB. &lt;/p&gt;

&lt;h2&gt;
  
  
  Crear una base de datos MongoDB desde la terminal
&lt;/h2&gt;

&lt;p&gt;Vamos a empezar trabajando con la &lt;a href="https://www.mongodb.com/try/download/shell" rel="noopener noreferrer"&gt;Mongo Shell&lt;/a&gt;. Una vez está instalada, la arrancamos así&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

mongosh


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk6wdne1qi5an44vy8u0x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk6wdne1qi5an44vy8u0x.png" alt="conexion mongosh a mongodb"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Eso nos conecta directamente a nuestro servidor local, lo cual podemos apreciar en la imagen, ya que al ejecutarlo se inicia una conexión a &lt;code&gt;127.0.0.1:27017&lt;/code&gt; o sea a la IP de bucle invertido, o &lt;code&gt;localhost&lt;/code&gt; en el puerto &lt;code&gt;27017&lt;/code&gt; que es el puerto que usa &lt;code&gt;mongod&lt;/code&gt; (o sea el proceso mongo daemon del que hablamos en la primera entrada de la serie) por defecto. Además inicializa el entorno REPL JavaScript (read-evaluation-print loop o bucle de lectura, evaluación y salida).&lt;/p&gt;

&lt;p&gt;Más adelante conectaremos a un despliegue remoto, para lo que necesitaremos usar una cadena de conexión pero por ahora trabajaremos en local.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mostrar las bases de datos existentes: &lt;code&gt;show dbs&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Para ver las bases de datos que existen en nuestro servidor vamos a usar el comando &lt;code&gt;show&lt;/code&gt;. Simplemente escribimos en la terminal &lt;code&gt;show dbs&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0b4qxb5fr5zdzm2cmu6y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0b4qxb5fr5zdzm2cmu6y.png" alt="show dbs mongodb"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cuando se instala un servidor, MongoDB crea algunas bases de datos que utiliza el sistema para operar, como &lt;code&gt;admin&lt;/code&gt;, &lt;code&gt;config&lt;/code&gt; y &lt;code&gt;local&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Nota: No se recomienda manipular las bases de datos por defecto, ya que  puede alterar el correcto funcionamiento del sistema.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  El comando &lt;code&gt;use&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Para cambiarnos de base de datos usamos el comando &lt;code&gt;use&lt;/code&gt;, al que le pasamos el nombre de la base de datos que queremos utilizar. &lt;/p&gt;

&lt;p&gt;En mi caso ya tengo una base datos adicional que se llama &lt;code&gt;Items&lt;/code&gt; de modo que si ejecuto&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

use Items


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;el sistema &lt;em&gt;va a usar esa base de datos&lt;/em&gt;, como se ve en la captura.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm102obedv6bo08fjwgop.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm102obedv6bo08fjwgop.png" alt="mongodb comando use"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pero...qué pasa si ejecuto &lt;code&gt;use&lt;/code&gt;, con una base de datos que no existe. Vamos a verlo...&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

use Item


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft0mxh2xnikapg4lhzsjb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft0mxh2xnikapg4lhzsjb.png" alt="mongodb comando use"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;En este caso el sistema creará una referencia a una base de datos de ese nombre. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;¡Pero cuidado! Mientras esa base de datos esté vacía, no será listada, como podemos ver en la siguiente captura&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1kn4yk59v8l8gky0458i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1kn4yk59v8l8gky0458i.png" alt="mongodb comando use db vacia"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hay que tener cuidado con la puntuación, entonces, porque si estamos trabajando con la base de datos &lt;code&gt;Items&lt;/code&gt; y nos equivocamos y escribimos &lt;code&gt;Item&lt;/code&gt;, estaremos creando esa base de datos nueva. ¡Con las colecciones, pasa lo mismo! Esto es el comportamiento por diseño de MongoDB y por eso, para evitar operar con una base de datos o colección incorrecta cuando usamos los drivers desde una aplicación, hay que seguir buenas prácticas que nos eviten dolores de cabeza, como por ejemplo asignar esos nombres a constantes.&lt;/p&gt;

&lt;p&gt;Cuando usamos &lt;code&gt;use&lt;/code&gt;, entonces, lo que hacemos es asignar un valor al objeto &lt;code&gt;db&lt;/code&gt; que ahora apuntará a una base de datos en concreto. Si simplemente ejecutamos &lt;code&gt;db&lt;/code&gt;, nos dirá cuál es ese base de datos.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbd3jmp771rt86anp0ct9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbd3jmp771rt86anp0ct9.png" alt="mongodb comando use"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;show collections&lt;/code&gt; para mostrar colecciones
&lt;/h2&gt;

&lt;p&gt;Para saber qué colecciones existen en una base de datos una vez que la estamos usando, ejecutamos &lt;code&gt;show collections&lt;/code&gt; en la misma. &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

show collections


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzvfbe3jqc1vyw3j2lt7q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzvfbe3jqc1vyw3j2lt7q.png" alt="mongodb show collections"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Dado que &lt;code&gt;Item&lt;/code&gt; no tiene ninguna colección, no devuelve nada. Así que vamos a crear una colección. Podemos usar el método &lt;code&gt;createCollection()&lt;/code&gt; del objeto db.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

db.createCollection("items")


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjpyv8efkx0ie9di3xs05.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjpyv8efkx0ie9di3xs05.png" alt="mongo db create collection"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Nota: métodos adicionales se pueden encontrar en la &lt;a href="https://www.mongodb.com/docs/manual/reference/method/js-database/" rel="noopener noreferrer"&gt;documentación oficial&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Podemos ver que al ejecutar &lt;code&gt;show collections&lt;/code&gt;, nos muestra la colección &lt;code&gt;items&lt;/code&gt; que existe en nuestra base de datos activa.&lt;/p&gt;

&lt;p&gt;También podemos ejecutar&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

db.[nombre_de_collección]


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Por ejemplo &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvslodvlv4cd48kqa4cd9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvslodvlv4cd48kqa4cd9.png" alt="mongodb show collection"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;¡A prestar atención! Porque hemos escrito &lt;code&gt;item&lt;/code&gt; como nombre de colección. Dado que no existe, MongoDB la creará.&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Operaciones CRUD para operar con documentos
&lt;/h2&gt;

&lt;p&gt;Para demostrar este último concepto, vamos a utilizar nuestro primer operaciones CRUD, a nivel colección. Podemos encontrar un listado completo de los mismos en la &lt;a href="https://www.mongodb.com/docs/manual/reference/method/js-collection/" rel="noopener noreferrer"&gt;documentación&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hasta ahora tenemos una colección llamada &lt;code&gt;items&lt;/code&gt;. Cuando ejecutamos &lt;code&gt;show collections&lt;/code&gt;, es la única que aparece. Pero si ejecutamos&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

db.item.insertOne({})


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;y luego ejecutamos &lt;code&gt;show collections&lt;/code&gt;, veremos que ahora que hemos insertado un documento vacío, entonces aparecen ambas colecciones.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj1zkkxqdfhs308zkgt0i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj1zkkxqdfhs308zkgt0i.png" alt="mongo db show collection colección vacia"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Lo importante a tener en cuenta, es que por diseño MongoDB creará una base de datos o colección que no existe, si se opera con las mismas.&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Hemos por fin ejecutado nuestra primera operación CRUD para crear un documento nuevo. Dado que le hemos pasado un objeto vacío &lt;code&gt;{}&lt;/code&gt; al método, el documento está vacío a excepción del identificador de tipo &lt;code&gt;ObjectId&lt;/code&gt; que MongoDB asigna automáticamente a todos los documentos. Más adelante en la serie cuando hablemos de indexes (indíces) explicaremos más sobre el campo &lt;code&gt;_id&lt;/code&gt; y cómo puede customizarse según las necesidades de nuestra aplicación, ya que este campo siempre se indexa como clave primaria de una colección.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;El campo automático &lt;code&gt;_id&lt;/code&gt; o identificador único de documento, de tipo &lt;code&gt;ObjectId&lt;/code&gt; se auto-indexa y es clave primaria de cada colección.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Si ahora ejecutamos el método &lt;code&gt;findOne()&lt;/code&gt;, podemos ver la estructura del documento.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbkvhi0lf1jd2cd2rzbb6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbkvhi0lf1jd2cd2rzbb6.png" alt="mongodb"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Operaciones CRUD
&lt;/h2&gt;

&lt;p&gt;Las operaciones CRUD (create, read, update, delete en Inglés) nos permiten operar con la base de datos para crear, leer, actualizar y borrar datos o documentos, en la base de datos. &lt;/p&gt;

&lt;p&gt;Cuando operamos con la base de datos, generalmente usamos una o una combinación de éstas operaciones convencionales.  &lt;/p&gt;

&lt;p&gt;Vamos a empezar con las operaciones que crean documentos.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creación de documentos
&lt;/h3&gt;

&lt;p&gt;Como ya pudimos observar anteriormente, podemos crear un documento a través del método &lt;code&gt;insertOne( {&amp;lt;documento&amp;gt;} )&lt;/code&gt;, al que pasamos un objeto que representa el documento. Si no pasamos ninguna propiedad, se creará un documento vacío, con un identificador único.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

db.[nombre-de-colección].insertOne({ "nombre": "Documento1", "estaEscrito": true })


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Además de &lt;code&gt;insertOne()&lt;/code&gt; al que pasamos un solo objeto, podemos utilizar &lt;code&gt;insertMany()&lt;/code&gt; para insertar múltiples documentos en la base de datos por medio de un arreglo.&lt;/p&gt;

&lt;p&gt;Para probarlo, vamos a ejecutar&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

db.item.insertMany([{},{},{}])


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fta2mmv54tbt8z3karg4z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fta2mmv54tbt8z3karg4z.png" alt="mongodb insertando documentos"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Tengan en cuenta que obviamente, los identificadores que se generarán en la ejecución de ustedes, serán otros.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Ahora vamos a actualizar uno de estos documentos de la colección, utilizando &lt;code&gt;updateOne()&lt;/code&gt;. Este método espera recibir una condición para filtrar el documento deseado (en nuestro caso sólo podemos pasarle el &lt;code&gt;_id&lt;/code&gt;, y un objeto con el campo que se va a modificar, que se pasa al método &lt;code&gt;$set&lt;/code&gt;, así:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

db.item.updateOne({ "_id": ObjectId("62e7f362b654003b0ba25e4a")}, // esto es el filtro que encuentra el documento a actualizar {$set: {"campo_nuevo": true}} // $set le agregará el campo_nuevo, o lo actualizará si existiera)


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6xr569hq1zj9ewwj68gs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6xr569hq1zj9ewwj68gs.png" alt="mongodb update document"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcuk3sdd95elmmrg90giw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcuk3sdd95elmmrg90giw.png" alt="mongodb update document"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Por cierto, cuando hablamos en la jerga de MongoDB en inglés, los métodos que tienen un &lt;code&gt;$&lt;/code&gt; antes del nombre, se suelen decir como &lt;code&gt;dollar-nombre&lt;/code&gt;. En este caso, se leerá &lt;code&gt;dollar-set&lt;/code&gt;.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;También podemos pasar &lt;code&gt;upsert&lt;/code&gt; como parámetro adicional del objeto &lt;code&gt;options&lt;/code&gt; que recibe opcionalmente este método, lo que garantizará que si el filtro no encuentra ninguna correspondencia, se creará el documento. Para demostrarlo, le cambiamos los 4 últimos dígitos a cualquiera de los ids que nos devuelva por &lt;code&gt;0000&lt;/code&gt;(¡a menos que ya exista uno que termine con 0000! Entonces elegiremos 4 cifras que no existan. 😅)&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

db.item.updateOne({ "_id": ObjectId("62e7f362b654003b0ba20000")}, {$set:{"campo_nuevo": true}},{ upsert: true })


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7vq6rb3elocz7gsldl3l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7vq6rb3elocz7gsldl3l.png" alt="mongodb update document"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Otras opciones que recibe este método, se pueden aprender &lt;a href="https://www.mongodb.com/docs/manual/reference/method/db.collection.updateOne/" rel="noopener noreferrer"&gt;aquí&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Más métodos que crean documentos
&lt;/h3&gt;

&lt;p&gt;Otros métodos que crean documentos cuando se les pasa la opción &lt;code&gt;upsert&lt;/code&gt; a &lt;code&gt;true&lt;/code&gt;, se especifican en &lt;a href="https://www.mongodb.com/docs/manual/reference/insert-methods/" rel="noopener noreferrer"&gt;está página&lt;/a&gt;, y más métodos adicionales de actualización, se explican &lt;a href="https://www.mongodb.com/docs/manual/reference/update-methods/" rel="noopener noreferrer"&gt;aquí&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Documentos con estructura diferente?
&lt;/h2&gt;

&lt;p&gt;Se dieron cuenta, ¿verdad? Al haber actualizado un par de los documentos, existen documentos en una misma colección, con una estructura distinta. Esto es perfectamente posible en MongoDB y el modelo documento, porque aunque se puede implementar un &lt;code&gt;schema&lt;/code&gt; y proceder a la validación de datos a través del mismo, no es obligatorio tenerlo. Sin embargo, &lt;strong&gt;&lt;u&gt;no es recomendable desde el punto de vista funcional que los documentos de una misma colección tengan campos totalmente diferentes&lt;/u&gt;&lt;/strong&gt;, aunque está cualidad permite agregar campos a ciertos documentos de la colección, sin tener que &lt;code&gt;nulificar&lt;/code&gt; (o para no inventarme términos raros, dar un valor &lt;code&gt;null&lt;/code&gt;) al mismo campo en aquellos documentos para los que no existe el valor -o la propiedad no aplica-. Esto puede ser útil para ciertos casos de uso, en el modelado de datos.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Existen documentos en esta colección con una estructura distinta. Esto es perfectamente posible en MongoDB y el modelo documento, porque aunque se puede implementar un &lt;code&gt;schema&lt;/code&gt; y proceder a la validación de datos a través del mismo, no es obligatorio tenerlo.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Utilizar &lt;code&gt;mongoimport&lt;/code&gt; para importar datos a una base de datos MongoDB
&lt;/h3&gt;

&lt;p&gt;Para poder hacer uso de esta utilidad, tendremos que haber instalado las &lt;code&gt;herramientas de base de datos&lt;/code&gt; como se indica en &lt;a href="https://www.mongodb.com/docs/database-tools/installation/installation/" rel="noopener noreferrer"&gt;este documento&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Además, pueden &lt;code&gt;forkear&lt;/code&gt; (me encanta escribir entradas en español y darme cuenta que no tengo ni idea de cómo traducir algunas operaciones de GIT. ¡Espero no ofender a nadie!) este &lt;a href="https://github.com/anfibiacreativa/atlas-serverless" rel="noopener noreferrer"&gt;repo&lt;/a&gt;. Básicamente lo que van a necesitar hacer es importar &lt;a href="https://github.com/anfibiacreativa/atlas-serverless/blob/develop/database_exports/tattoonetwork/artists.json" rel="noopener noreferrer"&gt;este archivo&lt;/a&gt; que es un listado de artistas de tatuaje (¡que no existen! los generé con &lt;a href="https://www.npmjs.com/package/mgeneratejs" rel="noopener noreferrer"&gt;mgeneratejs&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Antes que nada, vamos a poner en uso algunos de los conceptos que aprendimos antes para crear una base de datos que se llame &lt;code&gt;redtatuaje&lt;/code&gt; y una colección que se llame &lt;code&gt;artistas&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A la misma le vamos a importar &lt;a href="https://github.com/anfibiacreativa/atlas-serverless/blob/develop/database_exports/tattoonetwork/artists.json" rel="noopener noreferrer"&gt;este archivo&lt;/a&gt; abriendo una nueva pestaña de la terminal (o ventana, según el caso -ojo! no mongosh o mongo, sino bash/zsh, etc) y  ejecutando&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

mongoimport --uri mongodb://localhost:27017 --db redtatuaje --collection artistas --file [ruta-al-archivo]/artists.json


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;em&gt;El comando anterior asume que el servidor está corriendo en el puerto por defecto 27017. Recuerden que si no crearon la base de datos y colección con anterioridad, o si la escriben de manera diferente (intencionalmente o por error), se crearán.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conectando a una base de datos remota
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;mongoimport&lt;/code&gt; y el resto de utilidades, se pueden usar también para operar con bases de datos remotas. Por ejemplo supongamos que tenemos un servidor Cosmos DB que creamos para usar con MongoDB API. Lo podemos crear directamente desde VS Code, con la &lt;a href="https://code.visualstudio.com/docs/azure/extensions" rel="noopener noreferrer"&gt;extensión de Azure Tools&lt;/a&gt;, o desde el portal de Azure. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq81lldjnqehry8741o4x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq81lldjnqehry8741o4x.png" alt="crear servidor cosmos db desde vs code"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Una vez creado, podemos obtener la cadena de conexión desde la extensión de VS Code directamente, haciendo click con el botón derecho del ratón para desplegar el menú, y luego haciendo click en &lt;code&gt;Copy connection string&lt;/code&gt;(obtener cadena de conexión) &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4cfijn1wnzzqpsji11q7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4cfijn1wnzzqpsji11q7.png" alt="copiar cadena de conexión cosmosdb mongodb api"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;o yendo a la página de configuración del recurso y copiando o pegando la cadena de &lt;code&gt;lectura + escritura&lt;/code&gt;, en este caso, ya que vamos a crear documentos.&lt;/p&gt;

&lt;h3&gt;
  
  
  Más sobre la cadena de conexión MongoDB
&lt;/h3&gt;

&lt;p&gt;Una cadena de conexión es precisamente una concatenación de argumentos que nos permiten establecer la conexión, y que en el caso de la de MongoDB, se compone del protocolo, que en el caso de MongoDB puede ser &lt;code&gt;mongodb&lt;/code&gt; o &lt;code&gt;mongodb + srv&lt;/code&gt;, el dominio de servidor (o IP) que se corresponde al parámetro &lt;code&gt;host&lt;/code&gt;, con su respectivo &lt;code&gt;puerto&lt;/code&gt;, el nombre de usuario o cuenta, la contraseña y algunos parámetros adicionales de configuración, como por ejemplo si utilizaremos &lt;code&gt;ssl&lt;/code&gt;, el nombre del conjunto de réplicas y si se intentará reescribir en caso de errores de conexión o retardos. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;La cadena de conexión es la concatenación de argumentos que nos permiten establecer la conexión con la base de datos, a la vez que configuramos ciertos aspectos de la misma.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Lo que vamos a hacer es copiar exactamente el comando de arriba, y reemplazar el valor de la opción &lt;code&gt;--uri&lt;/code&gt; que ahora apunta a localhost, por la cadena de conexión tal cual la obtuvimos del portal o la extensión de VS Code, &lt;strong&gt;puesta entre comillas.&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

mongoimport --uri "[cadena-de-conexión]" --db redtatuaje --collection artistas --file [ruta-al-archivo]/artists.json


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Eso nos permitirá importar los datos desde el archivo en nuestro ordenador local, para poder trabajar con los mismos en remoto.&lt;/p&gt;

&lt;p&gt;Más información sobre la cadena de conexión, la podemos leer &lt;a href="https://www.mongodb.com/docs/manual/reference/connection-string/" rel="noopener noreferrer"&gt;aquí&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ahora ya tenemos todo listo para consultar documentos locales o remotos de manera eficiente con MQL. ¡Nos vemos en la próxima entrada donde vamos a aprender a hacerlo!&lt;/p&gt;

&lt;p&gt;¡Hasta la próxima!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Bases de datos distribuidas: sharding.</title>
      <dc:creator>Natalia Venditto</dc:creator>
      <pubDate>Fri, 15 Jul 2022 12:30:38 +0000</pubDate>
      <link>https://dev.to/anfibiacreativa/bases-de-datos-distribuidas-sharding-4a39</link>
      <guid>https://dev.to/anfibiacreativa/bases-de-datos-distribuidas-sharding-4a39</guid>
      <description>&lt;p&gt;En el post anterior hablé de algunos conceptos básicos para entender el modelo de documento. Básicamente, el modelo de documento surgió de una necesidad real por parte de los desarrolladores de tener un sistema más idiomático de representar datos y sus relaciones, que se pudiera mapear a los objetos que típicamente creamos cuando usamos patrones de programación orientados a los mismos, OOP.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Básicamente, el modelo de documento surgió de una necesidad real por parte de los desarrolladores de tener un sistema más idiomático de representar datos y sus relaciones, que se pudiera mapear a los objetos&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Es preciso recordar que las primeras bases de datos relacionales de modelo tabular, surgieron en los 70. Es decir, cuando el uso que se le daba a los sistemas computacionales era diferente del de ahora (¡no comprendía la web, por ejemplo!), y los mismos se desplegaban y servían de manera centralizada. No existía ni una necesidad, ni una infraestructura, ni una governanza que requiriera que las bases de datos se distribuyeran a través de diversas ubicaciones.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Las primeras bases de datos relacionales de modelo tabular, surgieron en la década de 1970. Es decir, cuando el uso que se le daba a los sistemas computacionales era bastante diferente, y los mismos se desplegaban y servían de manera centralizada&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Pero los tiempos cambiaron y &lt;strong&gt;la necesidad vino determinada por la globalización producto del acceso masivo a los mismos productos, servicios y aplicaciones, por parte de los usuarios de internet a nivel mundial&lt;/strong&gt;. Esta globalización exacerbó problemas ya existentes, pero menos relevantes, como la latencia. &lt;strong&gt;La latencia determina cuánto tiempo pasa desde que se inicia una petición hasta que se recibe una respuesta, en un modelo cliente servidor.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyhdte0q57obdc2q0ndvk.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyhdte0q57obdc2q0ndvk.jpg" alt="Latencia en despliegues"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Antes de que las nubes públicas y sus proveedores entraran en escena, los despliegues se hacían 'en premisas', es decir en las mismas premisas donde las empresas y organizaciones operaban sus negocios o en un centro de datos cercano. (Recordemos que todavía hay un enorme porcentaje de organizaciones que por motivos de seguridad o retraso en la adopción de sistemas en la nube, siguen operando en premisas o como se conoce en inglés 'on-prem(ise)'). Más adelante, los centros de datos que se dedicaban a proveer y mantener infraestructuras y las redes necesarias, fueron creciendo y distribuyéndose. Finalmente, el requerimiento de un mejor rendimiento, menos latencia, y de los controles de privacidad en forma de soberanía de datos por parte de países y regiones (como puede ser GDPR en la Unión Europea), definieron la descentralización y los modernos sistemas de distribución de datos.&lt;/p&gt;

&lt;p&gt;Pero muchas veces, aunque estos sistemas cachean datos en diversas regiones del globo (es decir, guardan una copia para servir más eficientemente a puntos distribuidos lo que se conoce como CDN), siguen teniendo su nodo transaccional en un único punto. &lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Qué es el sharding?
&lt;/h2&gt;

&lt;p&gt;Sharding es simplemente ese proceso de dividir grandes volumenes de datos en partes más pequeñas, que se guardan generalmente en particiones físicas o virtuales diferentes. Cualquier base de datos se puede dividir así, pero es un proceso complicado, que requiere toda una refactorización y reconfiguración de acuerdo a la nueva distribución.&lt;/p&gt;

&lt;p&gt;Partir modelos tabulares de modo que podamos desplegar parte de la base de datos en una región de la nube, por ejemplo, y otra parte en otra región, exige un diseño de sistema y una infraestructura realmente complejos. Particularmente por cómo está diseñado el modelo relacional, para desacoplar datos a los que se accede de manera frecuente, pero deben seguir relativos a otro (u otros) grupos de datos para conformar una entidad. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Partir modelos tabulares de modo que podamos desplegar parte de la misma base de datos en una región de la nube, por ejemplo, y otra parte en otra región, exige un diseño de sistema y una infraestructura, realmente complejos.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxn5bkedp8ov5t9l5a4m9.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxn5bkedp8ov5t9l5a4m9.jpg" alt="Distribuir modelos tabulares implica esfuerzos mayores de diseño"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  El modelo de documento simplifica la distribución de datos
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Sin embargo, el modelo documento propuso que todos los datos a los que se accede juntos, se guardan juntos,&lt;/strong&gt; en un único documento. Y aunque existen muchas excepciones a esa regla, y formas de relacionar documentos en distintas colecciones a través de ciertos patrones de diseño, es muy importante tener esta definición en cuenta, a la hora de diseñar bases de datos de modelo de documento.&lt;/p&gt;

&lt;p&gt;Una de las ventajas es que es mucho más simple 'dividir' bases de datos en conjuntos de datos completamente diferentes, siguiendo una estrategia de &lt;code&gt;particionamiento&lt;/code&gt; si respetamos ese precepto. &lt;/p&gt;

&lt;p&gt;En el caso de MongoDB además, el proceso de sharding es nativo y se puede automatizar, interviniendo en él otros procesos como el enrutado, el auto-balanceo, etc.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sharding si, sharding no
&lt;/h2&gt;

&lt;p&gt;El &lt;code&gt;sharding&lt;/code&gt; de MongoDB no es en lo absoluto un proceso simple. Es un proceso complejo que necesita una estrategia bien meditada para ser exitoso. Una de las preguntas más importantes que debemos hacernos (como con todos los procesos que implican una re-estructuración de la arquitectura, con un coste elevado) es si realmente lo necesitamos.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Es importante tener en cuenta que en Cosmos DB, por ejemplo, el sistema está particionado por defecto, en particiones pequeñas. Hablaremos de esto en el siguiente post.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Para empezar, es importante saber que el &lt;code&gt;sharding&lt;/code&gt; en una base de datos MongoDB se recomienda solamente para volúmenes muy grandes de datos. Pensemos en varios TB's de los mismos. Generalmente el volumen recomendado estará ligado a la infraestructura donde corre el software y su capacidad del hardware, que determina el rendimiento del motor a nivel escaneado, compresión y cacheado. Pero eso es tema para otro blog post. Así que prosigamos.&lt;/p&gt;

&lt;p&gt;Incluso si nuestro volumen de datos comprimido está por encima de los TB's recomendados en ese momento, la primera pregunta que hay que hacerse antes de habilitar &lt;code&gt;sharding&lt;/code&gt;, tendrá que ver con la arquitectura de nuestros datos, y las politicas de retención de los mismos. Es decir...¿realmente necesitamos tener en caliente, todos los datos que guardamos?.&lt;/p&gt;

&lt;h3&gt;
  
  
  Datos fríos y datos calientes
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Una de las definiciones más importantes que tiene que hacer una empresa en el momento en que empieza a brindar un servicio a usuarios a través de una aplicación, es la política de retención de datos.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A nivel estrategia de negocio siempre será más barato, y por ende más ventajoso para nuestra empresa, el definir claramente las expectativas y acuerdos de acceso a los datos por parte de nuestros usuarios. Es decir, imaginemos que somos una &lt;code&gt;start-up&lt;/code&gt; que recabamos datos a los que los usuarios acceden a través de nuestra aplicación o plataforma, podemos definir que los usuarios tendrán acceso inmediato a los datos de menos de 12 meses de edad en la base de datos, y que deben esperar un poco más tiempo para obtener datos más antiguos. Por un poco más de tiempo, me refiero a algunos segundos en vez de nano o milisegundos.&lt;/p&gt;

&lt;p&gt;Ese tipo de términos de uso son generalmente aceptados como normales por los usuarios, y nos permiten mantener datos en caliente por menos tiempo (es decir, en un cluster de acceso inmediato) mientras que los más antiguos de guardan en almacenamiento frío, por ejemplo un &lt;code&gt;data lake&lt;/code&gt; (lago de datos? Nunca lo he escuchado en español, pero eso sería literalmente el nombre!). Los &lt;code&gt;data lakes&lt;/code&gt; son almacenamientos en máquinas menos potentes, y por lo tanto son más baratos y admiten volúmenes enormes de datos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Múltiples clusters como alternativa al sharding
&lt;/h2&gt;

&lt;p&gt;Otra alternativa para volúmenes grandes de datos que deben estar en caliente, de más fácil implementación y mantenimiento particularmente cuando se debe observar la soberanía de datos, es la de desplegar bases de datos a través de diferentes clusters, en vez de recurrir al &lt;code&gt;sharding&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx2ekg2gi744dqyw4497h.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx2ekg2gi744dqyw4497h.jpg" alt="Multiples shards distribuidos"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Qué pasa en nuestra base de datos, cuando la particionamos?
&lt;/h2&gt;

&lt;p&gt;Ahora que ya hemos hablado de volúmenes mínimos de datos, y de políticas de datos que nos permitan mover datos a almacenamientos más baratos, y que ya hemos establecido que el &lt;code&gt;sharding&lt;/code&gt; es un proceso caro a nivel complejidad de la implementación y mantenimiento, hablemos del mecanismo de &lt;code&gt;sharding&lt;/code&gt; en si.&lt;/p&gt;

&lt;p&gt;El &lt;code&gt;sharding&lt;/code&gt; es un proceso que reconfigura al driver para que la aplicación ignore que se está comunicando con múltiples instancias de la base de datos, y ejecuta un balanceo de cargas que mueve datos automáticamente entre las mismas.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;El &lt;code&gt;sharding&lt;/code&gt; es un proceso que reconfigura al driver para que la aplicación ignore que se está comunicando con múltiples instancias de la base de datos, y ejecuta un balanceo de cargas que mueve datos automáticamente entre las mismas, de acuerdo a una estrategia predefinida.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Así como enfatizamos en que la replicación es una copia del mismo conjunto de datos que permite la redundancia de los mismos en varios nodos, es importante recordar que cada &lt;code&gt;shard&lt;/code&gt; o partición, es (si se siguen buenas prácticas) un conjunto de réplicas en si.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Cada &lt;code&gt;shard&lt;/code&gt; o partición, es un conjunto de réplicas en sí. Técnicamente es posible que cada shard sea un nodo único standalone, pero recordemos que eso no es lo recomendado&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;En un momento hablaremos de las estrategias de &lt;code&gt;sharding&lt;/code&gt;, que dependen de su &lt;code&gt;clave de sharding&lt;/code&gt;. La clave de &lt;code&gt;sharding&lt;/code&gt; o &lt;code&gt;sharding key&lt;/code&gt; es básicamente el campo que define cómo se separarán los datos, y cómo se indexarán. Antiguamente, una vez se elegía una clave, no se podía cambiar, pero desde la versión 5.0 de MongoDB se puede cambiar con un proceso de &lt;code&gt;resharding&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Componentes de la arquitectura de &lt;code&gt;sharding&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Una de las razones por las que el &lt;code&gt;sharding&lt;/code&gt; es más caro de mantener, es que requiere varios nodos adicionales al &lt;code&gt;standalone&lt;/code&gt; o a las &lt;code&gt;réplicas&lt;/code&gt; (en el caso de que cada &lt;code&gt;shard&lt;/code&gt; sea un conjunto de réplicas, como se recomienda). &lt;/p&gt;

&lt;p&gt;Vamos a suponer que tenemos 3 &lt;code&gt;shards&lt;/code&gt; de arquitectura PSS. Uno de los 3 &lt;code&gt;shards&lt;/code&gt; va a ser el primario. Además, necesitaremos un nodo adicional que corra el proceso &lt;code&gt;mongos&lt;/code&gt;. También necesitaremos un servidor de configuración, que también es un conjunto de réplicas. ¡Con esta configuración y usando buenas practicas, tenemos nada menos que 13 nodos corriendo! &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr9ni9h65brqwljtyllg4.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr9ni9h65brqwljtyllg4.jpg" alt="arquitectura mongodb sharding"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  El proceso Mongos
&lt;/h2&gt;

&lt;p&gt;Este proceso es un proceso de enrutado (un router) que mantiene una tabla de contenido de la base de datos que dirige las peticiones del cliente hacia el &lt;code&gt;shard&lt;/code&gt; correcto, y actúa como intermediario entre la aplicación y la base de datos particionada. La arquitectura acabará siendo como se ilustra en el diagrama anterior.&lt;/p&gt;

&lt;p&gt;Cuando habilitamos &lt;code&gt;sharding&lt;/code&gt; en una base de datos, para una o varias colecciones, debemos elegir la &lt;code&gt;clave de shard&lt;/code&gt;, que como decíamos, no es más que un campo indexado de la colección en cuestión. Voy a dedicar una entrada de blog a los índices (indexes en la jerga de MongoDB, no sé por qué, pero el plural en este contexto es así 🤷‍♀️). La indexación es uno de los temas más complejos y difíciles de entender, en lo que a MongoDB respecta.&lt;/p&gt;

&lt;h3&gt;
  
  
  Shards
&lt;/h3&gt;

&lt;p&gt;Cuando se inicia el proceso de &lt;code&gt;sharding&lt;/code&gt;, que por cierto es un proceso paulatino y asíncrono que puede tardar días y hasta semanas en completarse (dependiendo del volumen de datos), pero que no interfiere con el funcionamiento de la base de datos (es decir, se puede ejecutar en sistemas en producción, sin problemas), los datos de las colecciones afectadas se irán distribuyendo en forma de chunks del tamaño predeterminado, a través de la cantidad de shards configurada.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Un cluster particionado siempre tiene además un &lt;code&gt;shard primario&lt;/code&gt; que es el que guarda las colecciones que no están sujetas a partición.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Chunks
&lt;/h3&gt;

&lt;p&gt;Durante este proceso, el sistema particionará los datos en &lt;code&gt;chunks&lt;/code&gt; o &lt;code&gt;cachos&lt;/code&gt;(muy gracioso, pero no encuentro mejor traducción!) y los irá distribuyendo y redistribuyendo de manera balanceada, a través de los &lt;code&gt;shards&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Estos chunks deben de tener, por convención, un tamaño mínimo de 64MB. No tiene sentido tener chunks de menos tamaño. Recordar que el tamaño máximo de un documento MongoDB es 16MB. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;El &lt;code&gt;sharding&lt;/code&gt; es un proceso paulatino y asíncrono que puede tardar días y hasta semanas en completarse, dependiendo del volumen de datos, y no interfiere con el funcionamiento de la base de datos; se puede ejecutar en sistemas en producción.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Consultas (queries)
&lt;/h3&gt;

&lt;p&gt;Las consultas que ejecutamos contra un sistema particionado son de dos tipos: &lt;/p&gt;

&lt;p&gt;&lt;code&gt;targeted queries&lt;/code&gt;, vendría a ser como &lt;code&gt;consultas objetivas&lt;/code&gt;, y son las que contienen la clave de &lt;code&gt;sharding&lt;/code&gt;, y que pueden ser dirigidas por &lt;code&gt;mongos&lt;/code&gt; al &lt;code&gt;shard&lt;/code&gt; que contiene los datos relevantes.&lt;/p&gt;

&lt;p&gt;Por otro lados las consultas que no contienen la clave, se deben de mandar a todos los &lt;code&gt;shards&lt;/code&gt; y se conocen como &lt;code&gt;broadcast&lt;/code&gt; o &lt;code&gt;scatter-and-gather&lt;/code&gt;, (algo así como &lt;code&gt;desparramar-reunir&lt;/code&gt;), ya que son consultas que se &lt;code&gt;lanzan&lt;/code&gt; o &lt;code&gt;desparraman&lt;/code&gt; entre todos los &lt;code&gt;shards&lt;/code&gt; para finalmente &lt;code&gt;reunir&lt;/code&gt; los resultados.&lt;/p&gt;

&lt;h2&gt;
  
  
  Habilitando un sistema de &lt;code&gt;sharding&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Mientras que el &lt;code&gt;sharding&lt;/code&gt; se habilita a nivel base de datos es importante entender que el mismo se ejecuta a nivel de colección. Más abajo describo algunos métodos.&lt;/p&gt;

&lt;p&gt;Podemos utilizar la clase &lt;code&gt;ShardingTest&lt;/code&gt; del servidor de MongoDB que instalamos con la versión Community, para crear un cluster de prueba. Es una clase que se usa internamente, para hacer pruebas de &lt;code&gt;sharding&lt;/code&gt;, pero que está expuesta para uso externo. Podemos ver la implementación, &lt;a href="https://github.com/mongodb/mongo/blob/master/src/mongo/shell/shardingtest.js" rel="noopener noreferrer"&gt;aquí&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Nota: Es importante saber que esto está disponible solo para la versión anterior de la herramienta de linea de comandos &lt;code&gt;mongo&lt;/code&gt; y no para &lt;code&gt;mongosh&lt;/code&gt;. Intentaré para el siguiente post encontrar tiempo de cargar los scripts y snippets de compatibilidad para la clase y jstest, pero no prometo nada!)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Lo primero que hacemos es inicializar la consola de mongo&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

mongo --nodb --norc


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;con los parametros --nodb y --norc para no inicializar una base de datos ni la evaluación de JavaScript.&lt;/p&gt;

&lt;p&gt;Luego podemos crear un par de shards de test así&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

testdesharding = ShardingTest({
  name: "TestdeSharding",
  shards: 2,
  chunkSize: 1
});


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Nota: Si esta clase nos da un error de boost relativo a la no existencia de la ruta &lt;code&gt;data/db&lt;/code&gt;, se la podemos pasar al task runner así&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;MongoRunner.datapath = 'mi-ruta/es-tu-ruta/data/path';&lt;/code&gt;&lt;br&gt;
(hay gente que va a entender la referencia y otra que no...jaja)&lt;/p&gt;

&lt;p&gt;Hay muchísimas más opciones de configuración que podemos pasar a la hora de crear nuestro cluster de test, que están descritas a partir de la línea 8 del &lt;a href="https://github.com/mongodb/mongo/blob/master/src/mongo/shell/shardingtest.js" rel="noopener noreferrer"&gt;script&lt;/a&gt;. Entre ellas encontramos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;name (nombre del cluster)&lt;/li&gt;
&lt;li&gt;shards (número de shards)&lt;/li&gt;
&lt;li&gt;rs (al que podemos pasar un objeto de configuración para cada conjunto de replica, como cantidad de nodos y tamaño del oplog)&lt;/li&gt;
&lt;li&gt;mongos (número de mongos que se correrán)&lt;/li&gt;
&lt;li&gt;chunkSize (el tamaño de cada chunk)&lt;/li&gt;
&lt;li&gt;enableBalancer (si habilitamos el load balancer por defecto)&lt;/li&gt;
&lt;li&gt;enableAutoSplit (si habilitamos la auto partición)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;etc&lt;/p&gt;

&lt;p&gt;Cuando ejecutamos esta clase de test, creamos un cluster y se inicializan los procesos necesarios, incluyendo &lt;code&gt;mongos&lt;/code&gt; y los conjuntos de réplica configurados, así como el servidor de configuración. &lt;/p&gt;

&lt;p&gt;Una vez creado el cluster, podemos probar los &lt;a href="https://www.mongodb.com/docs/manual/reference/method/js-sharding/" rel="noopener noreferrer"&gt;métodos de sharding&lt;/a&gt;, que se describen en la documentación oficial del software. También podremos experimentar con las diversas estrategias de &lt;code&gt;sharding&lt;/code&gt;. Por defecto el proceso &lt;code&gt;mongos&lt;/code&gt; corre  en el puerto 20009, pero se puede reconfigurar.&lt;/p&gt;

&lt;p&gt;Para experimentar, abrimos otra ventana o pestaña de la terminal donde podemos crear una base de datos e importar o crear algunos datos, para poder experimentar.&lt;/p&gt;

&lt;p&gt;Esto es solamente para hacer pruebas y aprender. Si fuéramos a habilitar un sistema de &lt;code&gt;sharding&lt;/code&gt; de MongoDB real, deberíamos seguir el proceso que se describe &lt;a href="https://www.mongodb.com/docs/manual/core/sharded-cluster-components/" rel="noopener noreferrer"&gt;aquí&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Básicamente deberíamos inicializar todos los nodos por separados, &lt;strong&gt;primero que nada un conjunto de réplicas para el servidor de configuración&lt;/strong&gt;, que se inicializa con el parámetro &lt;code&gt;--configsvr&lt;/code&gt; (siempre antes que el proceso &lt;code&gt;mongos&lt;/code&gt;). Otro nodo para &lt;code&gt;mongos&lt;/code&gt; que se inicializa con el comando &lt;code&gt;mongos&lt;/code&gt; y el parámetro &lt;code&gt;--configdb&lt;/code&gt; (al que se pasan los datos de los servidores de configuración) Finalmente conectamos al que será el shard primario, asígnandole el rol a cada miembro con la opción &lt;code&gt;--shardsvr&lt;/code&gt;, lo que deberemos repetir con cuantos nodos decidamos tener para los conjuntos de réplicas que conformaran cada &lt;code&gt;shard&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Una vez tenemos todos los nodos activos, se pueden agregar al cluster de &lt;code&gt;sharding&lt;/code&gt; manualmente con el comando&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sh.addShard(//réplica set path + puerto);&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;al que pasamos cada réplica set individualmente.&lt;/p&gt;

&lt;h3&gt;
  
  
  Habilitar el proceso de distribución de datos
&lt;/h3&gt;

&lt;p&gt;Una vez tenemos todo configurado, debemos habilitar manualmente el &lt;code&gt;sharding&lt;/code&gt; para la base de datos. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;sh.enableSharding("nombre_base_de_datos");&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;y seguidamente, particionamos las colecciones que decidamos&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sh.shardCollection("nombre_base_de_datos.nombre_colección", {"clave_de_partición": 1})&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;donde &lt;code&gt;clave_de_partición&lt;/code&gt; es la clave elegida, o sea un campo &lt;strong&gt;indexado&lt;/strong&gt; de la colección.&lt;/p&gt;

&lt;h2&gt;
  
  
  Estrategias de &lt;code&gt;sharding&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Como comentaba anteriormente, la forma más eficiente de distribuir nuestros datos a través de múltiples &lt;code&gt;shards&lt;/code&gt;, va a determinarse por medio de una estrategia de partición. &lt;/p&gt;

&lt;h3&gt;
  
  
  La estrategia de hash
&lt;/h3&gt;

&lt;p&gt;La estrategia de hashing es la más eficiente a la hora de distribuir datos de manera balanceada. Los datos se distribuyen de manera aleatoria, asegurándose que hay el mismo volumen de datos en cada partición. Es la estrategia ideal cuando la intención es liberar espacio de disco y asegurarnos que los datos se distribuyen de manera equitativa.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1o4ra61dgq0tjbaeefw8.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1o4ra61dgq0tjbaeefw8.jpg" alt="estrategia de sharding: hash"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  La estrategia de rango
&lt;/h3&gt;

&lt;p&gt;Esta estrategia es la más eficiente para distribuir datos de acuerdo a ciertos rangos. Por ejemplo, si estamos distribuyendo usuarios, los podemos distribuir en el rango de la A a la I, de la J a la Q y de la R a la Z, de acuerdo con la primera letra de su apellido.&lt;/p&gt;

&lt;p&gt;Una desventaja de la distribución por rango, es la baja cardinalidad (hablaremos de cardinalidad cuando hablemos de indices) pero básicamente, como habrán muchos apellidos con ciertas letras, y muy pocos con otras, será difícil garantizar el buen balance.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7l5tzylnw9mmko79st6o.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7l5tzylnw9mmko79st6o.jpg" alt="estrategia sharding: rangos"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  La estrategia de zonas
&lt;/h3&gt;

&lt;p&gt;Finalmente, podemos segmentar los datos ya distribuidos, por zonas. Las zonas pueden venir determinadas por el data &lt;em&gt;locale&lt;/em&gt;, lo que permitiría distribuir geográficamente, o por otra variable. En el caso de usar la estrategia para distribuir geográficamente,   un &lt;code&gt;shard&lt;/code&gt; que se encuentre desplegado en cierta región del mundo guardará los datos de los usuarios que pertenecen a esa región. Esta estrategia nos ayuda a cumplir con políticas de protección de datos, por ejemplo, pero al igual que la estrategia de rangos, puede incurrir en un desequilibrio de las particiones.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwx74kxp5vyairn2fhpod.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwx74kxp5vyairn2fhpod.jpg" alt="estrategia de sharding por zonas"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  En el próximo post
&lt;/h2&gt;

&lt;p&gt;La próxima entrada será más corta e intentaré explicar sobre todo,&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sharding en Producción&lt;/li&gt;
&lt;li&gt;Particionamiento en CosmosDB y como difiere con MongoDB&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A prestar atención!&lt;/p&gt;

</description>
      <category>basesdedatos</category>
      <category>mongodb</category>
      <category>sharding</category>
      <category>nosql</category>
    </item>
    <item>
      <title>Bases de datos y el modelo de documento</title>
      <dc:creator>Natalia Venditto</dc:creator>
      <pubDate>Mon, 25 Apr 2022 19:45:05 +0000</pubDate>
      <link>https://dev.to/anfibiacreativa/bases-de-datos-y-el-modelo-de-documento-o54</link>
      <guid>https://dev.to/anfibiacreativa/bases-de-datos-y-el-modelo-de-documento-o54</guid>
      <description>&lt;p&gt;No sé si un blog en español va a funcionar en esta plataforma...pero, por qué no? En diciembre del año pasado dejé mi puesto como arquitecta de soluciones con MongoDB, para irme a Microsoft, a trabajar en experiencia y herramientas de desarrollo, para desarrolladores JavaScript en Azure. Una de las cosas que me apenó bastante, era que me había comprometido a escribir sobre MongoDB en español, y no había encontrado tiempo. Sé que suena como una excusa terrible, pero realmente estoy más ocupada de lo que me gusta admitir.&lt;/p&gt;

&lt;p&gt;Sin embargo, no quería dejar de hacer esto. Sobre todo mientras la información está fresca en mi cabeza. ¿Por qué? Bueno, realmente soy una fan del modelo documento y ahora mismo, uso la API de MongoDB con CosmosDB, constantemente. Inicialmente iba a hacer videos, pero llevan una cantidad de tiempo increíble, y era realmente inviable.&lt;/p&gt;

&lt;p&gt;Advierto que la información es bastante y seguramente no va a caber toda en un post único. Intentaré no demorar mucho entre post y post, &lt;em&gt;pero no puedo prometer nada&lt;/em&gt;. &lt;/p&gt;




&lt;h2&gt;
  
  
  Empecemos por el modelo.
&lt;/h2&gt;

&lt;p&gt;MongoDB como base de datos, fue concebida realmente para solucionar un problema que sus creadores venían experimentando ellos mismos, y que era obvio era general a toda la industria. Las bases de datos SQL eran cada vez menos compatibles con nuevos casos de uso, eran (y son) difíciles de escalar, necesitan capas intermedias entre la base de datos y la de la aplicación (conocidas como ORM u Object Relational Mapping) y además, son poco idiomáticas. Con esto quiero decir que cuando escribimos aplicaciones, generalmente creamos entidades que se describen como objetos con ciertas propiedades o atributos, métodos, etc. Representar esos objetos y la relación de los mismos con otros objetos, mediante tablas, no es precisamente fácil para aplicaciones complejas. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;...las bases de datos SQL eran cada vez menos compatibles con nuevos casos de uso, son difíciles de escalar, y necesitan capas intermedias entre la base de datos y la de la aplicación, conocidas como Object Relational Mapping&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Y no sólo eso. Las aplicaciones modernas generalmente hacen peticiones a través de APIs (mayoritariamente REST) que típicamente devuelven los datos en formato JSON. JSON es verdaderamente el estándar abierto de intercambio de información, más utilizado en redes. Así que...¿por qué no crear un tipo de base de datos que utilizara el mismo formato? Pues los creadores se abocaron a ello, y así nació MongoDB (que es una abreviación de la palabra en inglés 'humongous', que quiere decir algo así como 'enorme', porque realmente MongoDB siempre estuvo pensada para alojar grandes volúmenes de datos y para poder escalar de manera simple).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;...MongoDB siempre estuvo pensada para poder escalar de manera simple y alojar grandes volúmenes de datos&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Pero, como casi todas las soluciones, habían algunos problemas. A pesar de que JSON era idiomático y fácil de entender para todos los desarrolladores, y de que los documentos eran fáciles de crear y modificar, se podían anidar subdocumentos para establecer relaciones, (hablaremos más de relaciones y consistencia cuando hablemos de patrones de diseño), y otras ventajas a nivel flexibilidad, JSON no ofrece demasiadas opciones en lo que se refiere a tipos de datos. Por lo tanto, si bien a nivel humano es fácil de escribir y entender, no es eficiente a la hora de guardar los datos en sí. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;JSON es rápido a la hora de leerse y su tamaño es bastante pequeño, pero no ofrece demasiadas opciones en lo que se refiere a tipos de datos. Por lo tanto, si bien a nivel humano es fácil de escribir y entender, no es eficiente a la hora de compilar o guardar los datos en sí&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  BSON como estándar abierto, para guardar otros tipos de datos
&lt;/h2&gt;

&lt;p&gt;Y así se creó BSON (Binary encoded JavaScript Object Notation), como una manera de codificar JSON, para extender los tipos nativos de JSON: además de tener cadena (string), boleano (boolean), numérico (number), arreglo (array), objeto (object) y null, BSON ofrece tipos binarios, decimales de 128 bits, fecha (date), id de objeto (objectId), etc.&lt;/p&gt;

&lt;p&gt;BSON puede compararse con otros Protobuffs, o protocolos de buffer, que se usan para serializar y deserializar datos* estructurados, pero a diferencia de los mismos, no exige un &lt;em&gt;schema&lt;/em&gt;, lo que se traduce en una mayor flexibilidad a la hora de guardar datos.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(*) El proceso de serialización es el de codificar un objeto (y el de deserialización, el de decodificarlo), para que se encuentre en un formato más adecuado ya sea para su transmisión a través de una red, lectura por parte de un sistema informático o un humano, o su almacenaje.&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;La diferencia más significativa es que BSON tiene más tipos de datos, y es más rápido de escribir y compilar en la base de datos, mientras que JSON es más fácil de leer para humanos y computadoras, además de tener un tamaño más pequeño&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Podemos ir a la documentación de MongoDB, para obtener una &lt;a href="https://www.mongodb.com/basics/bson#:~:text=BSON%20is%20a%20binary%20encoded,it%20supports%20fewer%20data%20types" rel="noopener noreferrer"&gt;comparativa entre los dos estándares&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Comparativa (o contraste) entre una base de datos SQL o relacional, y una base de datos de modelo de documento
&lt;/h2&gt;

&lt;p&gt;A pesar de las diferencias, una base de datos es...bueno, eso. Es un software que opera sobre un sistema informático, para almacenar datos. Y todas las bases de datos tienen, a pesar de sus diferencias, muchas cosas en común. Por ejemplo, si queremos comparar MongoDB con una base de datos relacional clásica, el mapeo de terminología y conceptos, sería el siguiente:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Modelo Relacional&lt;/th&gt;
&lt;th&gt;Base de datos&lt;/th&gt;
&lt;th&gt;Tabla&lt;/th&gt;
&lt;th&gt;Fila&lt;/th&gt;
&lt;th&gt;Columna&lt;/th&gt;
&lt;th&gt;Clave&lt;/th&gt;
&lt;th&gt;Valor&lt;/th&gt;
&lt;th&gt;Vista&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Modelo de Documento&lt;/td&gt;
&lt;td&gt;Base de datos&lt;/td&gt;
&lt;td&gt;Colección&lt;/td&gt;
&lt;td&gt;Documento&lt;/td&gt;
&lt;td&gt;Campo&lt;/td&gt;
&lt;td&gt;Campo&lt;/td&gt;
&lt;td&gt;Valor&lt;/td&gt;
&lt;td&gt;Vista&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Vamos a ver más equivalencias, a medida que progresemos. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0b16l4d5g8t0rzjscaod.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0b16l4d5g8t0rzjscaod.jpg" alt="Modelo documento a relacional"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Anatomía de un documento
&lt;/h2&gt;

&lt;p&gt;Ahora que entendemos un poco más sobre datos, vamos a enfocarnos en los documentos en sí. Un documento del modelo documento (valga la redundancia), tiene estás características en su formato JSON.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{ 
   "field1" : "valor (string)",
   "field2" : "valor (boolean)",
   "field3": [valor(number), valor(number), valor(number)],
   "field4": { "valor": "string" } // (object) -&amp;gt; también conocido como subdocumento, si tiene su propio identificador
   //etc
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Donde podemos decir que el nombre del campo se corresponde a una clave o key en una base de datos relacional, y el valor corresponde al valor, que tiene un tipo. Cuando necesitamos convertir un valor a un tipo no soportado por JSON, pero soportado por BSON, generalmente efectuamos un "casting", ya sea a nivel driver (o aplicación) o durante el formateo del documento. Por ejemplo, todos los documentos guardados en una base de datos MongoDB, necesitan un identificador único, del tipo ObjectId. Al deserializar, la base de datos mostrará ese valor como un objeto anidado con esta estructura:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
   "_id": {"$oid":"61bf540215c38f38aff7f352"}
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cuando creamos un documento en MongoDB, sin guardar ningún tipo de datos en él, por ejemplo con el comando &lt;/p&gt;

&lt;p&gt;&lt;code&gt;db.[collection].insertOne({})&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;la base de datos le asignará un campo "_id", con un valor aleatorio y único, de manera automática.&lt;/p&gt;

&lt;p&gt;Ese comando es parte de las operaciones CRUD de la API de MongoDB. No importa que ahora no entiendas lo que hace ese comando. Hablaremos de las operaciones CRUD, más adelante.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bases de datos distribuidas y la consistencia eventual
&lt;/h2&gt;

&lt;p&gt;Además de ser diseñada para grandes cantidades de datos, (y quizás por esa misma razón) MongoDB fue diseñada como una base de datos distribuida. Es decir, a diferencia de las bases de datos tabulares, que son difíciles de distribuir de manera optimizada, MongoDB fue creada específicamente con la distribución en mente. &lt;/p&gt;

&lt;p&gt;Para entender cómo funciona MongoDB a nivel distribución y consistencia, hay que tener en mente el Teorema de CAP. En resumen, este teorema propone que cualquier almacenamiento de datos distribuido solo puede ofrecer dos de las siguientes tres garantías:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Consistencia&lt;/strong&gt; - cada petición va a obtener la escritura más reciente o un error.&lt;br&gt;
&lt;strong&gt;Disponibilidad&lt;/strong&gt; - cada petición va a obtener una respuesta y nunca un error, pero sin la garantía de que esta contiene la escritura más reciente&lt;br&gt;
&lt;strong&gt;Tolerancia a la partición&lt;/strong&gt; - El sistema va a continuar operando a pesar de que algunos mensajes entre nodos se pierdan o se descarten. En caso de fallos el sistema debe decidir entre disminuir la disponibilidad (cancelando la operación) o mantener la disponibilidad, sacrificando así la consistencia.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe0korwf6i3sn6gwvcdg1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe0korwf6i3sn6gwvcdg1.png" alt="Teorema de CAP - Consistencia Disponibilidad - Tolerancia a la particion"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;MongoDB es un sistema particionado, con lo cual continúa operando, y por defecto da más prioridad a la consistencia que a la disponibilidad, ya que todas las lecturas y escrituras se realizan por defecto al nodo primario. Sin embargo esto se puede reconfigurar cambiando lo que se conoce como &lt;code&gt;write/read concerns&lt;/code&gt; volviéndose así la base de datos eventualmente consistente.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  MongoDB y la alta disponibilidad
&lt;/h2&gt;

&lt;p&gt;La alta disponibilidad es realmente necesaria para satisfacer la mayoría de casos de uso de las aplicaciones modernas, sobre todo en un mundo donde el alto rendimiento y la inmediatez son lo mínimo que un usuario medio espera.&lt;/p&gt;

&lt;p&gt;¿Y cómo resuelve MongoDB este requisito, a pesar de estar diseñada para distribuir nodos a través de diferentes centros de datos e incluso proveedores de nube? Bueno, vamos a empezar por un ejemplo donde NO estamos distribuyendo un sistema, sino que lo inicializamos localmente.&lt;/p&gt;

&lt;p&gt;Para eso, vamos a instalar MongoDB en nuestros ordenadores. Lamentablemente la documentación de MongoDB está solo en inglés y no tengo capacidad para traducir las instrucciones de instalación para cada sistema operativo, pero les dirijo a la página:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.mongodb.com/docs/manual/administration/install-community/" rel="noopener noreferrer"&gt;https://www.mongodb.com/docs/manual/administration/install-community/&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.mongodb.com/products/shell" rel="noopener noreferrer"&gt;https://www.mongodb.com/products/shell&lt;/a&gt;&lt;br&gt;
&lt;a href="https://docs.mongodb.com/database-tools/?_ga=2.100697729.1601885193.1650825625-818649307.1634902066" rel="noopener noreferrer"&gt;https://docs.mongodb.com/database-tools/?_ga=2.100697729.1601885193.1650825625-818649307.1634902066&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Lo que vamos a estar instalando es la versión community, o gratuita, la herramienta de línea de comandos y las utilidades.&lt;/p&gt;

&lt;p&gt;Yo voy a utilizar además la extensión oficial de &lt;a href="https://code.visualstudio.com/docs/azure/mongodb" rel="noopener noreferrer"&gt;MongoDB para VS Code&lt;/a&gt;, para cualquier operación sobre las bases de datos y para trabajar con documentos.&lt;/p&gt;
&lt;h3&gt;
  
  
  Trabajando con la terminal (Mongo Shell)
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Como ya mencioné antes, no voy a explicar cómo instalar MongoDB. Aunque la documentación oficial está en inglés solamente, hay bastante información en la internet al respecto como para que lo puedan lograr sin problemas. Sin embargo, si por alguna razón encuentran problemas, por favor comenten abajo. Seguro que alguien de la comunidad les ayuda.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Cuando instalamos MongoDB localmente, y luego de configurarla, lo que estamos instalando es el servidor que va a correr el proceso &lt;code&gt;mongod&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Si ya saben lo que es un proceso y especialmente un proceso daemon, se pueden saltar esta parte. Esto es para quienes no lo tienen tan claro.&lt;/p&gt;
&lt;h3&gt;
  
  
  El proceso mongod
&lt;/h3&gt;

&lt;p&gt;MongoDB corre varios procesos y uno de ellos es &lt;code&gt;mongod&lt;/code&gt;, el proceso daemon primario del servidor, que se encarga de todas las peticiones, el manejo y procesamiento de datos, el acceso, además de -como todo daemon- correr operaciones en una capa profunda de fondo. Es una buena práctica denominar a los procesos daemon con una d al final, que facilita su identificación como tal. &lt;/p&gt;

&lt;p&gt;Cuando ejecutamos &lt;code&gt;mongod&lt;/code&gt; en la Mongo Shell, incializamos el proceso con los valores por defecto, es decir el puerto será &lt;code&gt;27017&lt;/code&gt; los datos se almacenarán en &lt;code&gt;/data/db&lt;/code&gt;. Estos valores por defecto (así como todos los demás) son reconfigurables. Por ejemplo, si queremos inicializar el servidor en otro puerto TCP y guardar los datos en otra ubicación, podemos ejecutar &lt;code&gt;mongod&lt;/code&gt; con las siguientes opciones &lt;/p&gt;

&lt;p&gt;&lt;code&gt;mongod --dbpath /mi/ruta/elegida/ --port 28001&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;El proceso se puede parar en cualquier momento, como cualquier otro proceso, típicamente con &lt;code&gt;ctrl+C&lt;/code&gt; o &lt;code&gt;mongod --shutdown&lt;/code&gt;. Hay métodos adicionales en otros contextos, que exploraremos más delante.&lt;/p&gt;
&lt;h3&gt;
  
  
  MongoDB standalone o nodo único
&lt;/h3&gt;

&lt;p&gt;Cuando nosotros inicializamos &lt;code&gt;mongod&lt;/code&gt; como proceso, estamos inicializando un proceso, es decir, un nodo único. Este nodo es un nodo primario, con todas las capacidades del nodo primario de un conjunto de réplicas, excepto, la de mudarse a otro nodo, en el caso de un fallo de sistema. &lt;/p&gt;

&lt;p&gt;Esto lo podemos verificar, ejecutando &lt;code&gt;rs.status()&lt;/code&gt; en la terminal. Cuando lo hacemos, obtendremos esta información, que básicamente nos dice que no estamos ejecutando un sistema de conjunto de réplicas.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv5rygv5r9k0ra1uouooi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv5rygv5r9k0ra1uouooi.png" alt="ejecutando rs.status() en la terminal Mongo Shell"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No te preocupes si no has entendido nada. Lo explicaremos. Antes de describir el proceso de instalación y lo que es &lt;code&gt;mongod&lt;/code&gt;, estábamos hablando de alta disponibilidad. Alta disponibilidad, en lo que refiere a sistemas en la nube, se refiere a la capacidad de un sistema de recuperarse ante un fallo, eliminando los puntos potenciales de fallo único. Y para eso, hay que implementar lo que se conoce como redundancia. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Alta disponibilidad, en lo que refiere a sistemas en la nube, se refiere a la capacidad de un sistema de recuperarse ante un fallo, eliminando los puntos potenciales de fallo único, a través de la redundancia.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  Redundancia y replicación
&lt;/h3&gt;

&lt;p&gt;La redundancia implica tener varias copias de un sistema, en un estado idéntico, de manera que siempre exista una copia disponible. En MongoDB, eso se logra a través del sistema de replicación y los conjuntos de réplicas. &lt;/p&gt;

&lt;p&gt;Si bien cuando por defecto inicializamos un proceso &lt;code&gt;mongod&lt;/code&gt;, estamos inicializando un nodo único y primario (es decir un nodo único que recibe todas las lecturas, efectúa todas las escrituras, y todos los procesos alternativos), las buenas prácticas con MongoDB, especialmente cuando pensamos en sistemas distribuidos geográficamente y a través de varios centros de datos, exigen que optemos por una arquitectura -como mínimo- &lt;code&gt;PSS&lt;/code&gt;, que se entiende como &lt;strong&gt;Primary, Secondary, Secondary&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Esta arquitectura describe una instalación de MongoDB, donde encontramos un nodo Primario, que por defecto recibe todas las lecturas, y efectúa todas las escrituras, y las replica a dos nodos Secundarios, que van a tener una copia exacta del primario. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Es decir, no hay que confundir replicación con particionamiento de datos.&lt;/strong&gt; La replicación es el sistema fundamental que soporta la alta disponibilidad, mientras que el particionamiento de datos (tener diferentes sets or conjuntos de datos distribuidos entre diferentes máquinas -ya sean físicas o virtuales, y lo que en MongoDB (y otros sistemas) se conoce como &lt;code&gt;sharding&lt;/code&gt;, son dos conceptos con aplicaciones y requerimientos diferentes). &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;El requerimiento de &lt;code&gt;Alta Disponibilidad&lt;/code&gt; se satisface en MongoDB con la &lt;code&gt;Replicación&lt;/code&gt;, que es igual a redundancia, o a tener copias idénticas de un conjunto de datos único, en un conjunto de varios nodos.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Las arquitecturas de los conjuntos de réplica, admiten desde 3 hasta 50 nodos, con una recomendación de al menos 3, 5 o 7 (dependiendo del volumen y del tipo de distribución), donde un máximo de 7 nodos participarán del proceso de recuperación a través de una elección del nodo primario, en caso de que este falle.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp9obnjjteq7uzx4ptcko.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp9obnjjteq7uzx4ptcko.jpg" alt="Representación de un conjunto de réplicas de MongoDB"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  El proceso de replicación
&lt;/h2&gt;

&lt;p&gt;El proceso de replicación es un proceso asíncrono, en el que los nodos secundarios replican los datos del primario. Existe una sincronización inicial, donde el primario vuelca todos sus datos a los sencundarios. Posteriormente la replicación continúa en un proceso mediante el cual los secundarios van leyendo y reescribiendo en su propio oplog el oplog del primario, y luego efectuando los cambios en disco.&lt;/p&gt;

&lt;p&gt;Cada vez que (y solamente cuando! Pregunta de examen!) se modifican datos, el primario escribe una entrada en su oplog, que luego se copia al oplog de cada secundario para que este pueda sincronizarse, siempre y cuando el secundario no sea del subtipo árbitro.&lt;/p&gt;
&lt;h4&gt;
  
  
  Subtipos de secundarios
&lt;/h4&gt;

&lt;p&gt;Existen subtipos de secundarios. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;secundario de prioridad != 0&lt;/strong&gt; - No es propiamente un subtipo, pero es el por defecto. La prioridad establece qué tan probable sea que este secundario se convierta en nuevo primario, en el evento de un fallo del primario.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;secundario de prioridad 0&lt;/strong&gt; -  Cuando creamos un secundario y le damos una prioridad diferente de 0, este guarda datos y puede recibir peticiones de lectura, pero nunca podrá ser elegido nuevo primario.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;secundario árbitro (arbiter)&lt;/strong&gt; - este secundario no puede escribir datos ni recibe peticiones de lectura, ni tampoco ser primario, solamente se usa para desempatar la votación en el caso de elecciones.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;secundario escondido (hidden)&lt;/strong&gt; - este secundario está escondido a la aplicación. mantiene una copia del primario y puede votar, pero no puede volverse primario. Se suele usar para workloads o tareas específicas, como procesamiento de análisis de datos. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;secundario con retraso (delayed)&lt;/strong&gt; - este secundario se debe mantener escondido y con prioridad 0, para que no se vuelva un primario, ya que es un secundario que mantiene una sincronización con un cierto tiempo de retraso con respecto del primario. Se suele usar como estrategia de respaldo.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Fallo del primario y elecciones
&lt;/h2&gt;

&lt;p&gt;Hemos dicho que una arquitectura MongoDB que sigue buenas prácticas, va a ser al menos PSS, es decir va a contar con 3 nodos. Pero ahora que conocemos los subtipos, tenemos que tener en cuenta que cuando decimos 3 nodos, nos referimos a 3 nodos con la capacidad de votar y ser elegidos primarios. Hemos dicho que podemos tener hasta 50 nodos, y que cuántos decidamos tener, va a depender de nuestros requerimientos.  &lt;strong&gt;Otra vez, recordar que esos 50 nodos tienen todos exactamente la misma copia de los datos.&lt;/strong&gt; Aunque puede ser que la latencia entre nodos afecte la replicación, en nanosegundos, milisegundos, segundos, o incluso minutos.&lt;/p&gt;

&lt;p&gt;Sin embargo, lo habitual es tener 3, 5 o 7 nodos (que votan). La cantidad de nodos que votan, siempre tiene que ser impar, con un máximo de 7.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Tenemos que tener en cuenta que cuando decimos 3 nodos, nos referimos a 3 nodos con la capacidad de votar y con la capacidad de convertirse en primarios. La cantidad de nodos que votan, debe ser siempre impar, con un máximo de 7&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;¿Y por qué tiene que ser impar? Para prevenir empates si ocurre una elección.&lt;/p&gt;
&lt;h4&gt;
  
  
  El procesos de elección y la conmutación automática del primario
&lt;/h4&gt;

&lt;p&gt;En el dibujo de arriba vemos unos corazoncitos. Estos representan un latido o &lt;code&gt;heartbeat&lt;/code&gt;, que es el proceso que identifica el estado de cada nodo, en todo momento. La frecuencia es configurable y lo que ocurre en el caso de no detectar un latido es lo siguiente:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;si el primario no detecta latidos de uno de los secundarios, de modo que no se pueda garantizar la mayoría, se convertirá automáticamente en secundario.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;si un secundario no detecta el latido del primario, se auto-nominará primario. En ese momento, cualquier otro secundario votante de la réplica intentará conectar con el primario, para verificar que el secundario que se intenta promover no ha dejado de percibir latidos por un problema de conexión o de red. &lt;br&gt;
Si este secundario comprueba que el primario realmente ha caído, entonces empezará un proceso de verificación del estado del secundario que se quiere promover, para validar su estado tanto de salud como de versión de datos, con respecto al oplog del primario que falla.&lt;br&gt;
Una vez han terminado las comprobaciones, el secundario que se ha promovido, es votado y pasa a ser el primario, mientras que el primario que ha fallado, se vuelve secundario y comienza su proceso de auto-reparación.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Todo este proceso dura unos 4 segundos, en condiciones óptimas.&lt;/p&gt;
&lt;h4&gt;
  
  
  Evitar la perdida de escrituras durante una conmutación automática
&lt;/h4&gt;

&lt;p&gt;Para evitar la pérdida de datos, en el momento de una conmutación, debemos haber habilitado los reintentos de escritura a nivel aplicación o driver, con la opción&lt;/p&gt;

&lt;p&gt;&lt;code&gt;retryWrites=true&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Hay que tener en cuenta que &lt;strong&gt;los reintentos de escritura no son posibles para los &lt;code&gt;concerns&lt;/code&gt; de escritura equivalentes a 0, ni a nivel individual durante una transacción&lt;/strong&gt; (hablaremos de transacciones cuando hablemos de soporte ACID), ni en los sistema de un nodo (standalone).&lt;/p&gt;
&lt;h3&gt;
  
  
  Más sobre el Oplog
&lt;/h3&gt;

&lt;p&gt;Hemos hablado de cómo los nodos de una réplica se sincronizan a través de la copia de operaciones que modifican los datos, que se registran en el oplog del primario, se copian a los oplogs de los secundarios, y finalmente se ejecutan a nivel de disco. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fabmxm4i1322ydaxprmdk.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fabmxm4i1322ydaxprmdk.jpg" alt="MongoDB Oplog dinamica"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;El oplog es una colección especial y capada (es decir, tiene un límite de bytes disponible) que define lo que se conoce como la ventana del oplog o retención de datos. Solo las operaciones que están dentro de la ventana son recuperables. &lt;/p&gt;

&lt;p&gt;Para decidir el tamaño del oplog y de la ventana del oplog, hay que evaluar la intensidad y cantidad de operaciones que modifican el set de datos (inserts, updates, etc), en un determinado periodo de tiempo. El oplog se puede configurar por tamaño en bytes (generalmente MBs o GBs) o en horas. Para la configuración en bytes, se suele reservar 5% del espacio en disco para el oplog.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Para decidir el tamaño del oplog y de la ventana del oplog, hay que evaluar la intensidad y cantidad de operaciones que modifican el set de datos (inserts, updates, deletes, etc), en un determinado periodo de tiempo.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Las operaciones guardadas en el oplog, serán removidas siempre y cuando el oplog esté lleno o haya superado el tiempo ventana, &lt;code&gt;first in, first out&lt;/code&gt;.&lt;/p&gt;
&lt;h4&gt;
  
  
  Write concerns (materia de escrituras)
&lt;/h4&gt;

&lt;p&gt;La verificación de escrituras de un conjunto de réplicas, se determina por su definición de write concern.&lt;/p&gt;

&lt;p&gt;Una configuración igual a &lt;code&gt;w: "majority"&lt;/code&gt;, establece que el reconocimiento de las escrituras, se debe haber propagado a una mayoría calculada en base al total de nodos que guardan datos y son votantes, antes de ser efectivas.&lt;/p&gt;

&lt;p&gt;Si &lt;code&gt;w: 1&lt;/code&gt;, entonces el reconocimiento del nodo primario es suficiente, para que la escritura sea efectiva. Un concern diferente de &lt;code&gt;w: 1&lt;/code&gt;, conlleva degradación de rendimiento, pero aumenta la consistencia. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Un concern diferente de &lt;code&gt;w: 1&lt;/code&gt;, conlleva degradación de rendimiento, pero aumenta la consistencia.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  Crear y configuar un set de réplicas con la terminal
&lt;/h3&gt;

&lt;p&gt;Lo primero que vamos a hacer es crear cada nodo del set de réplicas, de manera independiente.&lt;/p&gt;

&lt;p&gt;Creamos tres nodos con la siguiente configuración&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mongod --replSet nataliaRS --logpath "rsnode1.log" --dbpath rsnode1 --port 27017
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mongod --replSet nataliaRS --logpath "rsnode2.log" --dbpath rsnode2 --port 27018
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mongod --replSet nataliaRS --logpath "rsnode3.log" --dbpath rsnode3 --port 27019
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Es decir, inicializamos tres procesos &lt;code&gt;mongod&lt;/code&gt;, pasando la opción &lt;code&gt;--replSet&lt;/code&gt; a la que en mi caso doy el valor &lt;code&gt;nataliaRS&lt;/code&gt; que será el nombre del conjunto, le asignamos una ruta para el log y otra para los datos (ojo! que tiene que existir!), y a cada una un puerto.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwhpsq9hnoap0hmtdbr62.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwhpsq9hnoap0hmtdbr62.png" alt="Creando mongod primario"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fehvgbnpoajg3t8fgtl5w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fehvgbnpoajg3t8fgtl5w.png" alt="creando mongod secundario 1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn41ad8h4w98wapnm4vvl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn41ad8h4w98wapnm4vvl.png" alt="creando mongod secundario 2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Luego verificamos que los tres nodos están corriendo su proceso&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwjncufr4aoi246nkh9so.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwjncufr4aoi246nkh9so.png" alt="Se verifica que los tres nodos estan corriendo el proceso mongod"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Y ahora describimos la configuración con la que vamos a inicializar el conjunto de réplicas. &lt;/p&gt;

&lt;p&gt;Primero inicializamos el REPL de la línea de comandos con el comando 'mongo'. Y luego creamos un objeto &lt;code&gt;conf&lt;/code&gt; de la siguiente manera:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;config = { 
  _id: "nataliaRS",
  members: [
     {_id: 0, host: "localhost:27017"},
     {_id: 1, host: "localhost:27018"},
     {_id: 2, host: "localhost:27019"} 
  ]
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcmge9geralauuk8wsbe7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcmge9geralauuk8wsbe7.png" alt="Configurando el réplica set en el REPL"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Este objeto se lo pasaremos luego al método de replicación &lt;code&gt;rs.initiate()&lt;/code&gt; del la API de esta manera.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rs.initiate(config);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvopr09tawe5z7l79thyj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvopr09tawe5z7l79thyj.png" alt="Inicializando un conjunto de réplicas"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Si el objeto de respuesta tiene un valor &lt;code&gt;1&lt;/code&gt; para el campo &lt;code&gt;ok&lt;/code&gt;, podemos asumir que el conjunto de réplicas se ha creado correctamente. También podemos ejecutar &lt;code&gt;rs.status()&lt;/code&gt; para obtener información sobre el estado del conjunto y sus miembros. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frf9tf3blirvk9bir85v1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frf9tf3blirvk9bir85v1.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Se pueden agregar posteriormente más miembros al conjunto, usando&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rs.add(server)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(donde server tiene que ser un proceso &lt;code&gt;mongod&lt;/code&gt;)&lt;/p&gt;

&lt;p&gt;Si necesitamos reconfigurar la réplica y sus miembros, podemos hacerlo de esta manera. Supongamos que queremos cambiar la prioridad del nodo secundario de &lt;code&gt;_id = 1&lt;/code&gt;, que sabemos que está en el ínidice 1 del array &lt;code&gt;members&lt;/code&gt;: lo podemos hacer especificando el _id o de esta manera.&lt;/p&gt;

&lt;p&gt;Primero asignamos la configuración actual a una variable, en este caso la llamaremos &lt;code&gt;cfg&lt;/code&gt;, que es una convención en la documentación.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cfg = rs.conf();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Y luego procedemos a reasignar el valor&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cfg.members[1].priority = 3;
rs.reconfig(cfg);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1bokbqzycwt1rltaq2hf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1bokbqzycwt1rltaq2hf.png" alt="Asignando el valor de la config del conjunto de réplica a una variable en el REPL"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frk53v4liitveyd7oieqv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frk53v4liitveyd7oieqv.png" alt="Reconfigurando un miembro del conjunto de replicas"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Podemos ver que el conjunto de réplicas funciona correctamente, y crear una base de datos, una colección y un documento que después de la sincronización, serán accesibles desde cualquiera de los nodos de la réplica, que sean de escritura. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwl23i6h6xg6pjzw2j0iw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwl23i6h6xg6pjzw2j0iw.png" alt="Creando un objeto desde el REPL"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fthhdux8ylwa1qqqixldt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fthhdux8ylwa1qqqixldt.png" alt="Conectando al conjunto de réplicas desde la extensión de VSCode"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Podemos ver que el documento es accesible desde el nodo que corre el proceso en el puerto 27017, así como en el que corre el proceso en el 27018 ( y también lo será en el que lo corre en el 27019)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faqdczy3r9ytm8uama9fa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faqdczy3r9ytm8uama9fa.png" alt="Podemos ver que el documento está disponible en el puerto 27017"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7gdt8nlkt4idlb93eu3v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7gdt8nlkt4idlb93eu3v.png" alt="Podemos ver que el documento está también disponible en el puerto 27018"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Más métodos replicación, se describen en la &lt;a href="https://www.mongodb.com/docs/manual/reference/method/js-replication/" rel="noopener noreferrer"&gt;documentación&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Buenas prácticas para conjuntos de replicas
&lt;/h2&gt;

&lt;p&gt;Para terminar, hay que hacer incapié en que es importante seguir buenas prácticas al diseñar nuestras arquitecturas de conjuntos de réplicas, para poder garantizar la alta disponibilidad o la consistencia eventual, dependiendo del caso. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Es importante tener una buena política de retención de datos&lt;/strong&gt;, que gobierne nuestras decisiones en cuanto al tamaño y ventana de oplog.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.mongodb.com/docs/manual/reference/method/js-replication/" rel="noopener noreferrer"&gt;https://www.mongodb.com/docs/manual/reference/method/js-replication/&lt;/a&gt; Si se distribuyen a través de varios centros de datos (regiones o zonas), es importante que hayan al menos dos nodos en el mismo centro, para impedir que las interrupciones de conexión o la latencia, nos den falsos positivos. &lt;/p&gt;

&lt;p&gt;Es también importante &lt;strong&gt;habilitar los reintentos de escritura&lt;/strong&gt; y, dentro de lo posible, &lt;strong&gt;no abusar de los nodos árbitros y utilizarlos de manera eficiente.&lt;/strong&gt; Tener un árbitro, un secundario y un primario, no garantiza la alta disponibilidad del sistema.&lt;/p&gt;

&lt;p&gt;En la medida de lo posible, &lt;strong&gt;los nodos dedicados a tareas exclusivas (isolated workflows), deben esconderse&lt;/strong&gt;. &lt;/p&gt;

&lt;h3&gt;
  
  
  En los próximos blogs
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Operaciones CRUD&lt;/li&gt;
&lt;li&gt;Patrones de diseño&lt;/li&gt;
&lt;li&gt;Marco de Agregado&lt;/li&gt;
&lt;li&gt;Sharding&lt;/li&gt;
&lt;li&gt;Wired Tiger y caching&lt;/li&gt;
&lt;li&gt;CosmosDB para MongoDB API&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;y más...&lt;/p&gt;

&lt;p&gt;Si te ha gustado el artículo, compártelo y dale like aquí en dev.to! Una versión en inglés de este artículo estará disponible pronto en GitHub, para ser traducida a otros idiomas.&lt;br&gt;
Por favor, da crédito a &lt;a href="https://www.github.com/anfibiacreativa" rel="noopener noreferrer"&gt;https://www.github.com/anfibiacreativa&lt;/a&gt; si lo usas! &amp;lt;3&lt;/p&gt;

&lt;p&gt;Cuídense mucho! &lt;/p&gt;

</description>
      <category>mongodb</category>
      <category>modelodedocumento</category>
      <category>spanish</category>
      <category>basesdedatos</category>
    </item>
    <item>
      <title>CSS z-index illustrated</title>
      <dc:creator>Natalia Venditto</dc:creator>
      <pubDate>Tue, 27 Jul 2021 15:21:04 +0000</pubDate>
      <link>https://dev.to/playfulprogramming/css-z-index-illustrated-51f7</link>
      <guid>https://dev.to/playfulprogramming/css-z-index-illustrated-51f7</guid>
      <description>&lt;p&gt;My followers know that I no longer work as a frontend developer, however, I worked as one for nearly 15 years and I was self-taught. I was lucky to have a background in architecture, CAD and graphic and 3d design, so grasping the more mathematical (or in this case geometrical) aspects of putting together a layout, was not difficult for me. However, I see that for self-taught developers coming from completely unrelated backgrounds, the &lt;code&gt;z-index&lt;/code&gt; is a tough one to grasp.&lt;/p&gt;

&lt;p&gt;This is my attempt at explaining it in an illustrated way.&lt;/p&gt;

&lt;p&gt;Most people will be familiar with the concept of cartesian &lt;a href="https://www.techopedia.com/definition/14290/cartesian-coordinates" rel="noopener noreferrer"&gt;coordinates&lt;/a&gt;. They are used to define the location of a point in either a line (2d) or in space (3d). If you drive and use Google Maps, you are probably familiar with geospatial coordinates, or longitude and latitude; the points we use for locations on maps or Earth.&lt;/p&gt;

&lt;h3&gt;
  
  
  2d or two dimensional
&lt;/h3&gt;

&lt;p&gt;In &lt;code&gt;2d&lt;/code&gt;, we have the &lt;code&gt;y-axis&lt;/code&gt;, and the &lt;code&gt;x-axis&lt;/code&gt;. From their &lt;a href="https://www.techopedia.com/definition/769/convergence" rel="noopener noreferrer"&gt;convergence&lt;/a&gt;, the point (0,0), we can then specify where another point is located. Typically the &lt;code&gt;y-axis&lt;/code&gt; defines the vertical location, and the &lt;code&gt;x-axis&lt;/code&gt; the horizontal location of a point. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5las3igefk54ciebz8ff.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5las3igefk54ciebz8ff.jpg" alt="x-y-axis illustrated" width="800" height="780"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If we have several points that define a shape, like a box, then we can define its dimensions AND its location, using coordinates.&lt;/p&gt;

&lt;p&gt;This is basically how we do layout with css, defining the dimensions and location of elements with respect to those two imaginary lines that come defined by the edge of the viewport.&lt;/p&gt;

&lt;p&gt;We understand &lt;code&gt;y=0&lt;/code&gt; as the top of the browser viewport, and &lt;code&gt;x=0&lt;/code&gt; as the left edge (when left to right), so (0,0) would be the most top-left point as we load the page (considering it is not programmatically scrolling to another &lt;code&gt;x,y&lt;/code&gt; location).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx4rqzbonscyn29iys07j.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx4rqzbonscyn29iys07j.jpg" alt="a shape with respect to the x y axis of the viewports" width="800" height="605"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Layout and the box model
&lt;/h3&gt;

&lt;p&gt;When we are adding new elements to the markup of a page, by default they're added to the default context (I will explain context later in the article). They will follow the document flow and be stacked on top of each other, in the same order they are added to the document.&lt;/p&gt;

&lt;p&gt;So if we had 3 block elements like &lt;code&gt;divs&lt;/code&gt; for example, added to a document like you see in the figure below, if we could see them from the side in terms of an imaginary vertical stack, they would be stacked in this way:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fatqr531eof4fhw352s9w.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fatqr531eof4fhw352s9w.jpg" alt="divs stacked following the document flow" width="800" height="898"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But what would happen if you added a child to &lt;code&gt;div&lt;/code&gt; number 2, and give it a top margin to move it on top of &lt;code&gt;div&lt;/code&gt; 3 in the y-axis? That "overlapping" bit would be hidden by &lt;code&gt;div&lt;/code&gt; 3, and that's expected, since in terms of markup &lt;code&gt;div&lt;/code&gt; 3 is coming after &lt;code&gt;div&lt;/code&gt; 4 in the document flow.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fndn3sn0lyl1vtdq0qjzp.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fndn3sn0lyl1vtdq0qjzp.jpg" alt="divs markup" width="800" height="392"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn5lc5g3oy0lkuda7laom.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn5lc5g3oy0lkuda7laom.jpg" alt="divs stacked following the document flow" width="800" height="898"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  z-index: 99999999999 !important will help...NOT
&lt;/h3&gt;

&lt;p&gt;Many developers new to frontend will try to fix this using the &lt;code&gt;z-index&lt;/code&gt; property, with a very high positive value (or maybe negative, supposign they wanted to completely hide the &lt;code&gt;div 4&lt;/code&gt;). But that on its own, won't work. &lt;/p&gt;

&lt;p&gt;EDIT: Originally I had written -&amp;gt; "If you don't create a new stacking context, z-index won't work, no matter how many 9's and &lt;code&gt;!importants&lt;/code&gt; you add." ** I will address &lt;a href="https://dev.to/afif"&gt;Temani Afif&lt;/a&gt; comments below, stressing this: the new stacking context is created when position is set to ‘fixed’, ‘sticky’ or ‘relative’ and z-index is set to anything other than ‘auto’. Position on its own removes the element from the document flow, which means it no longer follows the order in the markup as elements are painted. However, it remains in the same stacking context.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding stacking contexts
&lt;/h2&gt;

&lt;p&gt;Let's port that two-dimensional representation of cartesian coordinates, to a three-dimensional or spatial one. As you probably guessed, now we have 3 points that specify the location of a point: (x, y, z)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F62rydnsnjpch3stw6mv2.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F62rydnsnjpch3stw6mv2.jpg" alt="3 dimensional representation of a layout" width="800" height="694"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A stacking context is each new layer added to that z-axis, that you can now reorder, to bring elements on top or place them below the default context or other contexts. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpip0ucwsr1jt1orb8tnx.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpip0ucwsr1jt1orb8tnx.jpg" alt="stacking contexts" width="800" height="785"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The order comes defined by the index, that can be 0, a positive integer or a negative integer or auto.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frh3rcr87bg5q8hys8byz.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frh3rcr87bg5q8hys8byz.jpg" alt="stack with z-index" width="800" height="785"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I advise you now head to the official documentation on MDN, and read all you can about &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Positioning/Understanding_z_index/The_stacking_context" rel="noopener noreferrer"&gt;stacking contexts&lt;/a&gt;. But in a nutshell, you create a new stacking context by giving a container div the following properties and values:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;you give it an &lt;code&gt;opacity&lt;/code&gt; different than 0&lt;/li&gt;
&lt;li&gt;you give it a &lt;code&gt;position&lt;/code&gt; other than &lt;code&gt;static&lt;/code&gt;, and a &lt;code&gt;z-index&lt;/code&gt; other than &lt;code&gt;auto&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;you give it &lt;code&gt;display&lt;/code&gt; either &lt;code&gt;flex&lt;/code&gt; or &lt;code&gt;grid&lt;/code&gt;, and a &lt;code&gt;z-index&lt;/code&gt; other than &lt;code&gt;auto&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;you use &lt;code&gt;transform&lt;/code&gt;, &lt;code&gt;perspective&lt;/code&gt;, &lt;code&gt;filter&lt;/code&gt;, &lt;code&gt;clip-path&lt;/code&gt; or &lt;code&gt;mask&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;or you use some of the brand new properties, such as &lt;code&gt;isolate&lt;/code&gt;(with a value of &lt;code&gt;isolate&lt;/code&gt;), &lt;code&gt;will-change&lt;/code&gt;, or &lt;code&gt;contain&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's all folks! I hope you find it useful and don't have to struggle with z-index issues anymore! &lt;em&gt;Also if this article has an error or you want to suggest an improvement, do it in the comments!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>css</category>
      <category>webdev</category>
      <category>layout</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>From developer to (solutions) architect. A simple guide.</title>
      <dc:creator>Natalia Venditto</dc:creator>
      <pubDate>Wed, 21 Jul 2021 17:36:54 +0000</pubDate>
      <link>https://dev.to/playfulprogramming/from-developer-to-solutions-architect-a-simple-guide-2b91</link>
      <guid>https://dev.to/playfulprogramming/from-developer-to-solutions-architect-a-simple-guide-2b91</guid>
      <description>&lt;p&gt;So you don't have formal CS education and have been doing development for some years, or you are a junior but your manager has already asked you where do you see yourself in tech in a few years. You want to become an Architect, but you are not sure of what it takes and you want to have a better idea of what you should focus on. You want to understand where are your technical gaps and what soft skills are required. This article is for you!&lt;/p&gt;

&lt;p&gt;Architect is an umbrella term to designate a role that is focused on either designing or refining software solutions for the benefit of the customer. But it has different accountabilities, depending on the organization you work for. &lt;/p&gt;

&lt;h2&gt;
  
  
  Pre-Sales Solutions Architects
&lt;/h2&gt;

&lt;p&gt;Pre-Sales Solutions Architects can also be called Customer Engineers or Sales Engineers, and are usually focused in making sure a technology they represent fits a customer's use case and their required capabilities, while they help them design a system to integrate it, or give pointers about the best application of it. They'll work on high-level diagrams, do discovery, work in scoping, and give support to Sales reps during technical alignments.&lt;/p&gt;

&lt;h2&gt;
  
  
  Post-Sales Solutions Architects
&lt;/h2&gt;

&lt;p&gt;Some of the pre-sales Architects, also do post sales, meaning that after you're done with the sales process, and a deal is closed, you focus in helping with the actual implementation. They may just design the systems at a high level and overview the implementation, or be very hands on, and execute it together with the technical implementation team.&lt;/p&gt;

&lt;h2&gt;
  
  
  Software Architects
&lt;/h2&gt;

&lt;p&gt;Software Architect is a very hands on role, architecting and oftentimes implementing a software solution. Software Architects are an equivalent of the Post-Sales, usually for a product or specific technology. Software Architects are not necessarily customer facing.&lt;/p&gt;

&lt;p&gt;Again, it's important to clarify that the designation and accountabilities for each role, may vary across the industry.&lt;/p&gt;

&lt;h2&gt;
  
  
  The technical common ground
&lt;/h2&gt;

&lt;p&gt;No matter what type of architect, the common ground is the technical one. Architects are technical by nature, from a perspective that allows them to connect tech specifications to complex security requirements, governance nuances and privacy compliance and sovereignty, and legal liabilities. They are not concerned with the nitty-gritty details of the implementation, rather the big picture. Deployment pipelines, layers of the stack, performance at a system level, user management, locality, infrastructure components...those are the things that really interest and occupy an architect.&lt;/p&gt;

&lt;h2&gt;
  
  
  Process phases a Solutions Architect participates of
&lt;/h2&gt;

&lt;p&gt;I work now in the role of Solutions Architect, and will focus on this particular dimension, since Software Architects are involved in processes pertaining the software development cycle, which is much more complex to describe.&lt;/p&gt;

&lt;p&gt;Solutions Architects are usually a customer facing role and participate of and are instrumental to a lot of conversations with them. Their main goal is to discover and scope a system's requirements and/or current technical state as much as drafting the desired state and deciding or advising on the most ideal solution.&lt;/p&gt;

&lt;h3&gt;
  
  
  Discovery
&lt;/h3&gt;

&lt;p&gt;SA's (acronym for Solutions Architect) participate of discovery. These are the early stages of conversation with a client, where many questions are asked. An SA needs to understand everything about their client, their product or project, their goals, their problems, so they can map those to tangible solution suggestions.&lt;/p&gt;

&lt;p&gt;The most important skills at a discovery meeting are not technical: Solutions Architects need to be able to &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;listen more than talk&lt;/li&gt;
&lt;li&gt;make good assumptions and validate them with the client&lt;/li&gt;
&lt;li&gt;do not propose a solution ahead of understanding well all the problems and requirements&lt;/li&gt;
&lt;li&gt;be very objective&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Contrary to what many people think, even those architects that represent a brand, are unlikely to push for a biased solution if they assess that's not what the client needs. Not only your reputation is at stake, most architects pride themselves in promoting the foundations of a solid system&lt;/p&gt;

&lt;h4&gt;
  
  
  Foundations of a solid system
&lt;/h4&gt;

&lt;p&gt;Solid, well designed systems share certain identical features. They all aim to be scalable, robust, resilient, recoverable and secure, among other important characteristics. Architects also want their systems to be highly available and sometimes they have requirements for them to be globally distributed, which is less of a problem today when global provisioning is guaranteed in the cloud. &lt;/p&gt;

&lt;h3&gt;
  
  
  Scoping
&lt;/h3&gt;

&lt;p&gt;Requirements are the documented capabilities used to measure a systems success, according to whether or not they're satisfied. They usually map to those foundational concepts. Like for example, it may be a requirement for the system to have an uptime of a certain percentage (usually 99.995% for mission critical applications, which is about 4s downtime daily - you can calculate that SLA here &lt;a href="https://uptime.is/" rel="noopener noreferrer"&gt;https://uptime.is/&lt;/a&gt;). That requirement maps to &lt;code&gt;High Availability&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;The process of putting requirements and capabilities in scope, is also done by the architect, and usually (technically) validated by the customer with business objectives in mind, at some point. Backlogs are oftentimes the result of generating user stories and functional requirements directly from the scoping exercise, together with the validation and priorization of capabilities, towards a release. &lt;/p&gt;

&lt;h2&gt;
  
  
  What technologies should I focus on?
&lt;/h2&gt;

&lt;p&gt;That is a difficult question to answer, since it will very much depend on the type of system a software or solutions architect is designing or assessing, the technologies may vary greatly. I will focus on describing a list of technologies and areas of expertise you may want to check out, if your goal is to become an architect working in web oriented solutions.&lt;/p&gt;

&lt;h3&gt;
  
  
  The cloud landscape
&lt;/h3&gt;

&lt;p&gt;This is not to say there aren't architects still working on premise in self managed environments, but if you're planning to join the forces, you probably want to have an idea of who are the 3 public cloud providers (&lt;a href="https://aws.amazon.com/" rel="noopener noreferrer"&gt;AWS&lt;/a&gt;, &lt;a href="https://azure.microsoft.com/en-gb/" rel="noopener noreferrer"&gt;Azure&lt;/a&gt; and &lt;a href="https://console.cloud.google.com/" rel="noopener noreferrer"&gt;GCP&lt;/a&gt;), and their offering and topology. &lt;/p&gt;

&lt;p&gt;You may also want to learn about cloud-native technologies, and explore what's hot and trending.&lt;/p&gt;

&lt;p&gt;Additionally it's very useful to know certain jargon and how some mechanisms work in the cloud. Concepts like&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;what is a &lt;a href="https://www.capitalone.com/tech/cloud/what-is-a-cluster/" rel="noopener noreferrer"&gt;cluster&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.delltechnologies.com/en-us/blog/the-difference-between-scale-up-and-scale-out/" rel="noopener noreferrer"&gt;scaling out vs. scaling up&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;what are &lt;a href="https://www.confluent.io/learn/distributed-systems/" rel="noopener noreferrer"&gt;distributed systems&lt;/a&gt; and how they work&lt;/li&gt;
&lt;li&gt;what are the &lt;a href="https://docs.microsoft.com/en-us/azure/architecture/best-practices/caching" rel="noopener noreferrer"&gt;caching mechanisms&lt;/a&gt; and the best practices in the cloud&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Infrastructure and infrastructure provisioning
&lt;/h3&gt;

&lt;p&gt;Provisioning infrastructure is not really the architect domain and it is usually done by the system engineers, Ops or other roles (the name may vary, depending on the organization). However, architects may have to validate or analyse the deployment pipelines and infrastructure setup before it is executed or afterward, for several reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;costs assessment&lt;/li&gt;
&lt;li&gt;compliance with architecture definitions (security, performance, technology definitions, etc)&lt;/li&gt;
&lt;li&gt;risk evaluation&lt;/li&gt;
&lt;li&gt;reconfiguration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Although infrastructure provisioning, especially in the cloud, is provider dependent, there are some concepts you need to know and understand.&lt;/p&gt;

&lt;h4&gt;
  
  
  Networking
&lt;/h4&gt;

&lt;p&gt;You will need to understand well how the internet works and all the layers involved. Some important concepts and focus areas would be&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the Networking Layer Model per type (TCP/IP, vLab, ISO/OSI)&lt;/li&gt;
&lt;li&gt;TCP/UDP/HTTP Protocols&lt;/li&gt;
&lt;li&gt;SSL, TLS and other Networking Security concepts (Firewalls, Keys, VPN's, VPC, Private Link, Network Peering, etc and the OWASP checklist)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A book I definitely recommend to read to catchup with a lot of these concepts, is &lt;a href="https://www.pearson.com/us/higher-education/program/Kurose-Computer-Networking-A-Top-Down-Approach-7th-Edition/PGM1101673.html" rel="noopener noreferrer"&gt;Computer Networking, a Top-Down Approach&lt;/a&gt; I had to read it when I was taking credits in Software Engineering, and it's one of the best books on the subject.&lt;/p&gt;

&lt;p&gt;I also recommend you download and install &lt;a href="https://www.wireshark.org/" rel="noopener noreferrer"&gt;Wireshark&lt;/a&gt; for packet sniffing or TCP analysis, to learn more about segments, headers, and other networking concepts. There are more sophisticated tools, but this one is great to get going. It's open source, free and a consolidated tool.&lt;/p&gt;

&lt;h4&gt;
  
  
  Hardware
&lt;/h4&gt;

&lt;p&gt;Yes, you need to know about hardware. This is particularly important at the time of deciding on infrastructure configuration and if you detect performance issues and must scale up or down/out or in and system, to decide on the specifications. Concepts like &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CPU, (disk) SDD and HDD, (memory) RAM(ø)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.quostar.com/blog/iops-explained/" rel="noopener noreferrer"&gt;IOPS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.zdnet.com/article/commonly-used-raid-architectures/" rel="noopener noreferrer"&gt;RAID&lt;/a&gt; architecture&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.cloudflare.com/en-gb/learning/network-layer/what-is-a-computer-port/" rel="noopener noreferrer"&gt;ports&lt;/a&gt; -very important for hexagonal architectures-&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;and concepts like&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;big and little &lt;a href="https://www.freecodecamp.org/news/what-is-endianness-big-endian-vs-little-endian/" rel="noopener noreferrer"&gt;endianness&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Unless you actually work at a data center and walk in between racks, you probably don't need to know about other components like power supplies. Just the necessary specifications to match a software requirement. Although I always advise that the more you know, the better! But you also need to know about: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;operating systems(ø)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://azure.microsoft.com/en-us/overview/what-is-virtualization/" rel="noopener noreferrer"&gt;virtualization&lt;/a&gt; (most servers are actually virtual machines on top of physical servers)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.ibm.com/cloud/learn/containerization" rel="noopener noreferrer"&gt;containerization&lt;/a&gt; and containerization and orchestration software (like &lt;a href="https://www.docker.com/" rel="noopener noreferrer"&gt;Docker&lt;/a&gt; and &lt;a href="https://kubernetes.io/" rel="noopener noreferrer"&gt;Kubernetes&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;(ø)I am not going to provide links to content about physical components of computers because there are way too many sources, and you only need to run a quick google search and pick the one that interests you the most.&lt;/p&gt;

&lt;p&gt;One important piece of advise I can give you, is that whatever operating system you love the most, you probably need to be familiar with Unix and Unix-like systems and architectures, and be proficient in the use of the &lt;a href="https://www.unixtutorial.org/basic-unix-commands" rel="noopener noreferrer"&gt;shell&lt;/a&gt; since it's the preferred means of executing code remotely, deploying packages and code and accessing systems. &lt;/p&gt;

&lt;h4&gt;
  
  
  Databases
&lt;/h4&gt;

&lt;p&gt;The task of storing and manipulating data becomes more and more important, as applications are more and more user-centric. Storing data is not only about the software used for it. It's a key part of the success of an application. And architects need to be well aware of the&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;different &lt;a href="https://ecomputernotes.com/fundamental/what-is-a-database/type-of-data-models" rel="noopener noreferrer"&gt;data models&lt;/a&gt; and database architecture&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.mongodb.com/nosql-explained/nosql-vs-sql" rel="noopener noreferrer"&gt;tabular vs document&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/nosql/graph/" rel="noopener noreferrer"&gt;graph databases&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cloud.google.com/learn/what-is-object-storage" rel="noopener noreferrer"&gt;object storage&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;physical requirements of the database software&lt;/li&gt;
&lt;li&gt;limitations of certain models in relation to scalability&lt;/li&gt;
&lt;li&gt;security implications of data flows&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You probably want to investigate what product corresponds to what provider, and want to learn concepts like &lt;a href="https://www.techopedia.com/definition/16455/transaction-databases" rel="noopener noreferrer"&gt;transactions and ACID compliance&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You may think I'm biased, but I recommend you head to the MongoDB free learning platform aka &lt;a href="https://university.mongodb.com/" rel="noopener noreferrer"&gt;MonogDB University&lt;/a&gt;, where there are tons of information on all those subjects, and a lot of it is -contrary to what many may think- very objective.&lt;/p&gt;

&lt;h4&gt;
  
  
  Architecture models
&lt;/h4&gt;

&lt;p&gt;Well obviously, an architect needs to know about architecture! And architecture is an evolving and dynamic ground! &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://microservices.io/" rel="noopener noreferrer"&gt;microservices&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dzone.com/articles/hexagonal-architecture-what-is-it-and-how-does-it" rel="noopener noreferrer"&gt;hexagonal architectures&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;monoliths&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.microsoft.com/en-us/azure/architecture/guide/architecture-styles/event-driven" rel="noopener noreferrer"&gt;event-driven&lt;/a&gt; architecture&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.martinfowler.com/articles/serverless.html" rel="noopener noreferrer"&gt;serverless&lt;/a&gt; architecture&lt;/li&gt;
&lt;li&gt;&lt;a href="https://jamstack.org/" rel="noopener noreferrer"&gt;jam stack&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You need to know those concepts by heart and when they're the approach to follow. I am inclined to think that a good architect, just like a good developer, is never biased, and will try to find the right solution to a problem, instead of finding a problem to implement a preferred solution.&lt;/p&gt;

&lt;p&gt;All those paradigms have software and technologies associated, that you may want to explore and experiment with. For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;docker (containerization/virtualization)&lt;/li&gt;
&lt;li&gt;kubernetes (orchestration/management of containers)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://kafka.apache.org/" rel="noopener noreferrer"&gt;kafka&lt;/a&gt; (event-streaming platform)&lt;/li&gt;
&lt;li&gt;serverless functions (very much provider dependent, are a way to execute functions on triggers and avoid large backend implemetations)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Needless to say that the many providers will have tools and connectors, modules and best practices or guidelines, to implement each different type of pattern according to their infrastructure architecture and offering.&lt;/p&gt;

&lt;h4&gt;
  
  
  Deployment pipelines and release models
&lt;/h4&gt;

&lt;p&gt;Architects are usually in charge of designing deployment pipelines, that tend to depend on the application release model. If you are working with a continuous integration pattern, you'll probably have to support it with CI/CD automation tools. And the following concepts should be familiar to you&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Actions&lt;/li&gt;
&lt;li&gt;Triggers/Events&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/en-us/dotnet/architecture/cloud-native/infrastructure-as-code" rel="noopener noreferrer"&gt;Infra as code&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;together with relevant software (again, options may be conditioned by the cloud provider choice)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://circleci.com/docker/?utm_medium=sem&amp;amp;utm_source=microsoft&amp;amp;utm_campaign=sem-microsoft-dg--emea-en-circleciBuildDeployEnviron-eCPC-auth-nb&amp;amp;utm_content=keyword-text_rsa-exact_docker-&amp;amp;msclkid=a0fbd75708d018c80cceb7af26c0bf57" rel="noopener noreferrer"&gt;Circle CI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.jetbrains.com/teamcity/?msclkid=415bd95bc1411e73c559b9a3f07fc2ff&amp;amp;utm_source=bing&amp;amp;utm_medium=cpc&amp;amp;utm_campaign=EMEA_en_ES_TeamCity_Search_Competitors&amp;amp;utm_term=circle%20ci&amp;amp;utm_content=circle%20ci" rel="noopener noreferrer"&gt;TeamCity&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.terraform.io/" rel="noopener noreferrer"&gt;Terraform&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the realms of automation you may also have to design means of performing test-automation for different areas, ranging from code sanity to performance, and have to know about the implementation and configuration of tools like&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.sonarqube.org/" rel="noopener noreferrer"&gt;SonarQube&lt;/a&gt; (code quality)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://customerportal.solarwinds.com/" rel="noopener noreferrer"&gt;SolarWinds&lt;/a&gt; (performance monitorization or observability)
and the likes&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Access control and governance
&lt;/h4&gt;

&lt;p&gt;Architects are for sure in many cases responsible for software/platform security, if not for its implementation, for its design or assessment.&lt;/p&gt;

&lt;p&gt;It is important for architects to understand the many means of controlling access to software code bases and data, and the services provided by the applications they architect.&lt;/p&gt;

&lt;p&gt;Architects know well the meaning of &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;authorization&lt;/li&gt;
&lt;li&gt;authentication
&lt;a href="http://www.bu.edu/tech/about/security-resources/bestpractice/auth/" rel="noopener noreferrer"&gt;http://www.bu.edu/tech/about/security-resources/bestpractice/auth/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;and have to understand the different ways to implement them, at an application level and low level, too.&lt;/p&gt;

&lt;p&gt;It is desirable for architects to understand what vectors of vulnerability their apps or platforms, or the software they work with may be exposed to, in order to mitigate risks.&lt;/p&gt;

&lt;p&gt;Governance has many meanings and implications and it's so intersectional I can only map it to the different dimensions it may connect to. &lt;/p&gt;

&lt;p&gt;For example, designing role based access depending on authorization granularity is part of governance policies for access, while software capabilities providing the ability to set those rules, guarantee legal compliance with standards like &lt;a href="https://www.iso.org/isoiec-27001-information-security.html" rel="noopener noreferrer"&gt;ISO27001&lt;/a&gt; or GDPR. &lt;/p&gt;

&lt;h4&gt;
  
  
  The API and application layers
&lt;/h4&gt;

&lt;p&gt;Most modern architecture patterns for web development are very heavily API dependent. It is very likely that the software or platform an architect is responsible for, does not only consume from dozens of API's but also exposes some of them.&lt;/p&gt;

&lt;p&gt;Needless to say, 100% of the tools I mentioned through the article, are API based, and so are most of the services exposed by cloud providers.&lt;/p&gt;

&lt;p&gt;For this reason, architects need to be skilled on API design and maintenance, and very familiar with concepts and patterns like&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://restfulapi.net/" rel="noopener noreferrer"&gt;REST APIs&lt;/a&gt; and &lt;a href="https://www.json.org/json-en.html" rel="noopener noreferrer"&gt;JSON&lt;/a&gt; standards&lt;/li&gt;
&lt;li&gt;&lt;a href="https://graphql.org/" rel="noopener noreferrer"&gt;GraphQL&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://stoplight.io/api-types/soap-api/" rel="noopener noreferrer"&gt;SOAP&lt;/a&gt; (although less used now, many legacy systems still consume or expose SOAP services)&lt;/li&gt;
&lt;li&gt;And other API alternatives like &lt;a href="https://www.geeksforgeeks.org/introduction-java-servlets/" rel="noopener noreferrer"&gt;Java Servlets&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And before you complain about the age of some of the mentioned API architectures, remember that a lot of times Solutions Architects assist in migrating &lt;a href="https://www.techopedia.com/definition/635/legacy-system" rel="noopener noreferrer"&gt;Legacy Systems&lt;/a&gt;, and for that, they need to know what they're facing!&lt;/p&gt;

&lt;p&gt;In order to effectively design and maintain, or even assess in-place solutions, it is very useful for architects to be aware of and implement the &lt;a href="https://www.openapis.org/" rel="noopener noreferrer"&gt;Open API specification&lt;/a&gt; and &lt;a href="https://swagger.io/" rel="noopener noreferrer"&gt;Swagger&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Architects need to design the connection and sometimes aggregation of data coming from all those API's. For that reason, they also need to understand well how to consume them and distribute them, and need to know concepts like&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://apifriends.com/api-management/api-gateway-to-the-cloud/" rel="noopener noreferrer"&gt;north-south bound&lt;/a&gt; (API gateway)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://apifriends.com/api-management/service-mesh/" rel="noopener noreferrer"&gt;east-west bound&lt;/a&gt;(service-to-service or service mesh)&lt;/li&gt;
&lt;li&gt;proxy and &lt;a href="https://www.cloudflare.com/en-gb/learning/cdn/glossary/reverse-proxy/" rel="noopener noreferrer"&gt;reverse proxy&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In terms of app development, it may not be necessary for architects to know or understand implementation details of high level languages, but most architects do anyway, since at a great percentage architects used to be developers. &lt;/p&gt;

&lt;h2&gt;
  
  
  High-level diagrams, UML and other types of diagrams
&lt;/h2&gt;

&lt;p&gt;Architects speak in diagrams. Believe me. Oftentimes they need to represent very complex systems and relationships, and the only way to do it is being proficient at representing entities with shapes and arrows.&lt;/p&gt;

&lt;p&gt;This is why architects learn &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.edrawsoft.com/what-is-uml-diagram.html" rel="noopener noreferrer"&gt;UML&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.vertabelo.com/blog/crow-s-foot-notation/" rel="noopener noreferrer"&gt;Crow's Foot Notation&lt;/a&gt;
and other representation schemas&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Architects usually conduct and lead calls with customers, and they need to have great public speaking and presentation skills: from putting together impressive slide decks, to expressing complex technical ideas in a language everyone can understand.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sales
&lt;/h2&gt;

&lt;p&gt;Some organizations hire architects to be part of their sales processes, and advise sales reps and clients from a technical perspective.&lt;/p&gt;

&lt;p&gt;Those organizations are very likely to offer training in their sales process and methodologies used, as well as ramping up the architects in a particular technology or software.&lt;/p&gt;

&lt;h2&gt;
  
  
  Will all my coding skills go to waste?
&lt;/h2&gt;

&lt;p&gt;Absolutely NOT! I can speak from personal experience that all I have learned as a software developer, helps me quickly understand systems and decisions, analyse existing code bases and configurations, and build rapport with other architects and developers. Some solutions architects are required to build PoC's on a regular basis, and your coding skills are not only helpful but necessary.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Well, I know this is already very long, and this is only the tip of the ice-berg! Software and Solutions Architecture is a very rewarding career path and one that many developers follow when they don't want to move to more administrative, project or account management positions, and want to continue to be part of the technical scene. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Disclaimer: I added links to resources from pretty reputable sites, but if you want to contribute with better ones, add them in the comments!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If you have more questions, hit me on &lt;a href="https://www.twitter.com/anfibiacreativa" rel="noopener noreferrer"&gt;twitter&lt;/a&gt;, share and like!&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>cloudskills</category>
      <category>infrastructure</category>
      <category>systems</category>
    </item>
    <item>
      <title>From Designer to Software Engineer to Solutions Architect: my journey</title>
      <dc:creator>Natalia Venditto</dc:creator>
      <pubDate>Fri, 29 Jan 2021 13:19:17 +0000</pubDate>
      <link>https://dev.to/playfulprogramming/from-designer-to-software-engineer-to-solutions-architect-my-journey-2p5b</link>
      <guid>https://dev.to/playfulprogramming/from-designer-to-software-engineer-to-solutions-architect-my-journey-2p5b</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;I want to start this post with the regular disclaimer: this is my journey, and everything about it, is intrinsically bound to my nature as a person. A different person, under the same circumstances, may experience something totally different and get different results.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To explain how I got here, I have to go all the way back to when I was studying to be a draftswoman, and was supposedly going to continue my education as a (buildings) architect. Somewhere down the road I fell in love with CAD, with computers and graphic design, and even got a job at a printshop after a Photoshop, Quark and Freehand crash course.&lt;/p&gt;

&lt;p&gt;In 2003 I moved to Spain. Immigrating is difficult, especially when you have to support yourself entirely. But when I did I was lucky to have over 5 years of experience as a graphic designer, and it was easy for me to get a job working for a small agency as soon as I moved here. We published a magazine focusing on real estate and after a few months I was promoted to Creative Director to be in charge of the magazine and the corporate image of a few clients. I had a couple of designers in my team, and it was fun.&lt;/p&gt;

&lt;h2&gt;
  
  
  Plot twist
&lt;/h2&gt;

&lt;p&gt;One year later, it was evident all business was moving online. Youtube was about to be born, Facebook was in diapers, and everyone wanted to have online presence. I convinced the manager we should have a website, and we should try to build an online version of the magazine as a portal. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"We need a web developer for that" -he said. "I will be the web developer". I answered.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I started spending all my spare time learning Action Script. I was amazed at those full screen Flash websites, featuring gorgeous animations and graphics. I wanted to learn to do that. For the portal, I learned HTML, CSS, Javascript, PHP and mySQL. I was amongst the first avid consumers of online tutorials and web development books.&lt;/p&gt;

&lt;p&gt;I experimented with Joomla, Wordpress, and finally Drupal.&lt;/p&gt;

&lt;h2&gt;
  
  
  And then the 2007 crisis hit us hard
&lt;/h2&gt;

&lt;p&gt;We could keep the boat afloat selling websites, exclusively. I would be in charge of designing the websites, managing the databases, the hosting, setting DNS records, configuring htaccess, installing the CMS and plugins, developing frontend, and doing the maintenance. I was a true "webmaster" of the time. I loved it! &lt;/p&gt;

&lt;p&gt;But in 2011, we hit rock bottom. Most of our clients were developers and real estate agents, that bursted together with the real estate bubble. They had to close business, and so did we. I started freelancing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Being a freelance web developer, is a 24/7 job
&lt;/h2&gt;

&lt;p&gt;If you're not working as a consultant for a much larger company and you have your own clients like I did, it's tough work. You're the sales person, the architect, the PM, the designer, the developer, the quality engineer, the tier 1 to 4 support person, the systems person, and the back office cashing the checks...you're it all. There are no evenings, no weekends... &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Being a mom and a freelancer, was the most challenging thing I ever did. I breastfed my kid while patching 10 Drupal sites for &lt;a href="https://www.drupal.org/project/heartbleed" rel="noopener noreferrer"&gt;heartbleed&lt;/a&gt;. I ran to school while holding a call with a client.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Getting a job in enterprise
&lt;/h2&gt;

&lt;p&gt;So in 2014 I sent my CV to a consultant company (the same one I work for right now), with little hope. I had no CS degree, and all I had read around was I stood no chance to land a job in that league. &lt;/p&gt;

&lt;p&gt;But I did land the job as a Frontend Developer for Adobe Experience Manager projects. I had to move to Barcelona, with my family. It was an immense bet. And you can say fortunately, it went well. Although it was not only fortune: there was always a lot of hard work involved. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;It was not only fortune. There was always a lot of hard work and persistence involved.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The enterprise context has particularities, also. Working on enterprise you also learn a lot about politics, policies and processes. ;)&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting acquainted with Adobe Experience Manager
&lt;/h2&gt;

&lt;p&gt;Up until that day, Adobe was for me the company behind Photoshop, period. (Aaaand the company that had bought Macromedia and decommissioned my favorite ever vectors editor, Freehand ... :/ ) I had no idea they had also bought Day Software and had a CMS. &lt;/p&gt;

&lt;p&gt;I was very comfortable with content management systems, and it did not take me too long to wrap my head around how it worked. Some frontend developers want to stick to frontend code only, and it's respectable. But I was coming from a different kind of dynamics (see the freelancer part!) and I was happy to traverse the whole stack.&lt;/p&gt;

&lt;p&gt;My first role was as a Frontend Tech Lead for a very large platform being built from scratch. One year later, I was moved to a banking platform where I stayed for 6 months. Then I was assigned to a new account we had just gotten, as a tier 3 support and solutions engineer for a massive legacy platform. I was again in the role of Frontend Tech Lead, and I know a lot of people dislike working with legacy software, but I can promise you the amount of knowledge I was getting every single day working with it, was priceless.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The amount of knowledge I was getting every single day working with legacy code was priceless; the problems I had to solve were unique.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In my opinion, no other experience is better to understand coupling, dependencies, and acquire an overall overview of a system.&lt;/p&gt;

&lt;h2&gt;
  
  
  Plot twist, again
&lt;/h2&gt;

&lt;p&gt;Apart from support, we were integrating new features, and at some point we decided we did not want the risk to build anymore on top of it, we wanted to go for cutting edge technologies. So a little bit more than a year later I got my first architect gig, working in the conceptualization and definitions of the 2.0 version for the same platform.&lt;/p&gt;

&lt;p&gt;I fell in love with designing systems. It is a lot like building with legos. And I could apply principles learned while studying to be a buildings architect. After all, you want the same for your buildings than you want for your systems, for them to meet quality standards, to be resilient, secure and durable, amongst other things.&lt;/p&gt;

&lt;h2&gt;
  
  
  My first pre-sales experience was intense
&lt;/h2&gt;

&lt;p&gt;In August 2017 I also attended my first RfP workshop. A global leading brand issued a RfP (request for proposal) for a very large enterprise project and I helped in putting together the whole DevOps strategy, and then travelled onsite, together with the Account Manager, a UX Engineer, and two C-levels, to defend our proposal.&lt;/p&gt;

&lt;p&gt;I had to present the whole DevOps offer. &lt;/p&gt;

&lt;p&gt;We won.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conferences and public speaking and how they help me in being a better architect
&lt;/h2&gt;

&lt;p&gt;Being an architect is a lot about communicating. You have to communicate your ideas and definitions or decisions to a team, other project leads and the clients. Translating those very technical concepts into simpler words and concepts any audience can understand demands highly developed communication skills. You need to be able to articulate and convey with simplicity, what sometimes are very abstract ideas.&lt;/p&gt;

&lt;p&gt;Speaking at conferences and other technical events, has definitely helped me grow more comfortable into that presenter role. But I have to admit it is never the same talking to a crowd of peers or other developers, than to a customer.&lt;/p&gt;

&lt;p&gt;The key is, no matter who you are addressing, you need to build rapport. And the most optimal way to build rapport is to identify with the more human side by providing structure to your narrative in a way that it becomes a story your audience can relate to.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Always, always put some work in your communication skills. Especially if you want to become an architect in the future.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Collaborating with sales teams
&lt;/h2&gt;

&lt;p&gt;Typically, Solutions Architects have more of a backend/systems background. 4 years ago, it was already obvious to me that as the volume of frontend work was growing, the integrations were more complex, and there was a lot more to put together nicely. The role of a frontend expert during discovery phases was not only necessary, it was essential. I started paving the way to get there.&lt;/p&gt;

&lt;p&gt;I joined a sales squad operating in northern Europe, in parallel to being a hybrid Tech Lead/Architect at the project I was assigned to (the one we won!).&lt;/p&gt;

&lt;p&gt;As part of that team, I review code bases of potential clients/leads, join meetings to understand their problems and requirements, write architecture vision papers from infrastructure to tech stack, estimate and define timelines, estimate staffing needs, etc. Before COVID, I was traveling places to present those analysis or gather more information, or to build a connection with the clients, or to educate them on a certain subject.&lt;/p&gt;

&lt;p&gt;Sometimes I would fly for the day only to Amsterdam or Copenhagen, sit in a meeting, and come back in the evening right on time to have dinner with my family. It was exciting, but also intense, and if you want that, you have to be prepared. On the way there, I was putting together slides and documentation for that meeting. On the flight back, I was reviewing PR's from my own project.(Thank you Norwegian and all the airlines that have wi-fi onboard!).&lt;/p&gt;

&lt;h2&gt;
  
  
  Leaving the tech lead role behind
&lt;/h2&gt;

&lt;p&gt;At some point last year, we started working on a brand new concept that required a lot of high level definitions and I was officially anchored to the Solutions Architect pathway. In the context of the project I work at, I already had the architect role officially for 2 years, as part of our Holocracy organization. &lt;/p&gt;

&lt;p&gt;Every company has their own role definitions and people energizing them are expected to deliver in different ways. At my current company, architects are definitely very hands-on. Our culture promotes and celebrates the intersection of architect and lead developer.&lt;/p&gt;

&lt;p&gt;However, the domains where architects and tech leads work, although intersecting, are on opposite sides of the high-level design imaginary line. For those that are not familiar with the differences, this diagram may shed some light.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fnjcuqf2nnumvu5u3l034.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fnjcuqf2nnumvu5u3l034.jpg" alt="architect-vs-tech-lead" width="800" height="1066"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What does an architect do?
&lt;/h2&gt;

&lt;p&gt;Architects are in charge of high level definitions of a system. They are the connecting point between the business vision and requirements, and the technical know-how. Even if they can, architects will not care about the nitty gritty details of the implementation.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Architects are the connecting point between the business vision and requirements, and the technical know-how&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is probably the part that is more difficult to detach yourself from, when you transition from being a tech lead. When you review a pull request, your input is not really so necessary in terms of "You could've used this method here, instead of this other one".  Your concern is the big picture.&lt;/p&gt;

&lt;p&gt;In fact, you will find yourself less and less in contact with other developers, and working more on your own or with other architects, requirement engineers, system engineers, and quality assurance leads. That is probably the hardest part of the transition. &lt;/p&gt;

&lt;p&gt;Also if you come from a frontend technical lead position, you will be less in the spotlight. Work at a high-level is less tangible and visible, but equally important.&lt;/p&gt;

&lt;h3&gt;
  
  
  The day to day
&lt;/h3&gt;

&lt;p&gt;As an architect, most of my (project) day is spent on client calls, team meetings to align the rest of the team on decisions made, partner calls, working on diagrams and documentation, and executing proof of concepts. I am more concerned about  API design and integrations, data storage, security, performance, CD/CI pipelines, releases and rollouts. I care about my client's system being legally and standards compliant.&lt;/p&gt;

&lt;p&gt;I am no longer part of the development sprint, and I don't deliver tasks in the scope of it. Do I miss it? I have to admit that I miss it less and less every time: for once, I really like what I do now. And I also enjoy tremendously the ability of delegating and seeing other people grow in the same direction I did.&lt;/p&gt;

&lt;p&gt;My sales support day is spent supporting proposals and discovery, attending meetings with leads, writing architecture visions, reviewing concepts by other architects, and preparing educational material pre and post sales. So everything I used to do before COVID, minus the traveling. &lt;/p&gt;

&lt;h2&gt;
  
  
  The skills required to become a solutions architect
&lt;/h2&gt;

&lt;p&gt;Let's map what I do, to the skills I find the most useful. The soft skills required to do a great architect job are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Communication skills (ability to articulate but also to listen)&lt;/li&gt;
&lt;li&gt;Presentation skills (put together great diagrams, and concise slide decks)&lt;/li&gt;
&lt;li&gt;Diplomacy (you're at the front line with the client. It's all about business and especially in enterprise, you have to use a lot of patience and good manners)&lt;/li&gt;
&lt;li&gt;Manoeuvring (because of working together with the client, you have to have the capacity to manoeuvre and respond fast)&lt;/li&gt;
&lt;li&gt;Analytical skills (your job is all about solving abstract problems, designing or fixing systems that many not even exist yet)&lt;/li&gt;
&lt;li&gt;Leadership skills (you have to lead your team and your client's team. You have to bring everyone onboard with what's best and the decisions made -which is a complex topic, sometimes, may not be the absolute best, but the most convenient in terms of parameters like time and budget-)&lt;/li&gt;
&lt;li&gt;Ability to estimate and staff a project&lt;/li&gt;
&lt;li&gt;Ability to prioritize &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The technical knowledge is also different than the one you needed to have as a tech lead. Apart from mastering a programming language, right now in 2021 I recommend you specialize in&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;cloud providers and their offerings&lt;/li&gt;
&lt;li&gt;concepts like horizontal and vertical scaling&lt;/li&gt;
&lt;li&gt;concepts like replication and sharding&lt;/li&gt;
&lt;li&gt;serverless computing&lt;/li&gt;
&lt;li&gt;databases&lt;/li&gt;
&lt;li&gt;API patterns and contracts&lt;/li&gt;
&lt;li&gt;CD/CI and how to build your pipelines effectively&lt;/li&gt;
&lt;li&gt;automation&lt;/li&gt;
&lt;li&gt;containerization&lt;/li&gt;
&lt;li&gt;orchestration&lt;/li&gt;
&lt;li&gt;architecture trends (like micro-services)&lt;/li&gt;
&lt;li&gt;design patterns&lt;/li&gt;
&lt;li&gt;UML and different types of diagrams (flow, mindmaps)&lt;/li&gt;
&lt;li&gt;security and protocols (networks)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you have a frontend focus, you can check this mindmap of useful skills I put together a bit ago&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fcschryvfuc1t8gweb0l7.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fcschryvfuc1t8gweb0l7.jpeg" alt="frontend architecture mindmap" width="800" height="357"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://twitter.com/AnfibiaCreativa/status/1331565865196777472/photo/1" rel="noopener noreferrer"&gt;https://twitter.com/AnfibiaCreativa/status/1331565865196777472/photo/1&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Additionally, stay up to date! These are some of the architects I follow to keep myself informed on architectural trends. This list is relevant for me, you may need to find your own good sources ;)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://lucamezzalira.com/" rel="noopener noreferrer"&gt;Luca Mezzalira&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.angulararchitects.io/en/team/manfred-steyer-gde/" rel="noopener noreferrer"&gt;Manfred Steyer&lt;/a&gt;&lt;br&gt;
&lt;a href="https://martinfowler.com/aboutMe.html" rel="noopener noreferrer"&gt;Martin Fowler&lt;/a&gt;&lt;br&gt;
&lt;a href="https://danwahlin.me/" rel="noopener noreferrer"&gt;Dan Wahlin&lt;/a&gt;&lt;br&gt;
&lt;a href="https://twitter.com/gabrielwalt?lang=en" rel="noopener noreferrer"&gt;Gabriel Walt&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Do I feel like my coding skills are suffering?
&lt;/h2&gt;

&lt;p&gt;Not for now, for sure. I spend a lot of time coding, and being a GDE and other community activities I do, help with that. I see myself coding for a very long time, and my new focus only adds value.&lt;/p&gt;

&lt;h2&gt;
  
  
  Finally
&lt;/h2&gt;

&lt;p&gt;Another very important skill is the one of receiving feedback and acting upon it. If you want to become a great architect, find people that have been doing the job for a long time (this is valid for any profession, of course) and ask them for feedback and mentorship. Ask them to assign you tasks in areas where they see you're the weakest, so you have the chance to gain experience. &lt;/p&gt;

&lt;p&gt;And...enjoy the ride!&lt;/p&gt;

&lt;p&gt;PS: Thanks to Mario, Ina, Conrad, Tomasz, Andreas and Georg, who have been those mentors for me, from infrastructure, to architecture to soft-skills.&lt;/p&gt;

</description>
      <category>career</category>
      <category>webdev</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Can you become a successful software developer without a CS degree? My opinion</title>
      <dc:creator>Natalia Venditto</dc:creator>
      <pubDate>Mon, 21 Dec 2020 07:56:38 +0000</pubDate>
      <link>https://dev.to/playfulprogramming/can-you-become-a-successful-software-developer-without-a-cs-degree-my-opinion-27om</link>
      <guid>https://dev.to/playfulprogramming/can-you-become-a-successful-software-developer-without-a-cs-degree-my-opinion-27om</guid>
      <description>&lt;p&gt;Last week I read a few tweets that really caught my attention. Most of them targeted the 'anti-academia' movement.&lt;/p&gt;

&lt;p&gt;It is not the first time I read some people are anything between skeptical to angry about those who say that you can have a successful career in tech without a CS degree, but these concrete tweets caught my attention because I never knew this particular 'anti-academia' movement existed, and I still have not come across a statement such as 'You should never go to the University!'.&lt;/p&gt;

&lt;p&gt;Although maybe such statements exist and are public out there even as tweets, they never reached me in my feed. Or I never read them. &lt;/p&gt;

&lt;p&gt;What I have read, unfortunately, are snark comments and dismissive remarks, ridiculing people who work in the tech industry without a CS degree, and saying things like "you can do websites, but cannot work on more complex stuff, like diagnose and disease detection software", or even remarks like "yeah, next thing is becoming a doctor without a CS degree. pffft!"&lt;/p&gt;

&lt;p&gt;As a successful software architect without a CS degree, I finally felt like it was a good time to share my opinion.&lt;/p&gt;

&lt;p&gt;After all, I have more than once encouraged people to transition from a different career background or no career background at all, to find new opportunities as developers. Just thinking that they may discouraged by a (sometimes) more privileged group of people for making a late-career choice, or for being unable to afford university education and deciding to get there following a different path, is heartbreaking to me.&lt;/p&gt;

&lt;h2&gt;
  
  
  Debunking some myths
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;First of all, I want to put things into perspective. People who become successful in tech, without a CS degree, are usually far from less intelligent, or too lazy to put the effort.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;People who become successful in tech without a CS degree, usually&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;but not always, have completed university education in another field&lt;/li&gt;
&lt;li&gt;always have spent an exponentially greater amount of time in self-teaching, including using online available resources and contributing to open-source communities, than those who do have a degree, before they get their first role in tech&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;People who have not attained a CS degree, but still have become successful in tech usually&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;but not always, have had to postpone or drop their education because of financial, health-related, or other personal reasons&lt;/li&gt;
&lt;li&gt;but not always, would've loved and would still love to complete their education, even when they're consolidated professionals&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I would say that in 90% of the cases if they would be given the chance, they would attempt at completing their university education and getting a CS degree, which is incompatible with being part of an 'anti-academia' movement.&lt;/p&gt;

&lt;h2&gt;
  
  
  How is it better to have a computer sciences degree than not?
&lt;/h2&gt;

&lt;p&gt;Let me elaborate my opinion. People who do have a university degree in computer sciences, while still studying, usually&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;learn foundational or low-level concepts in a structured way, which is very important to understand high-level concepts&lt;/li&gt;
&lt;li&gt;but not always, have access to a tutor or professor, to dissipate their doubts and help them apply the newly learned concepts&lt;/li&gt;
&lt;li&gt;but not always, do not need to spend personal time finding the right learning resources, since they're provided&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Also once they've attained their degree, they usually&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;almost always have more opportunities to be hired, since lots of companies have it as a hard-requirement &lt;/li&gt;
&lt;li&gt;always are less prone to be immediately discarded by recruiters, upon sending their CV, for not meeting this particular requirement&lt;/li&gt;
&lt;li&gt;almost always have more career progression opportunities&lt;/li&gt;
&lt;li&gt;but not always, are paid more than their counterparts that do exactly the same job, but do not have the CS degree&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Can we compare studying to be a doctor to studying to be a software engineer?
&lt;/h2&gt;

&lt;p&gt;No. And why?&lt;/p&gt;

&lt;p&gt;One of my siblings is a doctor, so my opinions are shaped by my experience of living with her, as she was studying. In Uruguay people don't go to Campuses. They stay home while they study, especially if they live in the capital city, Montevideo.&lt;/p&gt;

&lt;h3&gt;
  
  
  Let's talk about sources
&lt;/h3&gt;

&lt;p&gt;The source of anatomy and pathologies knowledge for doctors, historically and from centuries, has always been actual, real, living and dead human bodies.  I will not share details on how those doctors close to me dissected human parts on the same table I was having my meals. Well, ok, I guess that's enough detail. And yes, that happened. Those body-parts, unique and ultimate source of knowledge to understand anatomy and pathologies, were obviously provisioned by the university. &lt;/p&gt;

&lt;p&gt;Let me begin by sharing with you my opinion that probably the doctors you would like being diagnosed and treated by if you had anything serious, are the ones that have the most amount of clinic practice and not those that are university professors, and rely almost only on theoretical knowledge.&lt;/p&gt;

&lt;p&gt;Clinic practice is obviously not something you can teach on youtube. It would be unethical because you would have to disclose private information about a human being. It is unlikely anyone wants to visit a doctor that streams on Twitch as they perform you a colonoscopy or explores your naked body. &lt;/p&gt;

&lt;p&gt;I know there are a couple of reality shows that feature this, but it is a very extreme exception.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Unlike the act of exploring a human patient, diagnosing them and treating them (which by the way also involves laboratories for analysis with expensive equipment not available to doctors at home while they Twitch, and prescriptions of law regulated medicines), building and diagnosing computer systems and programs in front of everyone else is a lot simpler, cheaper, and ethically acceptable.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Do I think a person could become a good, self-trained doctor if all the bibliography used by doctors was open-sourced, made available from online repositories, and doctors live-streamed their practice with patients (and body-parts) and people put the same amount of time they sometimes put to become developers? Possibly. But my guess is that, because of the ethical implications and obvious other legal issues, that will never happen.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;However, even the most obscure and in-depth details about computer sciences, are available to everyone online, already.&lt;/strong&gt; &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Conclusion or tl;dr
&lt;/h2&gt;

&lt;p&gt;Should you study at the University to learn computer sciences and get a degree? My humble opinion is that, if you can afford it, money-wise and time-wise, is: YES! Go for it!&lt;/p&gt;

&lt;p&gt;But if you did not have the chance, or don't see that chance for you in the future, should you desist from the dream of being a successful, self-taught software developer? The answer is: NO! Go for it! &lt;/p&gt;

</description>
      <category>webdev</category>
      <category>healthydebate</category>
      <category>career</category>
    </item>
    <item>
      <title>Micro frontends: my lessons learned</title>
      <dc:creator>Natalia Venditto</dc:creator>
      <pubDate>Fri, 18 Dec 2020 15:26:14 +0000</pubDate>
      <link>https://dev.to/playfulprogramming/micro-frontends-my-lessons-learned-1pcp</link>
      <guid>https://dev.to/playfulprogramming/micro-frontends-my-lessons-learned-1pcp</guid>
      <description>&lt;p&gt;Hello there!&lt;/p&gt;

&lt;p&gt;For the past 6 months at work, I have been busy analyzing, experimenting, testing and sometimes suffering, while exploring the depths, the benefits, the cons of micro frontends as an architecture decision. &lt;/p&gt;

&lt;p&gt;All I am going to describe, and all the opinions I will express, come from in depth-analysis and code that was shipped to production. I am not positioned in any place, with respect to micro frontends. Simply because it is my firm belief, that software architecture solutions are always good, when you have the problem they solve (hence, solution!) and always bad, when you don't and you're following trends for the mere wish to integrate innovations your software does not need. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The key is to use architecture patterns when really needed, and not to follow a trend or because the buzzword sounds good. There are very valid use cases for micro frontends, where they are probably the best solution.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This post is long, so grab a coffee, a tea or read it in parts.&lt;/p&gt;

&lt;h2&gt;
  
  
  When do micro frontends originate?
&lt;/h2&gt;

&lt;p&gt;Micro frontends are the frontend analog to micro services in the backend.&lt;/p&gt;

&lt;p&gt;Basically, a few years ago, with the explosion of digital transformation (enterprises, especially large organizations migrating to the web to operate their business), web software systems started growing larger and larger into huge monoliths that comprehended it all.&lt;/p&gt;

&lt;p&gt;At some point, that architecture started bloating and smelling, and architects and developers came up with diverse approaches and strategies to break apart the code and the teams, and have dedicated release cycles.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fjdg0no0n9ns264giqz5i.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fjdg0no0n9ns264giqz5i.jpg" alt="microservices" width="676" height="384"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Monoliths are not always necessarily bad, but sometimes they're hard to manage
&lt;/h2&gt;

&lt;p&gt;When you have a very large system, and its pieces are very tightly coupled, meaning they're very inter-dependent, whatever change, upgrade, update, fix, etc you make to one part, however small it may be, requires you to release the whole monolith to a higher version. That affects also whatever depends on parts of your monolith, too, like sub-projects.&lt;/p&gt;

&lt;p&gt;Even when using semantic versioning for dependencies, even when modularizing, and even if we were breaking teams apart to give them ownership of certain parts, developing an maintaining a large coupled system is a very challenging task. &lt;/p&gt;

&lt;p&gt;Those are the fundamental reasons behind a micro-services architecture type: the wish to split apart large systems in a way that every component, and the team in charge, is independent in many areas&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;technologies&lt;/li&gt;
&lt;li&gt;lifecycles&lt;/li&gt;
&lt;li&gt;processes&lt;/li&gt;
&lt;li&gt;operations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Especially in combination with event driven strategies, API first concepts and cloud platforms, micro-services have demonstrated to solve some of the afore mentioned problems, while introducing their own, due to the need for complex and well designed orchestration, for example.&lt;/p&gt;

&lt;h2&gt;
  
  
  Micro-services in the frontend
&lt;/h2&gt;

&lt;p&gt;If splitting apart the backend was successful why not the frontend?&lt;/p&gt;

&lt;p&gt;Actually the split in the backend, with dedicated teams to cover a feature or service, demanded we took our own measures in the frontend.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F7enipadve7ev1ml7lo74.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F7enipadve7ev1ml7lo74.jpg" alt="microfrontends" width="663" height="377"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If we really wanted to make sure those components were completely independent, there was no other way around it, anyway. And that was the birth of micro frontends.&lt;/p&gt;

&lt;h2&gt;
  
  
  Micro applications
&lt;/h2&gt;

&lt;p&gt;In all honestly, in enterprise, it is not something new. We have been doing this for years. &lt;/p&gt;

&lt;p&gt;There are two ways in which we do this, we have a Single Page Application per hyperlink or url, or we embed a fully functional micro application in a page region, typically using an iframe.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Feq2p62fyhzkx00s1j2mw.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Feq2p62fyhzkx00s1j2mw.jpg" alt="microapps" width="582" height="331"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The pros for this approach are
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;the team developing the app can be fully independent, choosing their own technologies and cycles&lt;/li&gt;
&lt;li&gt;the app is fully encapsulated in the iframe, thus not interfering with the javascript or css of the host&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The cons are
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;if there is more than one instance of micro-app initializing in a page (or route) the impact on performance can be really high, and there is likely a duplication of dependencies, since shared assets like styles or fonts, cannot be shared between the host and app&lt;/li&gt;
&lt;li&gt;if the apps are integrated in the build system, there may be a chance to share certain dependencies, and even exercise some code-splitting/tree-shaking, however, but teams would lose independence, since they're bound to the cycles of the system where the build process is at&lt;/li&gt;
&lt;li&gt;routing can become very complex, especially if the navigation tree is very deep&lt;/li&gt;
&lt;li&gt;UX consolidation will be challenging. Aspects like localization, internationalization, and preservation of unified styles, will demand more efforts, alignments, or a very well documented style-guide&lt;/li&gt;
&lt;li&gt;if integrated via an iframe, you will need additional code to handle iframe resize. because iframe is completely encapsulated, you won't be able to share any assets&lt;/li&gt;
&lt;li&gt;if integrated via an iframe, additional measures for SEO and A11y will need to be taken&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Does not change
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;if you're consuming a bundled app, you would still need to update your main system dependency version and that little change demands a release, before you could see any updates made by an independent team to a micro app&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Web Components
&lt;/h2&gt;

&lt;p&gt;Another popular, yet less proven(*) way of integrating micro frontends, are via the web components W3C Standard. For those that are new to web development or never heard about them, web components are a web standard that allows the generation of custom elements (as in custom HTML elements) that via the DOM, have properties either custom or inherited from the HTMLElement (or whatever element class extended) parent.&lt;/p&gt;

&lt;p&gt;It is possible to bootstrap a javascript framework on top of the Web Component, as well. There are many libraries that support extended functionality and also provide the necessary polyfills to make sure the Web Components are supported across browsers. As you can imagine, like with any W3C specification, it gets fully supported overtime, and customElement, Shadow DOM API, etc, as part of Web Components, are only somewhat there.&lt;/p&gt;

&lt;p&gt;(&lt;em&gt;) *When I say less proven, I mean that there are less records of this pattern successfully used in large enterprise production systems&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The pros of web components
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;web components are more or less encapsulated depending on if Shadow DOM is used or not. That I have to say may be both a pro or a con, it depends on your use-case.&lt;/li&gt;
&lt;li&gt;when less encapsulated, web components can leverage common assets, which makes it easier to achieve a more integrated user experience, and consistent look and feel, especially for corporate identity&lt;/li&gt;
&lt;li&gt;having the ability to consume commons and shared code, reduces the amount of data shipped over the wire, and prevents duplicates, which enhances performance at runtime&lt;/li&gt;
&lt;li&gt;SEO and Accessibility are treated as they are for any HTML subpart, so no additional efforts, there&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cons of web components
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;if you have to give support to very old browsers, expect having to ship additional code to polyfill them&lt;/li&gt;
&lt;li&gt;if the teams behind each component are independent and they can make their own choices, can you foresee the impact on performance of bootstrapping and initializing multiple frameworks in a page? &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fufqp7o5fg0kkzyomoopv.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fufqp7o5fg0kkzyomoopv.jpg" alt="several frameworks initialized on a page" width="727" height="413"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fowkdj62l9qtom7rvn8w4.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fowkdj62l9qtom7rvn8w4.gif" alt="Distaster" width="350" height="250"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Does not change
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;same as with micro apps &lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;if you're consuming a bundled app, you would still need to update your main system dependency version and that little change demands a new build, release and deploy, before you could see any updates made by an independent team to the web component bundle&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Orchestration, or bringing the whole micro parts together
&lt;/h2&gt;

&lt;p&gt;It doesn't matter if your micro parts are standalone web components or micro applications, you will need to bring all that together, somehow.&lt;/p&gt;

&lt;p&gt;That is only possible if you define a team in charge, exclusively, of what we will call &lt;strong&gt;'the host'&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In large enterprise systems, the host is usually a CMS plus a large infrastructure, to support it. The team managing the host, should probably be in charge of the orchestration and composition, and make possible the following aspects&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;configuration for initialization (especially authored!)&lt;/li&gt;
&lt;li&gt;routing&lt;/li&gt;
&lt;li&gt;communication between components&lt;/li&gt;
&lt;li&gt;state management&lt;/li&gt;
&lt;li&gt;providing commons/shared code&lt;/li&gt;
&lt;li&gt;availability of any other user-triggered event-based API's&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Make it event-driven!
&lt;/h2&gt;

&lt;p&gt;Does not matter if you're integrating micro frontends as micro apps in an iframe or web components, or even ES imports into a much larger application, a key part of preserving a good user experience is about making sure that all components can talk to each other. You can do that by using a publication/subscription mechanism strategy, like for example &lt;a href="https://github.com/mroderick/PubSubJS" rel="noopener noreferrer"&gt;this one&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Publication/Subscription works in a very easy way. You publish a topic, and everyone listening or subscribed will react in any way you determine, to that publication. It is a great mechanism to use for micro frontends, because the publisher of the message or topic, does not need to know about the listeners. However, keep in mind that the subscribers, obviously do need to know the topic they need to subscribe to.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fo8lv6b4l6ptec611yes0.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fo8lv6b4l6ptec611yes0.jpg" alt="pub sub mechanisms" width="727" height="413"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are very, very light weight libraries to accomplish this and if we're bootstrapping a framework, it probably has its own preferred technology or recommended pattern. &lt;/p&gt;

&lt;h2&gt;
  
  
  But if you are bootstrapping different frameworks...
&lt;/h2&gt;

&lt;p&gt;That's again when it gets messy! If you're bootstrapping different frameworks, all of which come with their own state management pattern and flavour, combining them may be especially challenging.&lt;/p&gt;

&lt;p&gt;Each one will define its own store, and we will have to come up with ways to synchronise them. In my opinion, it defeats the purpose of a single source of truth, and I am not sure to buy into it. Even though we have effectively integrated Vuex and Redux store in very large applications, it is by no means an easy task.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Combining multiple state management patterns defeats the purpose of having a single source of truth, or unique store&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is something very important to keep in mind if you're stitching together multiple parts, and you're dealing with user authentication/authorization, etc.&lt;/p&gt;

&lt;h2&gt;
  
  
  Consistency in reactivity to browser native controls
&lt;/h2&gt;

&lt;p&gt;This aspect is also essential. Having multiple micro parts behaving differently with respect to browser API's, like history, could confuse the user and lead to a very poor experience. It is very likely that each team should make sure every component posts their history state on state change. &lt;/p&gt;

&lt;p&gt;Bookmarking may also become a challenge. Usually the user wants to bookmark a route, or the page in a specific state. If you're combining micro frontends in different technologies, this can become arduous. &lt;/p&gt;

&lt;h3&gt;
  
  
  Relying on Web API's will be helpful
&lt;/h3&gt;

&lt;p&gt;Modern, evergreen browsers, offer a myriad of API's that you not only can but should leverage, in order to execute composition. Even when, again, not all browsers may support all API's, or some only offer partial support, they can be extremely useful in reducing development efforts and abstraction around composition, and using methods globally available.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fx12ekv4he6oczi1vriw4.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fx12ekv4he6oczi1vriw4.jpg" alt="web or browser APIs" width="727" height="413"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Some of the most useful API's and interfaces for micro frontends composition, are these&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mutation Observer&lt;/li&gt;
&lt;li&gt;Intersection Observer&lt;/li&gt;
&lt;li&gt;History&lt;/li&gt;
&lt;li&gt;Channel Messaging&lt;/li&gt;
&lt;li&gt;Drag and Drop&lt;/li&gt;
&lt;li&gt;Picture-in-Picture&lt;/li&gt;
&lt;li&gt;Push API(^)&lt;/li&gt;
&lt;li&gt;Service Workers and WebSockets&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;and of course, all the client-side storage mechanisms, and the Cache(^)&lt;/p&gt;

&lt;p&gt;(^) &lt;em&gt;These are still experimental&lt;/em&gt; and you can find them all &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The testing part
&lt;/h2&gt;

&lt;p&gt;Testing a micro frontend component individually should be the responsibility of the team that owns it, that's clear. But if you're integrating it in a page, and again, you want it to communicate and sync state with other parts of that page, you also need to test that aggregation.&lt;/p&gt;

&lt;p&gt;It is by no means easy to design automated tests for items that are in a black box to you. So expect that part to be, if not a problem, another challenge.&lt;/p&gt;

&lt;h2&gt;
  
  
  So you're not recommending micro frontends?
&lt;/h2&gt;

&lt;p&gt;Again, no. That's not what I imply. I believe that micro frontends are the way to go, especially under these conditions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;you have to integrate development by teams that work in a different context (external repos, different organizations, etc)&lt;/li&gt;
&lt;li&gt;each part has very different cycles (like feature A needs daily releases and feature B may get some maintenance), and you don't want to redeploy the whole system because of a stitch in a single (or several, yet minimal) feature(s)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  And to make it possible you, need...
&lt;/h3&gt;

&lt;p&gt;...at minimum&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a very solid event driven strategy&lt;/li&gt;
&lt;li&gt;a team in charge of the orchestration, routing, and commons&lt;/li&gt;
&lt;li&gt;a very well documented and defined style-guide&lt;/li&gt;
&lt;li&gt;a performance budget, and mechanisms in place to accelerate load (particularly perceived load).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  And specifically in the enterprise world?
&lt;/h2&gt;

&lt;p&gt;In my opinion, micro frontends architecture works extremely well for products. &lt;/p&gt;

&lt;p&gt;Imagine you own an application with several different features. Let's imagine it's a search engine. You could break it down like this, into components, in the frontend:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the form elements (input, button, checkbox, radio-button, etc)&lt;/li&gt;
&lt;li&gt;the atomic text elements (link, label, description)&lt;/li&gt;
&lt;li&gt;image&lt;/li&gt;
&lt;li&gt;teaser&lt;/li&gt;
&lt;li&gt;pagination&lt;/li&gt;
&lt;li&gt;lazy loading mechanism (for images and infinite scroll or load more)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You'd need a service in the backend to run the queries against an index, and return the results.&lt;/p&gt;

&lt;p&gt;Of course there should be a (frontend) build system, a state management system or pub/sub module, a unified API/service to run queries from the frontend.&lt;/p&gt;

&lt;p&gt;With them you could compose the search box, the facets or filters, the search results, the related results, the featured results, and even customized suggestions, combined with an analytics or target layer.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What I feel is the most important, is that everyone of those features map to a business capability or domain&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You could easily form clusters and assign each one of those clusters to an independent team. &lt;/p&gt;

&lt;p&gt;It is very likely you'd want the users to login, to save their queries. You'd have a team dealing with authentication and authorization, and they'd also use components from the other teams. (form elements, etc).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fgmk51xn6nxvlv01wv2ez.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fgmk51xn6nxvlv01wv2ez.jpg" alt="a search page" width="582" height="331"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All those teams would still work with the guidance of a style system, to preserve UX and the identity of your product.&lt;/p&gt;

&lt;h2&gt;
  
  
  But what about the enterprise website context?
&lt;/h2&gt;

&lt;p&gt;But enterprise sites are usually less of a product, and more of a composition of components to create web pages, to provide information of or acquire products and services.&lt;/p&gt;

&lt;p&gt;Although you can very much assign each component to a different team that owns it, it is highly unlikely teams are configured in a way that allows for this. And that the business strategy backs up this split.&lt;/p&gt;

&lt;p&gt;Usually teams working in enterprise sites are not that large that you could put together a fully cross-functional team in charge of smaller features. And even if they were, sometimes it would not make sense.&lt;/p&gt;

&lt;p&gt;Oftentimes websites have a single business unit behind it. They advertise or commercialize a product or service, and all the components are tightly coupled, technically, and strategically.&lt;/p&gt;

&lt;p&gt;There may be exceptions to the rule. And there are services that you can still break apart from the whole, and assign to independent teams to own, like we mentioned before, user management, or even the search mechanism as we suggested.&lt;/p&gt;

&lt;p&gt;But it is more likely that enterprise platforms have a repository or library of components, used across many sites. And that the image component used in the search feature, is exactly the same than the one used in other places/components/modules/templates. All components are then equivalently important for the business stakeholder behind the site.&lt;/p&gt;

&lt;h2&gt;
  
  
  A really valid use case in enterprise
&lt;/h2&gt;

&lt;p&gt;And that's the case when you have to integrate micro parts that are developed by remote teams. I don't want to use the term 'independent', because I still believe 100% independent is not going to help your UX and your performance. You will still want your corporate identity in the form of consistent UI/UX, to be preserved. You will still want state coherence and synchronization and communication between components of a page. You will still want to make sure you have a certain consolidation in the choice of technologies, to prevent collisions and performance degradation.&lt;/p&gt;

&lt;p&gt;You will still want some decision matrix to rule and govern. As a Frontend Architect, concerned about performance, I wouldn't want to have Angular 9, 10 and 11, Vue 2 and 3 and React components initializing in a web page, requesting their myriad of accessories, and crashing the user experience (and the page!).&lt;/p&gt;

&lt;p&gt;So the idea of having 100% independent, isolated teams, does not seem really feasible to me, in this context. &lt;/p&gt;

&lt;p&gt;But the case of a team working in a really isolated feature, for sure merits independent release cycles, to avoid the need to rebuild and redeploy your whole monolith to pull a minor fix in a 3rd party component. &lt;/p&gt;

&lt;p&gt;To use that commodity, you need to implement Module Federation. And to read what I have learned about Module Federation, you will need to wait until my next post.&lt;/p&gt;

&lt;h2&gt;
  
  
  Decisions, decisions...
&lt;/h2&gt;

&lt;p&gt;These slides, from my talk at the HolyJS conference, offer a few graphics I created to aid with architecture decision making, based on the need for independent deploys or encapsulation, for example.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://slides.com/anfibiacreativa/micro-frontends/fullscreen" rel="noopener noreferrer"&gt;https://slides.com/anfibiacreativa/micro-frontends/fullscreen&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;being slides, 34, 35 and 52 to 56. If you're anywhere in the yellow areas, you may want to consider not using micro frontends.&lt;/p&gt;

&lt;p&gt;Edit: You can compliment the reading, hearing me discuss the topic with John Papa, Ward Bell, Dan Wahlin and Craig Shoemaker at their podcast &lt;a href="https://webrush.io/episodes/episode-113-micro-front-ends-with-natlia-venditto" rel="noopener noreferrer"&gt;https://webrush.io/episodes/episode-113-micro-front-ends-with-natlia-venditto&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Have a wonderful holiday season, folk! &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fci364a9xidbn0jjttbtc.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fci364a9xidbn0jjttbtc.jpg" alt="merry js christmas" width="727" height="413"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>microservices</category>
      <category>frontend</category>
      <category>microfrontends</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Angular Schematics from 0 to publishing your own library (I)</title>
      <dc:creator>Natalia Venditto</dc:creator>
      <pubDate>Sun, 16 Aug 2020 18:43:07 +0000</pubDate>
      <link>https://dev.to/anfibiacreativa/angular-schematics-from-0-to-publishing-your-own-library-i-1b3b</link>
      <guid>https://dev.to/anfibiacreativa/angular-schematics-from-0-to-publishing-your-own-library-i-1b3b</guid>
      <description>&lt;p&gt;This is a series of posts, that, if you follow through, will help you acquire the necessary knowledge to write your first schematics and even publish them to npm with ng-add support!&lt;/p&gt;

&lt;p&gt;Let's start!&lt;/p&gt;

&lt;h2&gt;
  
  
  What are schematics, you ask?
&lt;/h2&gt;

&lt;p&gt;Schematics are code generators based on descriptive code. Basically, you write some descriptions of what you need and artifacts are generated. Those artifacts could be more code, templates, etc&lt;/p&gt;

&lt;h2&gt;
  
  
  What problems can I solve with schematics?
&lt;/h2&gt;

&lt;p&gt;With Schematics you will be able to automate a lot of tasks across your projects or organization, allowing you to establish patterns and enforce best practices.&lt;/p&gt;

&lt;p&gt;You will become more productive and reduce manual tasks, especially those around setup.&lt;/p&gt;

&lt;p&gt;You won't need to write or read so much documentation!&lt;/p&gt;

&lt;p&gt;Additionally, if you write a library, you will automate steps to have it working, which makes it more attractive to other developers, that do not need to perform them every time they install it.&lt;/p&gt;

&lt;p&gt;In short, Schematics help with&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;structure standardization&lt;/li&gt;
&lt;li&gt;enforcing patterns&lt;/li&gt;
&lt;li&gt;enforcing best practices&lt;/li&gt;
&lt;li&gt;enforcing naming conventions&lt;/li&gt;
&lt;li&gt;reuse implementations&lt;/li&gt;
&lt;li&gt;automate tasks&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Main advantages of Schematics
&lt;/h2&gt;

&lt;p&gt;So schematics as code and other artifacts generators help us setup and configure a new project (or parts of it) in a standardized and automated way, with the following advantages&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;they're extensible and atomic&lt;/li&gt;
&lt;li&gt;they're safe and synchronous&lt;/li&gt;
&lt;li&gt;they're implemented in debug mode by default&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Extensible and atomic
&lt;/h3&gt;

&lt;p&gt;Schematics are organized in collections and can be combined or chained, but apply transformations in an atomic way&lt;/p&gt;

&lt;h3&gt;
  
  
  Safe and synchronous
&lt;/h3&gt;

&lt;p&gt;By being atomic, and because of their synchronous nature, Schematics are safe. They're executed one after another, which means errors are easily traceable. &lt;/p&gt;

&lt;h3&gt;
  
  
  Default debug mode
&lt;/h3&gt;

&lt;p&gt;When executed from the Schematics CLI, they're dry-run, which means that bt default, none of the transformations is really applied to the file system.&lt;/p&gt;

&lt;h2&gt;
  
  
  Important vocabulary
&lt;/h2&gt;

&lt;p&gt;It is difficult to learn Schematics without being familiar with its API and vocabulary first. Let's start with the vocabulary you will see in repeated over and over when we start the practical lessons.&lt;/p&gt;

&lt;h3&gt;
  
  
  Source, or ./files
&lt;/h3&gt;

&lt;p&gt;The Tree or source is the VIRTUAL tree composed by a base (files that actually do exist, and are identical to our file system's content) and the staging area (where all transformations are applied), plus some metadata necessary to work with all.&lt;/p&gt;

&lt;p&gt;For example, when we want our schematic to create new files in our system, we create a &lt;code&gt;/files&lt;/code&gt; folder at the root of our schematic, with contents identical to what we want to be replicated.&lt;/p&gt;

&lt;p&gt;We will call this folder &lt;code&gt;files&lt;/code&gt; simply because by default, the ts compiler will ignore this folder and never transpile it. If we want to call it something else, we need to configure the tsconfig.json file, to know that and exclude that folder.&lt;/p&gt;

&lt;h3&gt;
  
  
  Rule{}
&lt;/h3&gt;

&lt;p&gt;The Rule object defines a function that takes a tree as an argument and returns a new tree after all the transformations have been applied.&lt;/p&gt;

&lt;p&gt;We can also use Observables, and return the Observable of a Tree.&lt;/p&gt;

&lt;h3&gt;
  
  
  index.ts
&lt;/h3&gt;

&lt;p&gt;It's a Rule factory that acts as an entry point for our schematic. You find this file at the root of the schematic. It will always return a Rule.&lt;/p&gt;

&lt;p&gt;It runs always in a context, that provides the metadata and utilities (ie: logging), necessary.&lt;/p&gt;

&lt;h3&gt;
  
  
  SchematicContext
&lt;/h3&gt;

&lt;p&gt;This object represents the context in which the schematic runs, as explained before.&lt;/p&gt;

&lt;h3&gt;
  
  
  Action
&lt;/h3&gt;

&lt;p&gt;Action is the most atomic transformation you can apply to a tree.&lt;/p&gt;

&lt;h3&gt;
  
  
  collection.json
&lt;/h3&gt;

&lt;p&gt;A set of definitions for one or several schematics, where we find the declarations and values for the description, the path to the factory (or entry point for each schematic), the path to its validation schema (when it has one), and its aliases (when it has them)&lt;/p&gt;

&lt;h4&gt;
  
  
  Aliases
&lt;/h4&gt;

&lt;p&gt;Aliases are as expected, an alternative string you can all the schematic with, to invoke its execution.&lt;/p&gt;

&lt;p&gt;Each schematic may have one or several aliases.&lt;/p&gt;

&lt;p&gt;"aliases": ["alias"]&lt;/p&gt;

&lt;h3&gt;
  
  
  schema.json
&lt;/h3&gt;

&lt;p&gt;It's the validation schema for the schematic and its descriptor properties. It's optional, but recommended!&lt;/p&gt;

&lt;h3&gt;
  
  
  Options
&lt;/h3&gt;

&lt;p&gt;Configuration options you can pass to the schematic, for example --name&lt;/p&gt;

&lt;h3&gt;
  
  
  Prompts
&lt;/h3&gt;

&lt;p&gt;Prompts allow the schematic to interact with the user via the CLI. They're part of the schema.json&lt;/p&gt;

&lt;h2&gt;
  
  
  The virtual tree
&lt;/h2&gt;

&lt;p&gt;The virtual tree is an abstraction of the file system of the project we want to transform, consisting of the base (the existing files), a staging area where the actions to applied (transformations) are applied, and the metadata derived of the context.&lt;/p&gt;

&lt;h3&gt;
  
  
  Important!
&lt;/h3&gt;

&lt;p&gt;It is very important to understand that the transformations applied do not really modify the base directly! They're applied to the files in the staging area.&lt;/p&gt;

&lt;p&gt;To understand this concept, you can think of git, and how every diff, every modification you do of a file, is not really effective unless you commit it to the index. And it does not really affect the upstream unless you push it and merge it!&lt;/p&gt;

&lt;p&gt;In schematics, it works like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EDSDr2pl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/anfibiacreativa/image/upload/v1597346727/taller-schematics/Edit__De_0_a_crear_tu_publicar_tu_propia_libreri%25CC%2581a__con_Angular_Schematics_akcjef.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EDSDr2pl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/anfibiacreativa/image/upload/v1597346727/taller-schematics/Edit__De_0_a_crear_tu_publicar_tu_propia_libreri%25CC%2581a__con_Angular_Schematics_akcjef.jpg" alt="Tansformations applied in the staging area, schematics" title="Transformations applied in the staging area, schematics" width="800" height="463"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Actions
&lt;/h2&gt;

&lt;p&gt;All transformations applied to a tree are essentially atomic actions.&lt;/p&gt;

&lt;p&gt;These actions have four main types: CreateFileAction, DeleteFileAction, OverwriteFileAction, RenameFileAction&lt;/p&gt;

&lt;p&gt;You can find the actual implementation for each action type, exploring &lt;/p&gt;

&lt;p&gt;&lt;a href="//node_modules/@angular-devkit/schematics/src/tree/action.js"&gt;Implementación action.js&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Until here, a bit of theory. We will dive a bit deeper in the API, in the next post!&lt;/p&gt;

&lt;p&gt;EDIT: The rest of this series are being published in indepth.dev &lt;br&gt;
Please go here to continue reading! -&amp;gt; &lt;a href="https://indepth.dev/angular-schematics-from-0-to-publishing-your-own-library-i/"&gt;https://indepth.dev/angular-schematics-from-0-to-publishing-your-own-library-i/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>angular</category>
      <category>schematics</category>
      <category>javascript</category>
      <category>node</category>
    </item>
  </channel>
</rss>
