[{"data":1,"prerenderedAt":3901},["ShallowReactive",2],{"post-hexagonal-architecture":3,"rel-hexagonal-architecture":688,"sib-hexagonal-architecture":3829},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":8,"date":9,"layout":10,"subtitle":11,"image":12,"optimized_image":12,"category":13,"tags":14,"author":17,"paginate":6,"body":18,"_type":682,"_id":683,"_source":684,"_file":685,"_stem":686,"_extension":687},"/posts/hexagonal-architecture","posts",false,"","Introduction to Hexagonal Architecture","2023-10-02 18:00:00","post","A brief introduction","/assets/img/uploads/hexagonal-architecture.jpeg","code",[13,15,16],"java","architecture","jaimedearcos",{"type":19,"children":20,"toc":672},"root",[21,29,36,56,61,86,91,103,119,125,130,183,189,194,201,206,230,235,241,246,269,274,280,285,535,540,611,616,622,627,661,666],{"type":22,"tag":23,"props":24,"children":25},"element","p",{},[26],{"type":27,"value":28},"text","In the world of software development, architectural patterns play a pivotal role in creating robust, maintainable, and flexible systems. One such architectural pattern that has gained popularity in recent years is Hexagonal Architecture. In this article, we will delve into the fundamentals of Hexagonal Architecture, explore its advantages, and illustrate how to structure packages in a Java project following this architectural style.",{"type":22,"tag":30,"props":31,"children":33},"h2",{"id":32},"what-is-hexagonal-architecture",[34],{"type":27,"value":35},"What is Hexagonal Architecture?",{"type":22,"tag":23,"props":37,"children":38},{},[39,41,47,49,54],{"type":27,"value":40},"Hexagonal Architecture, also known as ",{"type":22,"tag":42,"props":43,"children":44},"strong",{},[45],{"type":27,"value":46},"Ports and Adapters",{"type":27,"value":48}," or the ",{"type":22,"tag":42,"props":50,"children":51},{},[52],{"type":27,"value":53},"Onion Architecture",{"type":27,"value":55},", is a design pattern that promotes the separation of concerns and modularization in software systems. It was first introduced by Alistair Cockburn in 2005. At its core, Hexagonal Architecture revolves around the idea of isolating the core business logic from external dependencies and infrastructure concerns.",{"type":22,"tag":23,"props":57,"children":58},{},[59],{"type":27,"value":60},"The central concept of Hexagonal Architecture is the division of an application into two main parts:",{"type":22,"tag":62,"props":63,"children":64},"ol",{},[65,76],{"type":22,"tag":66,"props":67,"children":68},"li",{},[69,74],{"type":22,"tag":42,"props":70,"children":71},{},[72],{"type":27,"value":73},"Core Business Logic",{"type":27,"value":75},": This is the heart of the application where the domain-specific rules and functionality reside. It should be completely isolated from any external factors like databases, user interfaces, or third-party services.",{"type":22,"tag":66,"props":77,"children":78},{},[79,84],{"type":22,"tag":42,"props":80,"children":81},{},[82],{"type":27,"value":83},"External Interfaces",{"type":27,"value":85},": These are the entry points and exit points to the application. They include adapters that communicate with the external world, such as REST APIs, databases, UI frameworks, and messaging systems.",{"type":22,"tag":23,"props":87,"children":88},{},[89],{"type":27,"value":90},"The goal of Hexagonal Architecture is to ensure that changes in the external interfaces (adapters) do not impact the core business logic, and vice versa. This separation enables better testability, maintainability, and scalability of your software.",{"type":22,"tag":23,"props":92,"children":93},{},[94,99],{"type":22,"tag":95,"props":96,"children":98},"img",{"alt":7,"src":97},"https://miro.medium.com/v2/resize:fit:1400/format:webp/1*ebUHgG6JwawEifXlARgfzg.png",[],{"type":22,"tag":100,"props":101,"children":102},"em",{},[],{"type":22,"tag":104,"props":105,"children":106},"center",{},[107],{"type":22,"tag":100,"props":108,"children":109},{},[110,112],{"type":27,"value":111},"source: ",{"type":22,"tag":113,"props":114,"children":116},"a",{"href":115},"https://blog.devgenius.io/flask-blog-tutorial-with-hexagonal-architecture-part-1-6446e7e9aaaa",[117],{"type":27,"value":118}," medium.com",{"type":22,"tag":30,"props":120,"children":122},{"id":121},"advantages-of-hexagonal-architecture",[123],{"type":27,"value":124},"Advantages of Hexagonal Architecture",{"type":22,"tag":23,"props":126,"children":127},{},[128],{"type":27,"value":129},"Utilizing Hexagonal Architecture offers several advantages:",{"type":22,"tag":62,"props":131,"children":132},{},[133,143,153,163,173],{"type":22,"tag":66,"props":134,"children":135},{},[136,141],{"type":22,"tag":42,"props":137,"children":138},{},[139],{"type":27,"value":140},"Modularity",{"type":27,"value":142},": The separation of concerns into core business logic and external interfaces makes it easier to maintain and extend your application. Changes in one part of the system have minimal impact on the other.",{"type":22,"tag":66,"props":144,"children":145},{},[146,151],{"type":22,"tag":42,"props":147,"children":148},{},[149],{"type":27,"value":150},"Testability",{"type":27,"value":152},": Isolating the core logic allows for comprehensive unit testing without the need for complex mocking of external dependencies.",{"type":22,"tag":66,"props":154,"children":155},{},[156,161],{"type":22,"tag":42,"props":157,"children":158},{},[159],{"type":27,"value":160},"Flexibility",{"type":27,"value":162},": You can switch out external components (e.g., databases, UI frameworks) without affecting the core business logic. This adaptability is particularly beneficial when upgrading or changing technology stacks.",{"type":22,"tag":66,"props":164,"children":165},{},[166,171],{"type":22,"tag":42,"props":167,"children":168},{},[169],{"type":27,"value":170},"Clean Code",{"type":27,"value":172},": Hexagonal Architecture encourages clean and organized code. It promotes the use of interfaces and clear boundaries between components, making the codebase more understandable.",{"type":22,"tag":66,"props":174,"children":175},{},[176,181],{"type":22,"tag":42,"props":177,"children":178},{},[179],{"type":27,"value":180},"Business Focus",{"type":27,"value":182},": Developers can focus on implementing business requirements without being distracted by technical details, resulting in a more business-centric codebase.",{"type":22,"tag":30,"props":184,"children":186},{"id":185},"ports-and-adapters-in-hexagonal-architecture",[187],{"type":27,"value":188},"Ports and Adapters in Hexagonal Architecture",{"type":22,"tag":23,"props":190,"children":191},{},[192],{"type":27,"value":193},"In Hexagonal Architecture, the concepts of \"Ports\" and \"Adapters\" play a central role in achieving its architectural goals. Let's take a closer look at what these terms mean:",{"type":22,"tag":195,"props":196,"children":198},"h3",{"id":197},"ports",[199],{"type":27,"value":200},"Ports",{"type":22,"tag":23,"props":202,"children":203},{},[204],{"type":27,"value":205},"Ports are interfaces or contracts that define the interactions between the core business logic of your application and the external world. They represent the entry points and exit points for data and functionality. In simpler terms, ports are the \"what\" your application needs from the outside world.",{"type":22,"tag":207,"props":208,"children":209},"ul",{},[210,220],{"type":22,"tag":66,"props":211,"children":212},{},[213,218],{"type":22,"tag":42,"props":214,"children":215},{},[216],{"type":27,"value":217},"Primary Ports (Inbound)",{"type":27,"value":219},": These are entry points for external interactions with your application. Examples include REST API endpoints, command handlers, or event listeners.",{"type":22,"tag":66,"props":221,"children":222},{},[223,228],{"type":22,"tag":42,"props":224,"children":225},{},[226],{"type":27,"value":227},"Secondary Ports (Outbound)",{"type":27,"value":229},": These are exit points through which your application interacts with external resources, such as databases, external services, or message queues. They define what your application provides to the external world.",{"type":22,"tag":23,"props":231,"children":232},{},[233],{"type":27,"value":234},"Ports are defined as Java interfaces, for example, in the context of Spring Boot, they can be defined as Spring beans, ensuring that the core business logic interacts with the external world through these well-defined interfaces.",{"type":22,"tag":195,"props":236,"children":238},{"id":237},"adapters",[239],{"type":27,"value":240},"Adapters",{"type":22,"tag":23,"props":242,"children":243},{},[244],{"type":27,"value":245},"Adapters, on the other hand, are responsible for implementing the ports and enabling communication between the core business logic and external resources. Adapters bridge the gap between the application's internal interfaces (ports) and the external technologies and systems.",{"type":22,"tag":207,"props":247,"children":248},{},[249,259],{"type":22,"tag":66,"props":250,"children":251},{},[252,257],{"type":22,"tag":42,"props":253,"children":254},{},[255],{"type":27,"value":256},"Primary Adapters (Inbound)",{"type":27,"value":258},": These are implementations of the primary ports, allowing external systems to communicate with your application. For example, a REST controller that handles HTTP requests and routes them to the application's use cases.",{"type":22,"tag":66,"props":260,"children":261},{},[262,267],{"type":22,"tag":42,"props":263,"children":264},{},[265],{"type":27,"value":266},"Secondary Adapters (Outbound)",{"type":27,"value":268},": These are implementations of the secondary ports, facilitating communication between your application and external resources. This could include database repositories, external API clients, or message queue consumers.",{"type":22,"tag":23,"props":270,"children":271},{},[272],{"type":27,"value":273},"Adapters are responsible for translating external input into a format understandable by the core business logic and vice versa. They ensure that the application remains isolated from the specifics of the external technologies it interacts with.",{"type":22,"tag":30,"props":275,"children":277},{"id":276},"structuring-a-spring-boot-project-with-hexagonal-architecture",[278],{"type":27,"value":279},"Structuring a Spring Boot Project with Hexagonal Architecture",{"type":22,"tag":23,"props":281,"children":282},{},[283],{"type":27,"value":284},"Now, let's explore how you can structure a Java (Spring Boot) project using Hexagonal Architecture. Here's an example structure:",{"type":22,"tag":286,"props":287,"children":291},"pre",{"className":288,"code":289,"language":290,"meta":7,"style":7},"language-css shiki shiki-themes github-dark github-light","myapp/\n├── src/\n│   ├── main/\n│   │   ├── java/\n│   │   │   ├── com/\n│   │   │   │   ├── myapp/\n│   │   │   │   │   ├── application/\n│   │   │   │   │   │   ├── MyApplication.java\n│   │   │   │   │   │   └── ...\n│   │   │   │   │   ├── domain/\n│   │   │   │   │   │   ├── MyEntity.java\n│   │   │   │   │   │   └── ...\n│   │   │   │   │   ├── ports/\n│   │   │   │   │   │   ├── MyRepository.java\n│   │   │   │   │   │   └── ...\n│   │   │   │   │   └── ...\n│   │   │   │   ├── infrastructure/\n│   │   │   │   │   ├── adapter/\n│   │   │   │   │   │   ├── MyRepositoryImpl.java\n│   │   │   │   │   │   └── ...\n│   │   │   │   │   ├── web/\n│   │   │   │   │   │   ├── MyController.java\n│   │   │   │   │   │   └── ...\n│   │   │   │   │   └── ...\n│   ├── resources/\n│   └── ...\n└── ...\n","css",[292],{"type":22,"tag":13,"props":293,"children":294},{"__ignoreMap":7},[295,306,315,324,333,342,351,360,369,378,387,396,404,413,422,430,439,448,457,466,474,483,492,500,508,517,526],{"type":22,"tag":296,"props":297,"children":300},"span",{"class":298,"line":299},"line",1,[301],{"type":22,"tag":296,"props":302,"children":303},{},[304],{"type":27,"value":305},"myapp/\n",{"type":22,"tag":296,"props":307,"children":309},{"class":298,"line":308},2,[310],{"type":22,"tag":296,"props":311,"children":312},{},[313],{"type":27,"value":314},"├── src/\n",{"type":22,"tag":296,"props":316,"children":318},{"class":298,"line":317},3,[319],{"type":22,"tag":296,"props":320,"children":321},{},[322],{"type":27,"value":323},"│   ├── main/\n",{"type":22,"tag":296,"props":325,"children":327},{"class":298,"line":326},4,[328],{"type":22,"tag":296,"props":329,"children":330},{},[331],{"type":27,"value":332},"│   │   ├── java/\n",{"type":22,"tag":296,"props":334,"children":336},{"class":298,"line":335},5,[337],{"type":22,"tag":296,"props":338,"children":339},{},[340],{"type":27,"value":341},"│   │   │   ├── com/\n",{"type":22,"tag":296,"props":343,"children":345},{"class":298,"line":344},6,[346],{"type":22,"tag":296,"props":347,"children":348},{},[349],{"type":27,"value":350},"│   │   │   │   ├── myapp/\n",{"type":22,"tag":296,"props":352,"children":354},{"class":298,"line":353},7,[355],{"type":22,"tag":296,"props":356,"children":357},{},[358],{"type":27,"value":359},"│   │   │   │   │   ├── application/\n",{"type":22,"tag":296,"props":361,"children":363},{"class":298,"line":362},8,[364],{"type":22,"tag":296,"props":365,"children":366},{},[367],{"type":27,"value":368},"│   │   │   │   │   │   ├── MyApplication.java\n",{"type":22,"tag":296,"props":370,"children":372},{"class":298,"line":371},9,[373],{"type":22,"tag":296,"props":374,"children":375},{},[376],{"type":27,"value":377},"│   │   │   │   │   │   └── ...\n",{"type":22,"tag":296,"props":379,"children":381},{"class":298,"line":380},10,[382],{"type":22,"tag":296,"props":383,"children":384},{},[385],{"type":27,"value":386},"│   │   │   │   │   ├── domain/\n",{"type":22,"tag":296,"props":388,"children":390},{"class":298,"line":389},11,[391],{"type":22,"tag":296,"props":392,"children":393},{},[394],{"type":27,"value":395},"│   │   │   │   │   │   ├── MyEntity.java\n",{"type":22,"tag":296,"props":397,"children":399},{"class":298,"line":398},12,[400],{"type":22,"tag":296,"props":401,"children":402},{},[403],{"type":27,"value":377},{"type":22,"tag":296,"props":405,"children":407},{"class":298,"line":406},13,[408],{"type":22,"tag":296,"props":409,"children":410},{},[411],{"type":27,"value":412},"│   │   │   │   │   ├── ports/\n",{"type":22,"tag":296,"props":414,"children":416},{"class":298,"line":415},14,[417],{"type":22,"tag":296,"props":418,"children":419},{},[420],{"type":27,"value":421},"│   │   │   │   │   │   ├── MyRepository.java\n",{"type":22,"tag":296,"props":423,"children":425},{"class":298,"line":424},15,[426],{"type":22,"tag":296,"props":427,"children":428},{},[429],{"type":27,"value":377},{"type":22,"tag":296,"props":431,"children":433},{"class":298,"line":432},16,[434],{"type":22,"tag":296,"props":435,"children":436},{},[437],{"type":27,"value":438},"│   │   │   │   │   └── ...\n",{"type":22,"tag":296,"props":440,"children":442},{"class":298,"line":441},17,[443],{"type":22,"tag":296,"props":444,"children":445},{},[446],{"type":27,"value":447},"│   │   │   │   ├── infrastructure/\n",{"type":22,"tag":296,"props":449,"children":451},{"class":298,"line":450},18,[452],{"type":22,"tag":296,"props":453,"children":454},{},[455],{"type":27,"value":456},"│   │   │   │   │   ├── adapter/\n",{"type":22,"tag":296,"props":458,"children":460},{"class":298,"line":459},19,[461],{"type":22,"tag":296,"props":462,"children":463},{},[464],{"type":27,"value":465},"│   │   │   │   │   │   ├── MyRepositoryImpl.java\n",{"type":22,"tag":296,"props":467,"children":469},{"class":298,"line":468},20,[470],{"type":22,"tag":296,"props":471,"children":472},{},[473],{"type":27,"value":377},{"type":22,"tag":296,"props":475,"children":477},{"class":298,"line":476},21,[478],{"type":22,"tag":296,"props":479,"children":480},{},[481],{"type":27,"value":482},"│   │   │   │   │   ├── web/\n",{"type":22,"tag":296,"props":484,"children":486},{"class":298,"line":485},22,[487],{"type":22,"tag":296,"props":488,"children":489},{},[490],{"type":27,"value":491},"│   │   │   │   │   │   ├── MyController.java\n",{"type":22,"tag":296,"props":493,"children":495},{"class":298,"line":494},23,[496],{"type":22,"tag":296,"props":497,"children":498},{},[499],{"type":27,"value":377},{"type":22,"tag":296,"props":501,"children":503},{"class":298,"line":502},24,[504],{"type":22,"tag":296,"props":505,"children":506},{},[507],{"type":27,"value":438},{"type":22,"tag":296,"props":509,"children":511},{"class":298,"line":510},25,[512],{"type":22,"tag":296,"props":513,"children":514},{},[515],{"type":27,"value":516},"│   ├── resources/\n",{"type":22,"tag":296,"props":518,"children":520},{"class":298,"line":519},26,[521],{"type":22,"tag":296,"props":522,"children":523},{},[524],{"type":27,"value":525},"│   └── ...\n",{"type":22,"tag":296,"props":527,"children":529},{"class":298,"line":528},27,[530],{"type":22,"tag":296,"props":531,"children":532},{},[533],{"type":27,"value":534},"└── ...\n",{"type":22,"tag":23,"props":536,"children":537},{},[538],{"type":27,"value":539},"In this structure:",{"type":22,"tag":207,"props":541,"children":542},{},[543,554,565,575],{"type":22,"tag":66,"props":544,"children":545},{},[546,552],{"type":22,"tag":13,"props":547,"children":549},{"className":548},[],[550],{"type":27,"value":551},"application",{"type":27,"value":553},": Contains use cases and application services that orchestrate the core business logic.",{"type":22,"tag":66,"props":555,"children":556},{},[557,563],{"type":22,"tag":13,"props":558,"children":560},{"className":559},[],[561],{"type":27,"value":562},"domain",{"type":27,"value":564},": Holds the domain model, including entities, value objects, and domain-specific logic.",{"type":22,"tag":66,"props":566,"children":567},{},[568,573],{"type":22,"tag":13,"props":569,"children":571},{"className":570},[],[572],{"type":27,"value":197},{"type":27,"value":574},": Defines interfaces (ports) that the core business logic requires from external dependencies. Implementations of these interfaces are provided in the infrastructure package.",{"type":22,"tag":66,"props":576,"children":577},{},[578,584,586],{"type":22,"tag":13,"props":579,"children":581},{"className":580},[],[582],{"type":27,"value":583},"infrastructure",{"type":27,"value":585},": Contains external adapters and implementations.",{"type":22,"tag":207,"props":587,"children":588},{},[589,600],{"type":22,"tag":66,"props":590,"children":591},{},[592,598],{"type":22,"tag":13,"props":593,"children":595},{"className":594},[],[596],{"type":27,"value":597},"adapter",{"type":27,"value":599},": Houses adapters that connect the application to external resources such as databases or message queues. For example, MyRepositoryImpl implements the MyRepository interface.",{"type":22,"tag":66,"props":601,"children":602},{},[603,609],{"type":22,"tag":13,"props":604,"children":606},{"className":605},[],[607],{"type":27,"value":608},"web",{"type":27,"value":610},": This is where you define your REST API controllers. MyController represents a RESTful API controller.",{"type":22,"tag":23,"props":612,"children":613},{},[614],{"type":27,"value":615},"With this structure, you maintain a clear separation between the core business logic (inside the application and domain packages) and the external interfaces (inside the infrastructure and web packages). This promotes testability, maintainability, and scalability while allowing you to leverage the Spring Boot framework for building RESTful APIs.",{"type":22,"tag":30,"props":617,"children":619},{"id":618},"further-reading",[620],{"type":27,"value":621},"Further Reading",{"type":22,"tag":23,"props":623,"children":624},{},[625],{"type":27,"value":626},"If you're interested in diving deeper into Hexagonal Architecture and its application in Spring Boot projects, here are some valuable resources to explore:",{"type":22,"tag":207,"props":628,"children":629},{},[630,646],{"type":22,"tag":66,"props":631,"children":632},{},[633,644],{"type":22,"tag":42,"props":634,"children":635},{},[636],{"type":22,"tag":113,"props":637,"children":641},{"href":638,"rel":639},"https://alistair.cockburn.us/hexagonal-architecture/",[640],"nofollow",[642],{"type":27,"value":643},"Hexagonal Architecture by Alistair Cockburn",{"type":27,"value":645},": The original article by Alistair Cockburn, the creator of Hexagonal Architecture, provides an in-depth explanation of the concept.",{"type":22,"tag":66,"props":647,"children":648},{},[649,659],{"type":22,"tag":42,"props":650,"children":651},{},[652],{"type":22,"tag":113,"props":653,"children":656},{"href":654,"rel":655},"https://www.oreilly.com/library/view/clean-architecture-a/9780134494272/",[640],[657],{"type":27,"value":658},"Clean Architecture by Robert C. Martin",{"type":27,"value":660},": Although not strictly Hexagonal Architecture, Clean Architecture shares similar principles and is worth exploring for a broader perspective on architectural patterns.",{"type":22,"tag":23,"props":662,"children":663},{},[664],{"type":27,"value":665},"These resources will provide you with a solid foundation and practical insights into Hexagonal Architecture, helping you design and build well-structured and maintainable software applications.",{"type":22,"tag":667,"props":668,"children":669},"style",{},[670],{"type":27,"value":671},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}",{"title":7,"searchDepth":308,"depth":308,"links":673},[674,675,676,680,681],{"id":32,"depth":308,"text":35},{"id":121,"depth":308,"text":124},{"id":185,"depth":308,"text":188,"children":677},[678,679],{"id":197,"depth":317,"text":200},{"id":237,"depth":317,"text":240},{"id":276,"depth":308,"text":279},{"id":618,"depth":308,"text":621},"markdown","content:posts:hexagonal-architecture.md","content","posts/hexagonal-architecture.md","posts/hexagonal-architecture","md",[689,2105,3011],{"_path":690,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":691,"description":692,"date":693,"layout":10,"subtitle":694,"image":695,"optimized_image":695,"category":13,"tags":696,"author":17,"paginate":6,"body":702,"_type":682,"_id":2102,"_source":684,"_file":2103,"_stem":2104,"_extension":687},"/posts/gpt-sql-integration","Implementa un analizador de consultas en lenguaje natural para bases de datos SQL con GPT","Aprende a implementar un sistema que convierte consultas en lenguaje natural en sentencias SQL usando OpenAI GPT, con un tutorial paso a paso y ejemplos prácticos.","2025-01-15T11:00:00.000Z","Transforma preguntas naturales en consultas SQL automatizadas","/assets/img/uploads/gpt-sql-integration.png",[13,697,698,699,700,701],"gpt","openai","sql","ai","nlp",{"type":19,"children":703,"toc":2091},[704,713,719,737,743,748,792,805,821,827,832,1048,1054,1059,1392,1398,1403,1750,1756,1761,1820,1826,1831,2012,2018,2036,2042,2047,2054,2087],{"type":22,"tag":705,"props":706,"children":707},"blockquote",{},[708],{"type":22,"tag":23,"props":709,"children":710},{},[711],{"type":27,"value":712},"Convertir preguntas naturales en consultas SQL de forma automática simplifica la interacción con bases de datos, permitiendo que usuarios sin conocimientos técnicos extraigan datos relevantes. En este tutorial, aprenderás a implementar esta solución utilizando la API de OpenAI GPT.",{"type":22,"tag":30,"props":714,"children":716},{"id":715},"requisitos-previos",[717],{"type":27,"value":718},"Requisitos Previos",{"type":22,"tag":207,"props":720,"children":721},{},[722,727,732],{"type":22,"tag":66,"props":723,"children":724},{},[725],{"type":27,"value":726},"Cuenta y clave API de OpenAI",{"type":22,"tag":66,"props":728,"children":729},{},[730],{"type":27,"value":731},"Python instalado en tu entorno",{"type":22,"tag":66,"props":733,"children":734},{},[735],{"type":27,"value":736},"Base de datos SQL (ej.: PostgreSQL, MySQL)",{"type":22,"tag":30,"props":738,"children":740},{"id":739},"paso-1-configuración-del-entorno",[741],{"type":27,"value":742},"Paso 1: Configuración del entorno",{"type":22,"tag":23,"props":744,"children":745},{},[746],{"type":27,"value":747},"Primero, instala las dependencias necesarias:",{"type":22,"tag":286,"props":749,"children":753},{"className":750,"code":751,"language":752,"meta":7,"style":7},"language-bash shiki shiki-themes github-dark github-light","pip install openai python-dotenv sqlalchemy psycopg2-binary\n","bash",[754],{"type":22,"tag":13,"props":755,"children":756},{"__ignoreMap":7},[757],{"type":22,"tag":296,"props":758,"children":759},{"class":298,"line":299},[760,766,772,777,782,787],{"type":22,"tag":296,"props":761,"children":763},{"style":762},"--shiki-default:#B392F0;--shiki-light:#6F42C1",[764],{"type":27,"value":765},"pip",{"type":22,"tag":296,"props":767,"children":769},{"style":768},"--shiki-default:#9ECBFF;--shiki-light:#032F62",[770],{"type":27,"value":771}," install",{"type":22,"tag":296,"props":773,"children":774},{"style":768},[775],{"type":27,"value":776}," openai",{"type":22,"tag":296,"props":778,"children":779},{"style":768},[780],{"type":27,"value":781}," python-dotenv",{"type":22,"tag":296,"props":783,"children":784},{"style":768},[785],{"type":27,"value":786}," sqlalchemy",{"type":22,"tag":296,"props":788,"children":789},{"style":768},[790],{"type":27,"value":791}," psycopg2-binary\n",{"type":22,"tag":23,"props":793,"children":794},{},[795,797,803],{"type":27,"value":796},"Guarda tu clave API en un archivo ",{"type":22,"tag":13,"props":798,"children":800},{"className":799},[],[801],{"type":27,"value":802},".env",{"type":27,"value":804},":",{"type":22,"tag":286,"props":806,"children":810},{"className":807,"code":808,"language":809,"meta":7,"style":7},"language-env shiki shiki-themes github-dark github-light","OPENAI_API_KEY='tu-api-key'\n","env",[811],{"type":22,"tag":13,"props":812,"children":813},{"__ignoreMap":7},[814],{"type":22,"tag":296,"props":815,"children":816},{"class":298,"line":299},[817],{"type":22,"tag":296,"props":818,"children":819},{},[820],{"type":27,"value":808},{"type":22,"tag":30,"props":822,"children":824},{"id":823},"paso-2-conexión-a-la-base-de-datos",[825],{"type":27,"value":826},"Paso 2: Conexión a la base de datos",{"type":22,"tag":23,"props":828,"children":829},{},[830],{"type":27,"value":831},"Utiliza SQLAlchemy para conectarte a tu base de datos:",{"type":22,"tag":286,"props":833,"children":837},{"className":834,"code":835,"language":836,"meta":7,"style":7},"language-python shiki shiki-themes github-dark github-light","from sqlalchemy import create_engine\nfrom sqlalchemy.orm import sessionmaker\nimport os\nfrom dotenv import load_dotenv\n\nload_dotenv()\n\nDATABASE_URL = os.getenv(\"DATABASE_URL\")\nengine = create_engine(DATABASE_URL)\nSession = sessionmaker(bind=engine)\nsession = Session()\n","python",[838],{"type":22,"tag":13,"props":839,"children":840},{"__ignoreMap":7},[841,866,887,899,920,929,937,944,973,999,1031],{"type":22,"tag":296,"props":842,"children":843},{"class":298,"line":299},[844,850,856,861],{"type":22,"tag":296,"props":845,"children":847},{"style":846},"--shiki-default:#F97583;--shiki-light:#D73A49",[848],{"type":27,"value":849},"from",{"type":22,"tag":296,"props":851,"children":853},{"style":852},"--shiki-default:#E1E4E8;--shiki-light:#24292E",[854],{"type":27,"value":855}," sqlalchemy ",{"type":22,"tag":296,"props":857,"children":858},{"style":846},[859],{"type":27,"value":860},"import",{"type":22,"tag":296,"props":862,"children":863},{"style":852},[864],{"type":27,"value":865}," create_engine\n",{"type":22,"tag":296,"props":867,"children":868},{"class":298,"line":308},[869,873,878,882],{"type":22,"tag":296,"props":870,"children":871},{"style":846},[872],{"type":27,"value":849},{"type":22,"tag":296,"props":874,"children":875},{"style":852},[876],{"type":27,"value":877}," sqlalchemy.orm ",{"type":22,"tag":296,"props":879,"children":880},{"style":846},[881],{"type":27,"value":860},{"type":22,"tag":296,"props":883,"children":884},{"style":852},[885],{"type":27,"value":886}," sessionmaker\n",{"type":22,"tag":296,"props":888,"children":889},{"class":298,"line":317},[890,894],{"type":22,"tag":296,"props":891,"children":892},{"style":846},[893],{"type":27,"value":860},{"type":22,"tag":296,"props":895,"children":896},{"style":852},[897],{"type":27,"value":898}," os\n",{"type":22,"tag":296,"props":900,"children":901},{"class":298,"line":326},[902,906,911,915],{"type":22,"tag":296,"props":903,"children":904},{"style":846},[905],{"type":27,"value":849},{"type":22,"tag":296,"props":907,"children":908},{"style":852},[909],{"type":27,"value":910}," dotenv ",{"type":22,"tag":296,"props":912,"children":913},{"style":846},[914],{"type":27,"value":860},{"type":22,"tag":296,"props":916,"children":917},{"style":852},[918],{"type":27,"value":919}," load_dotenv\n",{"type":22,"tag":296,"props":921,"children":922},{"class":298,"line":335},[923],{"type":22,"tag":296,"props":924,"children":926},{"emptyLinePlaceholder":925},true,[927],{"type":27,"value":928},"\n",{"type":22,"tag":296,"props":930,"children":931},{"class":298,"line":344},[932],{"type":22,"tag":296,"props":933,"children":934},{"style":852},[935],{"type":27,"value":936},"load_dotenv()\n",{"type":22,"tag":296,"props":938,"children":939},{"class":298,"line":353},[940],{"type":22,"tag":296,"props":941,"children":942},{"emptyLinePlaceholder":925},[943],{"type":27,"value":928},{"type":22,"tag":296,"props":945,"children":946},{"class":298,"line":362},[947,953,958,963,968],{"type":22,"tag":296,"props":948,"children":950},{"style":949},"--shiki-default:#79B8FF;--shiki-light:#005CC5",[951],{"type":27,"value":952},"DATABASE_URL",{"type":22,"tag":296,"props":954,"children":955},{"style":846},[956],{"type":27,"value":957}," =",{"type":22,"tag":296,"props":959,"children":960},{"style":852},[961],{"type":27,"value":962}," os.getenv(",{"type":22,"tag":296,"props":964,"children":965},{"style":768},[966],{"type":27,"value":967},"\"DATABASE_URL\"",{"type":22,"tag":296,"props":969,"children":970},{"style":852},[971],{"type":27,"value":972},")\n",{"type":22,"tag":296,"props":974,"children":975},{"class":298,"line":371},[976,981,986,991,995],{"type":22,"tag":296,"props":977,"children":978},{"style":852},[979],{"type":27,"value":980},"engine ",{"type":22,"tag":296,"props":982,"children":983},{"style":846},[984],{"type":27,"value":985},"=",{"type":22,"tag":296,"props":987,"children":988},{"style":852},[989],{"type":27,"value":990}," create_engine(",{"type":22,"tag":296,"props":992,"children":993},{"style":949},[994],{"type":27,"value":952},{"type":22,"tag":296,"props":996,"children":997},{"style":852},[998],{"type":27,"value":972},{"type":22,"tag":296,"props":1000,"children":1001},{"class":298,"line":380},[1002,1007,1011,1016,1022,1026],{"type":22,"tag":296,"props":1003,"children":1004},{"style":852},[1005],{"type":27,"value":1006},"Session ",{"type":22,"tag":296,"props":1008,"children":1009},{"style":846},[1010],{"type":27,"value":985},{"type":22,"tag":296,"props":1012,"children":1013},{"style":852},[1014],{"type":27,"value":1015}," sessionmaker(",{"type":22,"tag":296,"props":1017,"children":1019},{"style":1018},"--shiki-default:#FFAB70;--shiki-light:#E36209",[1020],{"type":27,"value":1021},"bind",{"type":22,"tag":296,"props":1023,"children":1024},{"style":846},[1025],{"type":27,"value":985},{"type":22,"tag":296,"props":1027,"children":1028},{"style":852},[1029],{"type":27,"value":1030},"engine)\n",{"type":22,"tag":296,"props":1032,"children":1033},{"class":298,"line":389},[1034,1039,1043],{"type":22,"tag":296,"props":1035,"children":1036},{"style":852},[1037],{"type":27,"value":1038},"session ",{"type":22,"tag":296,"props":1040,"children":1041},{"style":846},[1042],{"type":27,"value":985},{"type":22,"tag":296,"props":1044,"children":1045},{"style":852},[1046],{"type":27,"value":1047}," Session()\n",{"type":22,"tag":30,"props":1049,"children":1051},{"id":1050},"paso-3-obtener-esquema-de-la-base-de-datos",[1052],{"type":27,"value":1053},"Paso 3: Obtener esquema de la base de datos",{"type":22,"tag":23,"props":1055,"children":1056},{},[1057],{"type":27,"value":1058},"Genera una descripción del esquema que será utilizada por GPT:",{"type":22,"tag":286,"props":1060,"children":1062},{"className":834,"code":1061,"language":836,"meta":7,"style":7},"from sqlalchemy import inspect\n\ndef get_database_schema(engine):\n    inspector = inspect(engine)\n    schema_description = \"\"\n    for table_name in inspector.get_table_names():\n        schema_description += f\"Table: {table_name}\\n\"\n        for column in inspector.get_columns(table_name):\n            schema_description += f\"- {column['name']} ({column['type']})\\n\"\n        schema_description += \"\\n\"\n    return schema_description\n\nschema_description = get_database_schema(engine)\nprint(schema_description)\n",[1063],{"type":22,"tag":13,"props":1064,"children":1065},{"__ignoreMap":7},[1066,1086,1093,1111,1128,1145,1168,1211,1233,1318,1342,1355,1362,1379],{"type":22,"tag":296,"props":1067,"children":1068},{"class":298,"line":299},[1069,1073,1077,1081],{"type":22,"tag":296,"props":1070,"children":1071},{"style":846},[1072],{"type":27,"value":849},{"type":22,"tag":296,"props":1074,"children":1075},{"style":852},[1076],{"type":27,"value":855},{"type":22,"tag":296,"props":1078,"children":1079},{"style":846},[1080],{"type":27,"value":860},{"type":22,"tag":296,"props":1082,"children":1083},{"style":852},[1084],{"type":27,"value":1085}," inspect\n",{"type":22,"tag":296,"props":1087,"children":1088},{"class":298,"line":308},[1089],{"type":22,"tag":296,"props":1090,"children":1091},{"emptyLinePlaceholder":925},[1092],{"type":27,"value":928},{"type":22,"tag":296,"props":1094,"children":1095},{"class":298,"line":317},[1096,1101,1106],{"type":22,"tag":296,"props":1097,"children":1098},{"style":846},[1099],{"type":27,"value":1100},"def",{"type":22,"tag":296,"props":1102,"children":1103},{"style":762},[1104],{"type":27,"value":1105}," get_database_schema",{"type":22,"tag":296,"props":1107,"children":1108},{"style":852},[1109],{"type":27,"value":1110},"(engine):\n",{"type":22,"tag":296,"props":1112,"children":1113},{"class":298,"line":326},[1114,1119,1123],{"type":22,"tag":296,"props":1115,"children":1116},{"style":852},[1117],{"type":27,"value":1118},"    inspector ",{"type":22,"tag":296,"props":1120,"children":1121},{"style":846},[1122],{"type":27,"value":985},{"type":22,"tag":296,"props":1124,"children":1125},{"style":852},[1126],{"type":27,"value":1127}," inspect(engine)\n",{"type":22,"tag":296,"props":1129,"children":1130},{"class":298,"line":335},[1131,1136,1140],{"type":22,"tag":296,"props":1132,"children":1133},{"style":852},[1134],{"type":27,"value":1135},"    schema_description ",{"type":22,"tag":296,"props":1137,"children":1138},{"style":846},[1139],{"type":27,"value":985},{"type":22,"tag":296,"props":1141,"children":1142},{"style":768},[1143],{"type":27,"value":1144}," \"\"\n",{"type":22,"tag":296,"props":1146,"children":1147},{"class":298,"line":344},[1148,1153,1158,1163],{"type":22,"tag":296,"props":1149,"children":1150},{"style":846},[1151],{"type":27,"value":1152},"    for",{"type":22,"tag":296,"props":1154,"children":1155},{"style":852},[1156],{"type":27,"value":1157}," table_name ",{"type":22,"tag":296,"props":1159,"children":1160},{"style":846},[1161],{"type":27,"value":1162},"in",{"type":22,"tag":296,"props":1164,"children":1165},{"style":852},[1166],{"type":27,"value":1167}," inspector.get_table_names():\n",{"type":22,"tag":296,"props":1169,"children":1170},{"class":298,"line":353},[1171,1176,1181,1186,1191,1196,1201,1206],{"type":22,"tag":296,"props":1172,"children":1173},{"style":852},[1174],{"type":27,"value":1175},"        schema_description ",{"type":22,"tag":296,"props":1177,"children":1178},{"style":846},[1179],{"type":27,"value":1180},"+=",{"type":22,"tag":296,"props":1182,"children":1183},{"style":846},[1184],{"type":27,"value":1185}," f",{"type":22,"tag":296,"props":1187,"children":1188},{"style":768},[1189],{"type":27,"value":1190},"\"Table: ",{"type":22,"tag":296,"props":1192,"children":1193},{"style":949},[1194],{"type":27,"value":1195},"{",{"type":22,"tag":296,"props":1197,"children":1198},{"style":852},[1199],{"type":27,"value":1200},"table_name",{"type":22,"tag":296,"props":1202,"children":1203},{"style":949},[1204],{"type":27,"value":1205},"}\\n",{"type":22,"tag":296,"props":1207,"children":1208},{"style":768},[1209],{"type":27,"value":1210},"\"\n",{"type":22,"tag":296,"props":1212,"children":1213},{"class":298,"line":362},[1214,1219,1224,1228],{"type":22,"tag":296,"props":1215,"children":1216},{"style":846},[1217],{"type":27,"value":1218},"        for",{"type":22,"tag":296,"props":1220,"children":1221},{"style":852},[1222],{"type":27,"value":1223}," column ",{"type":22,"tag":296,"props":1225,"children":1226},{"style":846},[1227],{"type":27,"value":1162},{"type":22,"tag":296,"props":1229,"children":1230},{"style":852},[1231],{"type":27,"value":1232}," inspector.get_columns(table_name):\n",{"type":22,"tag":296,"props":1234,"children":1235},{"class":298,"line":371},[1236,1241,1245,1249,1254,1258,1263,1268,1273,1278,1283,1287,1291,1296,1300,1304,1309,1314],{"type":22,"tag":296,"props":1237,"children":1238},{"style":852},[1239],{"type":27,"value":1240},"            schema_description ",{"type":22,"tag":296,"props":1242,"children":1243},{"style":846},[1244],{"type":27,"value":1180},{"type":22,"tag":296,"props":1246,"children":1247},{"style":846},[1248],{"type":27,"value":1185},{"type":22,"tag":296,"props":1250,"children":1251},{"style":768},[1252],{"type":27,"value":1253},"\"- ",{"type":22,"tag":296,"props":1255,"children":1256},{"style":949},[1257],{"type":27,"value":1195},{"type":22,"tag":296,"props":1259,"children":1260},{"style":852},[1261],{"type":27,"value":1262},"column[",{"type":22,"tag":296,"props":1264,"children":1265},{"style":768},[1266],{"type":27,"value":1267},"'name'",{"type":22,"tag":296,"props":1269,"children":1270},{"style":852},[1271],{"type":27,"value":1272},"]",{"type":22,"tag":296,"props":1274,"children":1275},{"style":949},[1276],{"type":27,"value":1277},"}",{"type":22,"tag":296,"props":1279,"children":1280},{"style":768},[1281],{"type":27,"value":1282}," (",{"type":22,"tag":296,"props":1284,"children":1285},{"style":949},[1286],{"type":27,"value":1195},{"type":22,"tag":296,"props":1288,"children":1289},{"style":852},[1290],{"type":27,"value":1262},{"type":22,"tag":296,"props":1292,"children":1293},{"style":768},[1294],{"type":27,"value":1295},"'type'",{"type":22,"tag":296,"props":1297,"children":1298},{"style":852},[1299],{"type":27,"value":1272},{"type":22,"tag":296,"props":1301,"children":1302},{"style":949},[1303],{"type":27,"value":1277},{"type":22,"tag":296,"props":1305,"children":1306},{"style":768},[1307],{"type":27,"value":1308},")",{"type":22,"tag":296,"props":1310,"children":1311},{"style":949},[1312],{"type":27,"value":1313},"\\n",{"type":22,"tag":296,"props":1315,"children":1316},{"style":768},[1317],{"type":27,"value":1210},{"type":22,"tag":296,"props":1319,"children":1320},{"class":298,"line":380},[1321,1325,1329,1334,1338],{"type":22,"tag":296,"props":1322,"children":1323},{"style":852},[1324],{"type":27,"value":1175},{"type":22,"tag":296,"props":1326,"children":1327},{"style":846},[1328],{"type":27,"value":1180},{"type":22,"tag":296,"props":1330,"children":1331},{"style":768},[1332],{"type":27,"value":1333}," \"",{"type":22,"tag":296,"props":1335,"children":1336},{"style":949},[1337],{"type":27,"value":1313},{"type":22,"tag":296,"props":1339,"children":1340},{"style":768},[1341],{"type":27,"value":1210},{"type":22,"tag":296,"props":1343,"children":1344},{"class":298,"line":389},[1345,1350],{"type":22,"tag":296,"props":1346,"children":1347},{"style":846},[1348],{"type":27,"value":1349},"    return",{"type":22,"tag":296,"props":1351,"children":1352},{"style":852},[1353],{"type":27,"value":1354}," schema_description\n",{"type":22,"tag":296,"props":1356,"children":1357},{"class":298,"line":398},[1358],{"type":22,"tag":296,"props":1359,"children":1360},{"emptyLinePlaceholder":925},[1361],{"type":27,"value":928},{"type":22,"tag":296,"props":1363,"children":1364},{"class":298,"line":406},[1365,1370,1374],{"type":22,"tag":296,"props":1366,"children":1367},{"style":852},[1368],{"type":27,"value":1369},"schema_description ",{"type":22,"tag":296,"props":1371,"children":1372},{"style":846},[1373],{"type":27,"value":985},{"type":22,"tag":296,"props":1375,"children":1376},{"style":852},[1377],{"type":27,"value":1378}," get_database_schema(engine)\n",{"type":22,"tag":296,"props":1380,"children":1381},{"class":298,"line":415},[1382,1387],{"type":22,"tag":296,"props":1383,"children":1384},{"style":949},[1385],{"type":27,"value":1386},"print",{"type":22,"tag":296,"props":1388,"children":1389},{"style":852},[1390],{"type":27,"value":1391},"(schema_description)\n",{"type":22,"tag":30,"props":1393,"children":1395},{"id":1394},"paso-4-preparar-la-consulta-con-gpt",[1396],{"type":27,"value":1397},"Paso 4: Preparar la consulta con GPT",{"type":22,"tag":23,"props":1399,"children":1400},{},[1401],{"type":27,"value":1402},"Utiliza la API de OpenAI para transformar preguntas en consultas SQL, incluyendo el esquema de la base de datos:",{"type":22,"tag":286,"props":1404,"children":1406},{"className":834,"code":1405,"language":836,"meta":7,"style":7},"import openai\nimport os\n\nopenai.api_key = os.getenv(\"OPENAI_API_KEY\")\n\ndef generate_sql(question, schema):\n    response = openai.ChatCompletion.create(\n        model=\"gpt-4\",\n        messages=[\n            {\"role\": \"system\", \"content\": f\"Convierte preguntas en lenguaje natural a consultas SQL. Esquema de la base de datos:\\n{schema}\"},\n            {\"role\": \"user\", \"content\": question}\n        ]\n    )\n    sql_query = response.choices[0].message.content.strip()\n    return sql_query\n\nquery = generate_sql(\"¿Cuántos usuarios se registraron el último mes?\", schema_description)\nprint(query)\n",[1407],{"type":22,"tag":13,"props":1408,"children":1409},{"__ignoreMap":7},[1410,1422,1433,1440,1465,1472,1489,1506,1528,1545,1616,1649,1657,1665,1692,1704,1711,1738],{"type":22,"tag":296,"props":1411,"children":1412},{"class":298,"line":299},[1413,1417],{"type":22,"tag":296,"props":1414,"children":1415},{"style":846},[1416],{"type":27,"value":860},{"type":22,"tag":296,"props":1418,"children":1419},{"style":852},[1420],{"type":27,"value":1421}," openai\n",{"type":22,"tag":296,"props":1423,"children":1424},{"class":298,"line":308},[1425,1429],{"type":22,"tag":296,"props":1426,"children":1427},{"style":846},[1428],{"type":27,"value":860},{"type":22,"tag":296,"props":1430,"children":1431},{"style":852},[1432],{"type":27,"value":898},{"type":22,"tag":296,"props":1434,"children":1435},{"class":298,"line":317},[1436],{"type":22,"tag":296,"props":1437,"children":1438},{"emptyLinePlaceholder":925},[1439],{"type":27,"value":928},{"type":22,"tag":296,"props":1441,"children":1442},{"class":298,"line":326},[1443,1448,1452,1456,1461],{"type":22,"tag":296,"props":1444,"children":1445},{"style":852},[1446],{"type":27,"value":1447},"openai.api_key ",{"type":22,"tag":296,"props":1449,"children":1450},{"style":846},[1451],{"type":27,"value":985},{"type":22,"tag":296,"props":1453,"children":1454},{"style":852},[1455],{"type":27,"value":962},{"type":22,"tag":296,"props":1457,"children":1458},{"style":768},[1459],{"type":27,"value":1460},"\"OPENAI_API_KEY\"",{"type":22,"tag":296,"props":1462,"children":1463},{"style":852},[1464],{"type":27,"value":972},{"type":22,"tag":296,"props":1466,"children":1467},{"class":298,"line":335},[1468],{"type":22,"tag":296,"props":1469,"children":1470},{"emptyLinePlaceholder":925},[1471],{"type":27,"value":928},{"type":22,"tag":296,"props":1473,"children":1474},{"class":298,"line":344},[1475,1479,1484],{"type":22,"tag":296,"props":1476,"children":1477},{"style":846},[1478],{"type":27,"value":1100},{"type":22,"tag":296,"props":1480,"children":1481},{"style":762},[1482],{"type":27,"value":1483}," generate_sql",{"type":22,"tag":296,"props":1485,"children":1486},{"style":852},[1487],{"type":27,"value":1488},"(question, schema):\n",{"type":22,"tag":296,"props":1490,"children":1491},{"class":298,"line":353},[1492,1497,1501],{"type":22,"tag":296,"props":1493,"children":1494},{"style":852},[1495],{"type":27,"value":1496},"    response ",{"type":22,"tag":296,"props":1498,"children":1499},{"style":846},[1500],{"type":27,"value":985},{"type":22,"tag":296,"props":1502,"children":1503},{"style":852},[1504],{"type":27,"value":1505}," openai.ChatCompletion.create(\n",{"type":22,"tag":296,"props":1507,"children":1508},{"class":298,"line":362},[1509,1514,1518,1523],{"type":22,"tag":296,"props":1510,"children":1511},{"style":1018},[1512],{"type":27,"value":1513},"        model",{"type":22,"tag":296,"props":1515,"children":1516},{"style":846},[1517],{"type":27,"value":985},{"type":22,"tag":296,"props":1519,"children":1520},{"style":768},[1521],{"type":27,"value":1522},"\"gpt-4\"",{"type":22,"tag":296,"props":1524,"children":1525},{"style":852},[1526],{"type":27,"value":1527},",\n",{"type":22,"tag":296,"props":1529,"children":1530},{"class":298,"line":371},[1531,1536,1540],{"type":22,"tag":296,"props":1532,"children":1533},{"style":1018},[1534],{"type":27,"value":1535},"        messages",{"type":22,"tag":296,"props":1537,"children":1538},{"style":846},[1539],{"type":27,"value":985},{"type":22,"tag":296,"props":1541,"children":1542},{"style":852},[1543],{"type":27,"value":1544},"[\n",{"type":22,"tag":296,"props":1546,"children":1547},{"class":298,"line":380},[1548,1553,1558,1563,1568,1573,1578,1582,1587,1592,1597,1602,1606,1611],{"type":22,"tag":296,"props":1549,"children":1550},{"style":852},[1551],{"type":27,"value":1552},"            {",{"type":22,"tag":296,"props":1554,"children":1555},{"style":768},[1556],{"type":27,"value":1557},"\"role\"",{"type":22,"tag":296,"props":1559,"children":1560},{"style":852},[1561],{"type":27,"value":1562},": ",{"type":22,"tag":296,"props":1564,"children":1565},{"style":768},[1566],{"type":27,"value":1567},"\"system\"",{"type":22,"tag":296,"props":1569,"children":1570},{"style":852},[1571],{"type":27,"value":1572},", ",{"type":22,"tag":296,"props":1574,"children":1575},{"style":768},[1576],{"type":27,"value":1577},"\"content\"",{"type":22,"tag":296,"props":1579,"children":1580},{"style":852},[1581],{"type":27,"value":1562},{"type":22,"tag":296,"props":1583,"children":1584},{"style":846},[1585],{"type":27,"value":1586},"f",{"type":22,"tag":296,"props":1588,"children":1589},{"style":768},[1590],{"type":27,"value":1591},"\"Convierte preguntas en lenguaje natural a consultas SQL. Esquema de la base de datos:",{"type":22,"tag":296,"props":1593,"children":1594},{"style":949},[1595],{"type":27,"value":1596},"\\n{",{"type":22,"tag":296,"props":1598,"children":1599},{"style":852},[1600],{"type":27,"value":1601},"schema",{"type":22,"tag":296,"props":1603,"children":1604},{"style":949},[1605],{"type":27,"value":1277},{"type":22,"tag":296,"props":1607,"children":1608},{"style":768},[1609],{"type":27,"value":1610},"\"",{"type":22,"tag":296,"props":1612,"children":1613},{"style":852},[1614],{"type":27,"value":1615},"},\n",{"type":22,"tag":296,"props":1617,"children":1618},{"class":298,"line":389},[1619,1623,1627,1631,1636,1640,1644],{"type":22,"tag":296,"props":1620,"children":1621},{"style":852},[1622],{"type":27,"value":1552},{"type":22,"tag":296,"props":1624,"children":1625},{"style":768},[1626],{"type":27,"value":1557},{"type":22,"tag":296,"props":1628,"children":1629},{"style":852},[1630],{"type":27,"value":1562},{"type":22,"tag":296,"props":1632,"children":1633},{"style":768},[1634],{"type":27,"value":1635},"\"user\"",{"type":22,"tag":296,"props":1637,"children":1638},{"style":852},[1639],{"type":27,"value":1572},{"type":22,"tag":296,"props":1641,"children":1642},{"style":768},[1643],{"type":27,"value":1577},{"type":22,"tag":296,"props":1645,"children":1646},{"style":852},[1647],{"type":27,"value":1648},": question}\n",{"type":22,"tag":296,"props":1650,"children":1651},{"class":298,"line":398},[1652],{"type":22,"tag":296,"props":1653,"children":1654},{"style":852},[1655],{"type":27,"value":1656},"        ]\n",{"type":22,"tag":296,"props":1658,"children":1659},{"class":298,"line":406},[1660],{"type":22,"tag":296,"props":1661,"children":1662},{"style":852},[1663],{"type":27,"value":1664},"    )\n",{"type":22,"tag":296,"props":1666,"children":1667},{"class":298,"line":415},[1668,1673,1677,1682,1687],{"type":22,"tag":296,"props":1669,"children":1670},{"style":852},[1671],{"type":27,"value":1672},"    sql_query ",{"type":22,"tag":296,"props":1674,"children":1675},{"style":846},[1676],{"type":27,"value":985},{"type":22,"tag":296,"props":1678,"children":1679},{"style":852},[1680],{"type":27,"value":1681}," response.choices[",{"type":22,"tag":296,"props":1683,"children":1684},{"style":949},[1685],{"type":27,"value":1686},"0",{"type":22,"tag":296,"props":1688,"children":1689},{"style":852},[1690],{"type":27,"value":1691},"].message.content.strip()\n",{"type":22,"tag":296,"props":1693,"children":1694},{"class":298,"line":424},[1695,1699],{"type":22,"tag":296,"props":1696,"children":1697},{"style":846},[1698],{"type":27,"value":1349},{"type":22,"tag":296,"props":1700,"children":1701},{"style":852},[1702],{"type":27,"value":1703}," sql_query\n",{"type":22,"tag":296,"props":1705,"children":1706},{"class":298,"line":432},[1707],{"type":22,"tag":296,"props":1708,"children":1709},{"emptyLinePlaceholder":925},[1710],{"type":27,"value":928},{"type":22,"tag":296,"props":1712,"children":1713},{"class":298,"line":441},[1714,1719,1723,1728,1733],{"type":22,"tag":296,"props":1715,"children":1716},{"style":852},[1717],{"type":27,"value":1718},"query ",{"type":22,"tag":296,"props":1720,"children":1721},{"style":846},[1722],{"type":27,"value":985},{"type":22,"tag":296,"props":1724,"children":1725},{"style":852},[1726],{"type":27,"value":1727}," generate_sql(",{"type":22,"tag":296,"props":1729,"children":1730},{"style":768},[1731],{"type":27,"value":1732},"\"¿Cuántos usuarios se registraron el último mes?\"",{"type":22,"tag":296,"props":1734,"children":1735},{"style":852},[1736],{"type":27,"value":1737},", schema_description)\n",{"type":22,"tag":296,"props":1739,"children":1740},{"class":298,"line":450},[1741,1745],{"type":22,"tag":296,"props":1742,"children":1743},{"style":949},[1744],{"type":27,"value":1386},{"type":22,"tag":296,"props":1746,"children":1747},{"style":852},[1748],{"type":27,"value":1749},"(query)\n",{"type":22,"tag":30,"props":1751,"children":1753},{"id":1752},"paso-5-ejecutar-consultas-generadas",[1754],{"type":27,"value":1755},"Paso 5: Ejecutar consultas generadas",{"type":22,"tag":23,"props":1757,"children":1758},{},[1759],{"type":27,"value":1760},"Ejecuta la consulta generada y obtiene resultados:",{"type":22,"tag":286,"props":1762,"children":1764},{"className":834,"code":1763,"language":836,"meta":7,"style":7},"result = session.execute(query)\nfor row in result:\n    print(row)\n",[1765],{"type":22,"tag":13,"props":1766,"children":1767},{"__ignoreMap":7},[1768,1785,1807],{"type":22,"tag":296,"props":1769,"children":1770},{"class":298,"line":299},[1771,1776,1780],{"type":22,"tag":296,"props":1772,"children":1773},{"style":852},[1774],{"type":27,"value":1775},"result ",{"type":22,"tag":296,"props":1777,"children":1778},{"style":846},[1779],{"type":27,"value":985},{"type":22,"tag":296,"props":1781,"children":1782},{"style":852},[1783],{"type":27,"value":1784}," session.execute(query)\n",{"type":22,"tag":296,"props":1786,"children":1787},{"class":298,"line":308},[1788,1793,1798,1802],{"type":22,"tag":296,"props":1789,"children":1790},{"style":846},[1791],{"type":27,"value":1792},"for",{"type":22,"tag":296,"props":1794,"children":1795},{"style":852},[1796],{"type":27,"value":1797}," row ",{"type":22,"tag":296,"props":1799,"children":1800},{"style":846},[1801],{"type":27,"value":1162},{"type":22,"tag":296,"props":1803,"children":1804},{"style":852},[1805],{"type":27,"value":1806}," result:\n",{"type":22,"tag":296,"props":1808,"children":1809},{"class":298,"line":317},[1810,1815],{"type":22,"tag":296,"props":1811,"children":1812},{"style":949},[1813],{"type":27,"value":1814},"    print",{"type":22,"tag":296,"props":1816,"children":1817},{"style":852},[1818],{"type":27,"value":1819},"(row)\n",{"type":22,"tag":30,"props":1821,"children":1823},{"id":1822},"paso-6-manejo-de-errores-y-seguridad",[1824],{"type":27,"value":1825},"Paso 6: Manejo de errores y seguridad",{"type":22,"tag":23,"props":1827,"children":1828},{},[1829],{"type":27,"value":1830},"Para evitar problemas con consultas inseguras o errores, siempre valida las consultas generadas por GPT antes de ejecutarlas directamente:",{"type":22,"tag":286,"props":1832,"children":1834},{"className":834,"code":1833,"language":836,"meta":7,"style":7},"def execute_safe_query(sql_query):\n    try:\n        result = session.execute(sql_query)\n        return result.fetchall()\n    except Exception as e:\n        print(f\"Error al ejecutar consulta: {e}\")\n        return None\n\nresults = execute_safe_query(query)\nprint(results)\n",[1835],{"type":22,"tag":13,"props":1836,"children":1837},{"__ignoreMap":7},[1838,1855,1868,1885,1898,1921,1964,1976,1983,2000],{"type":22,"tag":296,"props":1839,"children":1840},{"class":298,"line":299},[1841,1845,1850],{"type":22,"tag":296,"props":1842,"children":1843},{"style":846},[1844],{"type":27,"value":1100},{"type":22,"tag":296,"props":1846,"children":1847},{"style":762},[1848],{"type":27,"value":1849}," execute_safe_query",{"type":22,"tag":296,"props":1851,"children":1852},{"style":852},[1853],{"type":27,"value":1854},"(sql_query):\n",{"type":22,"tag":296,"props":1856,"children":1857},{"class":298,"line":308},[1858,1863],{"type":22,"tag":296,"props":1859,"children":1860},{"style":846},[1861],{"type":27,"value":1862},"    try",{"type":22,"tag":296,"props":1864,"children":1865},{"style":852},[1866],{"type":27,"value":1867},":\n",{"type":22,"tag":296,"props":1869,"children":1870},{"class":298,"line":317},[1871,1876,1880],{"type":22,"tag":296,"props":1872,"children":1873},{"style":852},[1874],{"type":27,"value":1875},"        result ",{"type":22,"tag":296,"props":1877,"children":1878},{"style":846},[1879],{"type":27,"value":985},{"type":22,"tag":296,"props":1881,"children":1882},{"style":852},[1883],{"type":27,"value":1884}," session.execute(sql_query)\n",{"type":22,"tag":296,"props":1886,"children":1887},{"class":298,"line":326},[1888,1893],{"type":22,"tag":296,"props":1889,"children":1890},{"style":846},[1891],{"type":27,"value":1892},"        return",{"type":22,"tag":296,"props":1894,"children":1895},{"style":852},[1896],{"type":27,"value":1897}," result.fetchall()\n",{"type":22,"tag":296,"props":1899,"children":1900},{"class":298,"line":335},[1901,1906,1911,1916],{"type":22,"tag":296,"props":1902,"children":1903},{"style":846},[1904],{"type":27,"value":1905},"    except",{"type":22,"tag":296,"props":1907,"children":1908},{"style":949},[1909],{"type":27,"value":1910}," Exception",{"type":22,"tag":296,"props":1912,"children":1913},{"style":846},[1914],{"type":27,"value":1915}," as",{"type":22,"tag":296,"props":1917,"children":1918},{"style":852},[1919],{"type":27,"value":1920}," e:\n",{"type":22,"tag":296,"props":1922,"children":1923},{"class":298,"line":344},[1924,1929,1934,1938,1943,1947,1952,1956,1960],{"type":22,"tag":296,"props":1925,"children":1926},{"style":949},[1927],{"type":27,"value":1928},"        print",{"type":22,"tag":296,"props":1930,"children":1931},{"style":852},[1932],{"type":27,"value":1933},"(",{"type":22,"tag":296,"props":1935,"children":1936},{"style":846},[1937],{"type":27,"value":1586},{"type":22,"tag":296,"props":1939,"children":1940},{"style":768},[1941],{"type":27,"value":1942},"\"Error al ejecutar consulta: ",{"type":22,"tag":296,"props":1944,"children":1945},{"style":949},[1946],{"type":27,"value":1195},{"type":22,"tag":296,"props":1948,"children":1949},{"style":852},[1950],{"type":27,"value":1951},"e",{"type":22,"tag":296,"props":1953,"children":1954},{"style":949},[1955],{"type":27,"value":1277},{"type":22,"tag":296,"props":1957,"children":1958},{"style":768},[1959],{"type":27,"value":1610},{"type":22,"tag":296,"props":1961,"children":1962},{"style":852},[1963],{"type":27,"value":972},{"type":22,"tag":296,"props":1965,"children":1966},{"class":298,"line":353},[1967,1971],{"type":22,"tag":296,"props":1968,"children":1969},{"style":846},[1970],{"type":27,"value":1892},{"type":22,"tag":296,"props":1972,"children":1973},{"style":949},[1974],{"type":27,"value":1975}," None\n",{"type":22,"tag":296,"props":1977,"children":1978},{"class":298,"line":362},[1979],{"type":22,"tag":296,"props":1980,"children":1981},{"emptyLinePlaceholder":925},[1982],{"type":27,"value":928},{"type":22,"tag":296,"props":1984,"children":1985},{"class":298,"line":371},[1986,1991,1995],{"type":22,"tag":296,"props":1987,"children":1988},{"style":852},[1989],{"type":27,"value":1990},"results ",{"type":22,"tag":296,"props":1992,"children":1993},{"style":846},[1994],{"type":27,"value":985},{"type":22,"tag":296,"props":1996,"children":1997},{"style":852},[1998],{"type":27,"value":1999}," execute_safe_query(query)\n",{"type":22,"tag":296,"props":2001,"children":2002},{"class":298,"line":380},[2003,2007],{"type":22,"tag":296,"props":2004,"children":2005},{"style":949},[2006],{"type":27,"value":1386},{"type":22,"tag":296,"props":2008,"children":2009},{"style":852},[2010],{"type":27,"value":2011},"(results)\n",{"type":22,"tag":30,"props":2013,"children":2015},{"id":2014},"buenas-prácticas",[2016],{"type":27,"value":2017},"Buenas prácticas",{"type":22,"tag":207,"props":2019,"children":2020},{},[2021,2026,2031],{"type":22,"tag":66,"props":2022,"children":2023},{},[2024],{"type":27,"value":2025},"Siempre revisa o limita el acceso de los usuarios a consultas críticas o sensibles.",{"type":22,"tag":66,"props":2027,"children":2028},{},[2029],{"type":27,"value":2030},"Implementa validaciones adicionales para asegurar la integridad y seguridad de tu base de datos.",{"type":22,"tag":66,"props":2032,"children":2033},{},[2034],{"type":27,"value":2035},"Utiliza tokens y modelos específicos de OpenAI optimizados para tareas SQL.",{"type":22,"tag":30,"props":2037,"children":2039},{"id":2038},"conclusión",[2040],{"type":27,"value":2041},"Conclusión",{"type":22,"tag":23,"props":2043,"children":2044},{},[2045],{"type":27,"value":2046},"Utilizar GPT para transformar consultas en lenguaje natural a SQL facilita enormemente la accesibilidad a los datos. Implementando este sistema, podrás ofrecer una experiencia de usuario más amigable y eficiente.",{"type":22,"tag":2048,"props":2049,"children":2051},"h1",{"id":2050},"recursos-adicionales",[2052],{"type":27,"value":2053},"Recursos adicionales",{"type":22,"tag":207,"props":2055,"children":2056},{},[2057,2067,2077],{"type":22,"tag":66,"props":2058,"children":2059},{},[2060],{"type":22,"tag":113,"props":2061,"children":2064},{"href":2062,"rel":2063},"https://platform.openai.com/docs/api-reference",[640],[2065],{"type":27,"value":2066},"Documentación API OpenAI",{"type":22,"tag":66,"props":2068,"children":2069},{},[2070],{"type":22,"tag":113,"props":2071,"children":2074},{"href":2072,"rel":2073},"https://docs.sqlalchemy.org/en/20/",[640],[2075],{"type":27,"value":2076},"SQLAlchemy ORM Documentation",{"type":22,"tag":66,"props":2078,"children":2079},{},[2080],{"type":22,"tag":113,"props":2081,"children":2084},{"href":2082,"rel":2083},"https://pypi.org/project/python-dotenv/",[640],[2085],{"type":27,"value":2086},"Python Dotenv",{"type":22,"tag":667,"props":2088,"children":2089},{},[2090],{"type":27,"value":671},{"title":7,"searchDepth":308,"depth":308,"links":2092},[2093,2094,2095,2096,2097,2098,2099,2100,2101],{"id":715,"depth":308,"text":718},{"id":739,"depth":308,"text":742},{"id":823,"depth":308,"text":826},{"id":1050,"depth":308,"text":1053},{"id":1394,"depth":308,"text":1397},{"id":1752,"depth":308,"text":1755},{"id":1822,"depth":308,"text":1825},{"id":2014,"depth":308,"text":2017},{"id":2038,"depth":308,"text":2041},"content:posts:gpt-sql-integration.md","posts/gpt-sql-integration.md","posts/gpt-sql-integration",{"_path":2106,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":2107,"description":2108,"date":2109,"layout":10,"subtitle":2110,"image":2111,"optimized_image":2111,"category":13,"tags":2112,"author":17,"paginate":6,"body":2116,"_type":682,"_id":3008,"_source":684,"_file":3009,"_stem":3010,"_extension":687},"/posts/java-security-best-practices","Java Security Best Practices: Preventing Vulnerabilities and Threats","Explore essential security strategies for Java applications, addressing common vulnerabilities identified by OWASP Top 10 with practical examples.","2024-08-15T11:00:00.000Z","Practical Strategies to Safeguard Your Java Applications","/assets/img/uploads/java-security-best-practices.png",[13,15,2113,2114,2115],"security","owasp","cybersecurity",{"type":19,"children":2117,"toc":2996},[2118,2126,2132,2137,2190,2195,2201,2206,2329,2334,2340,2345,2448,2454,2459,2582,2587,2593,2598,2623,2628,2634,2639,2655,2660,2666,2671,2754,2759,2765,2770,2890,2895,2901,2906,2939,2944,2950,2955,2959,2992],{"type":22,"tag":705,"props":2119,"children":2120},{},[2121],{"type":22,"tag":23,"props":2122,"children":2123},{},[2124],{"type":27,"value":2125},"Security is critical in software development. Java applications, like all software, face numerous potential vulnerabilities. In this article, we will explore essential security best practices, referencing the OWASP Top 10, and providing practical Java examples to help you protect your applications effectively.",{"type":22,"tag":30,"props":2127,"children":2129},{"id":2128},"understanding-owasp-top-10",[2130],{"type":27,"value":2131},"Understanding OWASP Top 10",{"type":22,"tag":23,"props":2133,"children":2134},{},[2135],{"type":27,"value":2136},"The OWASP Top 10 outlines the most critical web application security risks:",{"type":22,"tag":62,"props":2138,"children":2139},{},[2140,2145,2150,2155,2160,2165,2170,2175,2180,2185],{"type":22,"tag":66,"props":2141,"children":2142},{},[2143],{"type":27,"value":2144},"Injection",{"type":22,"tag":66,"props":2146,"children":2147},{},[2148],{"type":27,"value":2149},"Broken Authentication",{"type":22,"tag":66,"props":2151,"children":2152},{},[2153],{"type":27,"value":2154},"Sensitive Data Exposure",{"type":22,"tag":66,"props":2156,"children":2157},{},[2158],{"type":27,"value":2159},"XML External Entities (XXE)",{"type":22,"tag":66,"props":2161,"children":2162},{},[2163],{"type":27,"value":2164},"Broken Access Control",{"type":22,"tag":66,"props":2166,"children":2167},{},[2168],{"type":27,"value":2169},"Security Misconfiguration",{"type":22,"tag":66,"props":2171,"children":2172},{},[2173],{"type":27,"value":2174},"Cross-Site Scripting (XSS)",{"type":22,"tag":66,"props":2176,"children":2177},{},[2178],{"type":27,"value":2179},"Insecure Deserialization",{"type":22,"tag":66,"props":2181,"children":2182},{},[2183],{"type":27,"value":2184},"Using Components with Known Vulnerabilities",{"type":22,"tag":66,"props":2186,"children":2187},{},[2188],{"type":27,"value":2189},"Insufficient Logging and Monitoring",{"type":22,"tag":23,"props":2191,"children":2192},{},[2193],{"type":27,"value":2194},"Let's delve into practical strategies and Java implementations for some of these threats.",{"type":22,"tag":30,"props":2196,"children":2198},{"id":2197},"_1-injection-prevention",[2199],{"type":27,"value":2200},"1. Injection Prevention",{"type":22,"tag":23,"props":2202,"children":2203},{},[2204],{"type":27,"value":2205},"Use Prepared Statements and parameterized queries:",{"type":22,"tag":286,"props":2207,"children":2210},{"className":2208,"code":2209,"language":15,"meta":7,"style":7},"language-java shiki shiki-themes github-dark github-light","PreparedStatement stmt = connection.prepareStatement(\"SELECT * FROM users WHERE username=? AND password=?\");\nstmt.setString(1, username);\nstmt.setString(2, password);\nResultSet rs = stmt.executeQuery();\n",[2211],{"type":22,"tag":13,"props":2212,"children":2213},{"__ignoreMap":7},[2214,2250,2277,2302],{"type":22,"tag":296,"props":2215,"children":2216},{"class":298,"line":299},[2217,2222,2226,2231,2236,2240,2245],{"type":22,"tag":296,"props":2218,"children":2219},{"style":852},[2220],{"type":27,"value":2221},"PreparedStatement stmt ",{"type":22,"tag":296,"props":2223,"children":2224},{"style":846},[2225],{"type":27,"value":985},{"type":22,"tag":296,"props":2227,"children":2228},{"style":852},[2229],{"type":27,"value":2230}," connection.",{"type":22,"tag":296,"props":2232,"children":2233},{"style":762},[2234],{"type":27,"value":2235},"prepareStatement",{"type":22,"tag":296,"props":2237,"children":2238},{"style":852},[2239],{"type":27,"value":1933},{"type":22,"tag":296,"props":2241,"children":2242},{"style":768},[2243],{"type":27,"value":2244},"\"SELECT * FROM users WHERE username=? AND password=?\"",{"type":22,"tag":296,"props":2246,"children":2247},{"style":852},[2248],{"type":27,"value":2249},");\n",{"type":22,"tag":296,"props":2251,"children":2252},{"class":298,"line":308},[2253,2258,2263,2267,2272],{"type":22,"tag":296,"props":2254,"children":2255},{"style":852},[2256],{"type":27,"value":2257},"stmt.",{"type":22,"tag":296,"props":2259,"children":2260},{"style":762},[2261],{"type":27,"value":2262},"setString",{"type":22,"tag":296,"props":2264,"children":2265},{"style":852},[2266],{"type":27,"value":1933},{"type":22,"tag":296,"props":2268,"children":2269},{"style":949},[2270],{"type":27,"value":2271},"1",{"type":22,"tag":296,"props":2273,"children":2274},{"style":852},[2275],{"type":27,"value":2276},", username);\n",{"type":22,"tag":296,"props":2278,"children":2279},{"class":298,"line":317},[2280,2284,2288,2292,2297],{"type":22,"tag":296,"props":2281,"children":2282},{"style":852},[2283],{"type":27,"value":2257},{"type":22,"tag":296,"props":2285,"children":2286},{"style":762},[2287],{"type":27,"value":2262},{"type":22,"tag":296,"props":2289,"children":2290},{"style":852},[2291],{"type":27,"value":1933},{"type":22,"tag":296,"props":2293,"children":2294},{"style":949},[2295],{"type":27,"value":2296},"2",{"type":22,"tag":296,"props":2298,"children":2299},{"style":852},[2300],{"type":27,"value":2301},", password);\n",{"type":22,"tag":296,"props":2303,"children":2304},{"class":298,"line":326},[2305,2310,2314,2319,2324],{"type":22,"tag":296,"props":2306,"children":2307},{"style":852},[2308],{"type":27,"value":2309},"ResultSet rs ",{"type":22,"tag":296,"props":2311,"children":2312},{"style":846},[2313],{"type":27,"value":985},{"type":22,"tag":296,"props":2315,"children":2316},{"style":852},[2317],{"type":27,"value":2318}," stmt.",{"type":22,"tag":296,"props":2320,"children":2321},{"style":762},[2322],{"type":27,"value":2323},"executeQuery",{"type":22,"tag":296,"props":2325,"children":2326},{"style":852},[2327],{"type":27,"value":2328},"();\n",{"type":22,"tag":23,"props":2330,"children":2331},{},[2332],{"type":27,"value":2333},"This approach prevents SQL injection by ensuring that input data is treated as data, not executable code.",{"type":22,"tag":30,"props":2335,"children":2337},{"id":2336},"_2-secure-authentication",[2338],{"type":27,"value":2339},"2. Secure Authentication",{"type":22,"tag":23,"props":2341,"children":2342},{},[2343],{"type":27,"value":2344},"Implement robust authentication using secure password storage (bcrypt or Argon2):",{"type":22,"tag":286,"props":2346,"children":2348},{"className":2208,"code":2347,"language":15,"meta":7,"style":7},"import org.springframework.security.crypto.bcrypt.BCrypt;\n\nString hashedPassword = BCrypt.hashpw(password, BCrypt.gensalt());\nif (BCrypt.checkpw(password, hashedPassword)) {\n    // authentication successful\n}\n",[2349],{"type":22,"tag":13,"props":2350,"children":2351},{"__ignoreMap":7},[2352,2364,2371,2408,2431,2440],{"type":22,"tag":296,"props":2353,"children":2354},{"class":298,"line":299},[2355,2359],{"type":22,"tag":296,"props":2356,"children":2357},{"style":846},[2358],{"type":27,"value":860},{"type":22,"tag":296,"props":2360,"children":2361},{"style":852},[2362],{"type":27,"value":2363}," org.springframework.security.crypto.bcrypt.BCrypt;\n",{"type":22,"tag":296,"props":2365,"children":2366},{"class":298,"line":308},[2367],{"type":22,"tag":296,"props":2368,"children":2369},{"emptyLinePlaceholder":925},[2370],{"type":27,"value":928},{"type":22,"tag":296,"props":2372,"children":2373},{"class":298,"line":317},[2374,2379,2383,2388,2393,2398,2403],{"type":22,"tag":296,"props":2375,"children":2376},{"style":852},[2377],{"type":27,"value":2378},"String hashedPassword ",{"type":22,"tag":296,"props":2380,"children":2381},{"style":846},[2382],{"type":27,"value":985},{"type":22,"tag":296,"props":2384,"children":2385},{"style":852},[2386],{"type":27,"value":2387}," BCrypt.",{"type":22,"tag":296,"props":2389,"children":2390},{"style":762},[2391],{"type":27,"value":2392},"hashpw",{"type":22,"tag":296,"props":2394,"children":2395},{"style":852},[2396],{"type":27,"value":2397},"(password, BCrypt.",{"type":22,"tag":296,"props":2399,"children":2400},{"style":762},[2401],{"type":27,"value":2402},"gensalt",{"type":22,"tag":296,"props":2404,"children":2405},{"style":852},[2406],{"type":27,"value":2407},"());\n",{"type":22,"tag":296,"props":2409,"children":2410},{"class":298,"line":326},[2411,2416,2421,2426],{"type":22,"tag":296,"props":2412,"children":2413},{"style":846},[2414],{"type":27,"value":2415},"if",{"type":22,"tag":296,"props":2417,"children":2418},{"style":852},[2419],{"type":27,"value":2420}," (BCrypt.",{"type":22,"tag":296,"props":2422,"children":2423},{"style":762},[2424],{"type":27,"value":2425},"checkpw",{"type":22,"tag":296,"props":2427,"children":2428},{"style":852},[2429],{"type":27,"value":2430},"(password, hashedPassword)) {\n",{"type":22,"tag":296,"props":2432,"children":2433},{"class":298,"line":335},[2434],{"type":22,"tag":296,"props":2435,"children":2437},{"style":2436},"--shiki-default:#6A737D;--shiki-light:#6A737D",[2438],{"type":27,"value":2439},"    // authentication successful\n",{"type":22,"tag":296,"props":2441,"children":2442},{"class":298,"line":344},[2443],{"type":22,"tag":296,"props":2444,"children":2445},{"style":852},[2446],{"type":27,"value":2447},"}\n",{"type":22,"tag":30,"props":2449,"children":2451},{"id":2450},"_3-sensitive-data-exposure",[2452],{"type":27,"value":2453},"3. Sensitive Data Exposure",{"type":22,"tag":23,"props":2455,"children":2456},{},[2457],{"type":27,"value":2458},"Use encryption for sensitive data storage:",{"type":22,"tag":286,"props":2460,"children":2462},{"className":2208,"code":2461,"language":15,"meta":7,"style":7},"Cipher cipher = Cipher.getInstance(\"AES/GCM/NoPadding\");\nSecretKey key = generateSecretKey();\ncipher.init(Cipher.ENCRYPT_MODE, key);\nbyte[] encryptedData = cipher.doFinal(plainData.getBytes(StandardCharsets.UTF_8));\n",[2463],{"type":22,"tag":13,"props":2464,"children":2465},{"__ignoreMap":7},[2466,2501,2522,2540],{"type":22,"tag":296,"props":2467,"children":2468},{"class":298,"line":299},[2469,2474,2478,2483,2488,2492,2497],{"type":22,"tag":296,"props":2470,"children":2471},{"style":852},[2472],{"type":27,"value":2473},"Cipher cipher ",{"type":22,"tag":296,"props":2475,"children":2476},{"style":846},[2477],{"type":27,"value":985},{"type":22,"tag":296,"props":2479,"children":2480},{"style":852},[2481],{"type":27,"value":2482}," Cipher.",{"type":22,"tag":296,"props":2484,"children":2485},{"style":762},[2486],{"type":27,"value":2487},"getInstance",{"type":22,"tag":296,"props":2489,"children":2490},{"style":852},[2491],{"type":27,"value":1933},{"type":22,"tag":296,"props":2493,"children":2494},{"style":768},[2495],{"type":27,"value":2496},"\"AES/GCM/NoPadding\"",{"type":22,"tag":296,"props":2498,"children":2499},{"style":852},[2500],{"type":27,"value":2249},{"type":22,"tag":296,"props":2502,"children":2503},{"class":298,"line":308},[2504,2509,2513,2518],{"type":22,"tag":296,"props":2505,"children":2506},{"style":852},[2507],{"type":27,"value":2508},"SecretKey key ",{"type":22,"tag":296,"props":2510,"children":2511},{"style":846},[2512],{"type":27,"value":985},{"type":22,"tag":296,"props":2514,"children":2515},{"style":762},[2516],{"type":27,"value":2517}," generateSecretKey",{"type":22,"tag":296,"props":2519,"children":2520},{"style":852},[2521],{"type":27,"value":2328},{"type":22,"tag":296,"props":2523,"children":2524},{"class":298,"line":317},[2525,2530,2535],{"type":22,"tag":296,"props":2526,"children":2527},{"style":852},[2528],{"type":27,"value":2529},"cipher.",{"type":22,"tag":296,"props":2531,"children":2532},{"style":762},[2533],{"type":27,"value":2534},"init",{"type":22,"tag":296,"props":2536,"children":2537},{"style":852},[2538],{"type":27,"value":2539},"(Cipher.ENCRYPT_MODE, key);\n",{"type":22,"tag":296,"props":2541,"children":2542},{"class":298,"line":326},[2543,2548,2553,2557,2562,2567,2572,2577],{"type":22,"tag":296,"props":2544,"children":2545},{"style":846},[2546],{"type":27,"value":2547},"byte",{"type":22,"tag":296,"props":2549,"children":2550},{"style":852},[2551],{"type":27,"value":2552},"[] encryptedData ",{"type":22,"tag":296,"props":2554,"children":2555},{"style":846},[2556],{"type":27,"value":985},{"type":22,"tag":296,"props":2558,"children":2559},{"style":852},[2560],{"type":27,"value":2561}," cipher.",{"type":22,"tag":296,"props":2563,"children":2564},{"style":762},[2565],{"type":27,"value":2566},"doFinal",{"type":22,"tag":296,"props":2568,"children":2569},{"style":852},[2570],{"type":27,"value":2571},"(plainData.",{"type":22,"tag":296,"props":2573,"children":2574},{"style":762},[2575],{"type":27,"value":2576},"getBytes",{"type":22,"tag":296,"props":2578,"children":2579},{"style":852},[2580],{"type":27,"value":2581},"(StandardCharsets.UTF_8));\n",{"type":22,"tag":23,"props":2583,"children":2584},{},[2585],{"type":27,"value":2586},"Always encrypt data at rest and in transit (use HTTPS).",{"type":22,"tag":30,"props":2588,"children":2590},{"id":2589},"_4-security-misconfiguration",[2591],{"type":27,"value":2592},"4. Security Misconfiguration",{"type":22,"tag":23,"props":2594,"children":2595},{},[2596],{"type":27,"value":2597},"Adopt secure defaults, disable debugging, and avoid detailed error messages:",{"type":22,"tag":286,"props":2599,"children":2603},{"className":2600,"code":2601,"language":2602,"meta":7,"style":7},"language-properties shiki shiki-themes github-dark github-light","server.error.include-stacktrace=never\nserver.error.include-message=never\n","properties",[2604],{"type":22,"tag":13,"props":2605,"children":2606},{"__ignoreMap":7},[2607,2615],{"type":22,"tag":296,"props":2608,"children":2609},{"class":298,"line":299},[2610],{"type":22,"tag":296,"props":2611,"children":2612},{},[2613],{"type":27,"value":2614},"server.error.include-stacktrace=never\n",{"type":22,"tag":296,"props":2616,"children":2617},{"class":298,"line":308},[2618],{"type":22,"tag":296,"props":2619,"children":2620},{},[2621],{"type":27,"value":2622},"server.error.include-message=never\n",{"type":22,"tag":23,"props":2624,"children":2625},{},[2626],{"type":27,"value":2627},"Review and secure your Java application configuration regularly.",{"type":22,"tag":30,"props":2629,"children":2631},{"id":2630},"_5-cross-site-scripting-xss",[2632],{"type":27,"value":2633},"5. Cross-Site Scripting (XSS)",{"type":22,"tag":23,"props":2635,"children":2636},{},[2637],{"type":27,"value":2638},"Utilize proper encoding or frameworks that prevent XSS by default, such as Thymeleaf:",{"type":22,"tag":286,"props":2640,"children":2644},{"className":2641,"code":2642,"language":2643,"meta":7,"style":7},"language-html shiki shiki-themes github-dark github-light","\u003Cp th:text=\"${userInput}\">\u003C/p>\n","html",[2645],{"type":22,"tag":13,"props":2646,"children":2647},{"__ignoreMap":7},[2648],{"type":22,"tag":296,"props":2649,"children":2650},{"class":298,"line":299},[2651],{"type":22,"tag":296,"props":2652,"children":2653},{},[2654],{"type":27,"value":2642},{"type":22,"tag":23,"props":2656,"children":2657},{},[2658],{"type":27,"value":2659},"Avoid directly inserting user inputs into HTML without proper sanitization or encoding.",{"type":22,"tag":30,"props":2661,"children":2663},{"id":2662},"_6-insecure-deserialization",[2664],{"type":27,"value":2665},"6. Insecure Deserialization",{"type":22,"tag":23,"props":2667,"children":2668},{},[2669],{"type":27,"value":2670},"Limit deserialization to trusted sources only:",{"type":22,"tag":286,"props":2672,"children":2674},{"className":2208,"code":2673,"language":15,"meta":7,"style":7},"ObjectInputStream ois = new ObjectInputStream(new FileInputStream(\"trusted_data.ser\"));\nMyObject obj = (MyObject) ois.readObject();\n",[2675],{"type":22,"tag":13,"props":2676,"children":2677},{"__ignoreMap":7},[2678,2728],{"type":22,"tag":296,"props":2679,"children":2680},{"class":298,"line":299},[2681,2686,2690,2695,2700,2704,2709,2714,2718,2723],{"type":22,"tag":296,"props":2682,"children":2683},{"style":852},[2684],{"type":27,"value":2685},"ObjectInputStream ois ",{"type":22,"tag":296,"props":2687,"children":2688},{"style":846},[2689],{"type":27,"value":985},{"type":22,"tag":296,"props":2691,"children":2692},{"style":846},[2693],{"type":27,"value":2694}," new",{"type":22,"tag":296,"props":2696,"children":2697},{"style":762},[2698],{"type":27,"value":2699}," ObjectInputStream",{"type":22,"tag":296,"props":2701,"children":2702},{"style":852},[2703],{"type":27,"value":1933},{"type":22,"tag":296,"props":2705,"children":2706},{"style":846},[2707],{"type":27,"value":2708},"new",{"type":22,"tag":296,"props":2710,"children":2711},{"style":762},[2712],{"type":27,"value":2713}," FileInputStream",{"type":22,"tag":296,"props":2715,"children":2716},{"style":852},[2717],{"type":27,"value":1933},{"type":22,"tag":296,"props":2719,"children":2720},{"style":768},[2721],{"type":27,"value":2722},"\"trusted_data.ser\"",{"type":22,"tag":296,"props":2724,"children":2725},{"style":852},[2726],{"type":27,"value":2727},"));\n",{"type":22,"tag":296,"props":2729,"children":2730},{"class":298,"line":308},[2731,2736,2740,2745,2750],{"type":22,"tag":296,"props":2732,"children":2733},{"style":852},[2734],{"type":27,"value":2735},"MyObject obj ",{"type":22,"tag":296,"props":2737,"children":2738},{"style":846},[2739],{"type":27,"value":985},{"type":22,"tag":296,"props":2741,"children":2742},{"style":852},[2743],{"type":27,"value":2744}," (MyObject) ois.",{"type":22,"tag":296,"props":2746,"children":2747},{"style":762},[2748],{"type":27,"value":2749},"readObject",{"type":22,"tag":296,"props":2751,"children":2752},{"style":852},[2753],{"type":27,"value":2328},{"type":22,"tag":23,"props":2755,"children":2756},{},[2757],{"type":27,"value":2758},"Always validate deserialized data.",{"type":22,"tag":30,"props":2760,"children":2762},{"id":2761},"_7-component-vulnerabilities",[2763],{"type":27,"value":2764},"7. Component Vulnerabilities",{"type":22,"tag":23,"props":2766,"children":2767},{},[2768],{"type":27,"value":2769},"Regularly update libraries and dependencies, and use tools like OWASP Dependency-Check to identify vulnerabilities:",{"type":22,"tag":286,"props":2771,"children":2775},{"className":2772,"code":2773,"language":2774,"meta":7,"style":7},"language-xml shiki shiki-themes github-dark github-light","\u003Cplugin>\n    \u003CgroupId>org.owasp\u003C/groupId>\n    \u003CartifactId>dependency-check-maven\u003C/artifactId>\n    \u003Cversion>9.0.9\u003C/version>\n\u003C/plugin>\n","xml",[2776],{"type":22,"tag":13,"props":2777,"children":2778},{"__ignoreMap":7},[2779,2798,2824,2849,2874],{"type":22,"tag":296,"props":2780,"children":2781},{"class":298,"line":299},[2782,2787,2793],{"type":22,"tag":296,"props":2783,"children":2784},{"style":852},[2785],{"type":27,"value":2786},"\u003C",{"type":22,"tag":296,"props":2788,"children":2790},{"style":2789},"--shiki-default:#85E89D;--shiki-light:#22863A",[2791],{"type":27,"value":2792},"plugin",{"type":22,"tag":296,"props":2794,"children":2795},{"style":852},[2796],{"type":27,"value":2797},">\n",{"type":22,"tag":296,"props":2799,"children":2800},{"class":298,"line":308},[2801,2806,2811,2816,2820],{"type":22,"tag":296,"props":2802,"children":2803},{"style":852},[2804],{"type":27,"value":2805},"    \u003C",{"type":22,"tag":296,"props":2807,"children":2808},{"style":2789},[2809],{"type":27,"value":2810},"groupId",{"type":22,"tag":296,"props":2812,"children":2813},{"style":852},[2814],{"type":27,"value":2815},">org.owasp\u003C/",{"type":22,"tag":296,"props":2817,"children":2818},{"style":2789},[2819],{"type":27,"value":2810},{"type":22,"tag":296,"props":2821,"children":2822},{"style":852},[2823],{"type":27,"value":2797},{"type":22,"tag":296,"props":2825,"children":2826},{"class":298,"line":317},[2827,2831,2836,2841,2845],{"type":22,"tag":296,"props":2828,"children":2829},{"style":852},[2830],{"type":27,"value":2805},{"type":22,"tag":296,"props":2832,"children":2833},{"style":2789},[2834],{"type":27,"value":2835},"artifactId",{"type":22,"tag":296,"props":2837,"children":2838},{"style":852},[2839],{"type":27,"value":2840},">dependency-check-maven\u003C/",{"type":22,"tag":296,"props":2842,"children":2843},{"style":2789},[2844],{"type":27,"value":2835},{"type":22,"tag":296,"props":2846,"children":2847},{"style":852},[2848],{"type":27,"value":2797},{"type":22,"tag":296,"props":2850,"children":2851},{"class":298,"line":326},[2852,2856,2861,2866,2870],{"type":22,"tag":296,"props":2853,"children":2854},{"style":852},[2855],{"type":27,"value":2805},{"type":22,"tag":296,"props":2857,"children":2858},{"style":2789},[2859],{"type":27,"value":2860},"version",{"type":22,"tag":296,"props":2862,"children":2863},{"style":852},[2864],{"type":27,"value":2865},">9.0.9\u003C/",{"type":22,"tag":296,"props":2867,"children":2868},{"style":2789},[2869],{"type":27,"value":2860},{"type":22,"tag":296,"props":2871,"children":2872},{"style":852},[2873],{"type":27,"value":2797},{"type":22,"tag":296,"props":2875,"children":2876},{"class":298,"line":335},[2877,2882,2886],{"type":22,"tag":296,"props":2878,"children":2879},{"style":852},[2880],{"type":27,"value":2881},"\u003C/",{"type":22,"tag":296,"props":2883,"children":2884},{"style":2789},[2885],{"type":27,"value":2792},{"type":22,"tag":296,"props":2887,"children":2888},{"style":852},[2889],{"type":27,"value":2797},{"type":22,"tag":23,"props":2891,"children":2892},{},[2893],{"type":27,"value":2894},"Execute dependency checks regularly in your CI/CD pipeline.",{"type":22,"tag":30,"props":2896,"children":2898},{"id":2897},"_8-logging-and-monitoring",[2899],{"type":27,"value":2900},"8. Logging and Monitoring",{"type":22,"tag":23,"props":2902,"children":2903},{},[2904],{"type":27,"value":2905},"Implement comprehensive logging and monitoring to detect and respond to security incidents:",{"type":22,"tag":286,"props":2907,"children":2909},{"className":2208,"code":2908,"language":15,"meta":7,"style":7},"logger.warn(\"Failed login attempt for user: {}\", username);\n",[2910],{"type":22,"tag":13,"props":2911,"children":2912},{"__ignoreMap":7},[2913],{"type":22,"tag":296,"props":2914,"children":2915},{"class":298,"line":299},[2916,2921,2926,2930,2935],{"type":22,"tag":296,"props":2917,"children":2918},{"style":852},[2919],{"type":27,"value":2920},"logger.",{"type":22,"tag":296,"props":2922,"children":2923},{"style":762},[2924],{"type":27,"value":2925},"warn",{"type":22,"tag":296,"props":2927,"children":2928},{"style":852},[2929],{"type":27,"value":1933},{"type":22,"tag":296,"props":2931,"children":2932},{"style":768},[2933],{"type":27,"value":2934},"\"Failed login attempt for user: {}\"",{"type":22,"tag":296,"props":2936,"children":2937},{"style":852},[2938],{"type":27,"value":2276},{"type":22,"tag":23,"props":2940,"children":2941},{},[2942],{"type":27,"value":2943},"Aggregate logs centrally, and set up alerts for suspicious activities.",{"type":22,"tag":30,"props":2945,"children":2947},{"id":2946},"conclusion",[2948],{"type":27,"value":2949},"Conclusion",{"type":22,"tag":23,"props":2951,"children":2952},{},[2953],{"type":27,"value":2954},"Adopting these best practices can greatly enhance the security posture of your Java applications. Stay proactive by regularly reviewing security measures, updating dependencies, and monitoring your systems. Security is a continuous process, not a one-time setup.",{"type":22,"tag":2048,"props":2956,"children":2957},{"id":618},[2958],{"type":27,"value":621},{"type":22,"tag":207,"props":2960,"children":2961},{},[2962,2972,2982],{"type":22,"tag":66,"props":2963,"children":2964},{},[2965],{"type":22,"tag":113,"props":2966,"children":2969},{"href":2967,"rel":2968},"https://owasp.org/www-project-top-ten/",[640],[2970],{"type":27,"value":2971},"OWASP Top 10",{"type":22,"tag":66,"props":2973,"children":2974},{},[2975],{"type":22,"tag":113,"props":2976,"children":2979},{"href":2977,"rel":2978},"https://spring.io/projects/spring-security",[640],[2980],{"type":27,"value":2981},"Spring Security",{"type":22,"tag":66,"props":2983,"children":2984},{},[2985],{"type":22,"tag":113,"props":2986,"children":2989},{"href":2987,"rel":2988},"https://owasp.org/www-project-dependency-check/",[640],[2990],{"type":27,"value":2991},"OWASP Dependency Check",{"type":22,"tag":667,"props":2993,"children":2994},{},[2995],{"type":27,"value":671},{"title":7,"searchDepth":308,"depth":308,"links":2997},[2998,2999,3000,3001,3002,3003,3004,3005,3006,3007],{"id":2128,"depth":308,"text":2131},{"id":2197,"depth":308,"text":2200},{"id":2336,"depth":308,"text":2339},{"id":2450,"depth":308,"text":2453},{"id":2589,"depth":308,"text":2592},{"id":2630,"depth":308,"text":2633},{"id":2662,"depth":308,"text":2665},{"id":2761,"depth":308,"text":2764},{"id":2897,"depth":308,"text":2900},{"id":2946,"depth":308,"text":2949},"content:posts:java-security-best-practices.md","posts/java-security-best-practices.md","posts/java-security-best-practices",{"_path":3012,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":3013,"description":3014,"date":3015,"layout":10,"subtitle":3016,"image":3017,"optimized_image":3017,"category":13,"tags":3018,"author":17,"paginate":6,"body":3022,"_type":682,"_id":3826,"_source":684,"_file":3827,"_stem":3828,"_extension":687},"/posts/circuit-breaking-resilience","Circuit Breaking in Distributed Systems","An expert guide to understanding and implementing circuit breakers in distributed systems, with practical Java examples using Resilience4j and best practices.","2024-07-15T11:00:00.000Z","Enhancing Resilience with Circuit Breaker Patterns","/assets/img/uploads/circuit-breaking-resilience.png",[13,15,3019,3020,3021],"resilience","circuit-breaker","distributed-systems",{"type":19,"children":3023,"toc":3814},[3024,3032,3038,3043,3076,3081,3087,3092,3110,3116,3122,3127,3237,3243,3447,3453,3458,3625,3631,3636,3730,3735,3741,3764,3768,3773,3777,3810],{"type":22,"tag":705,"props":3025,"children":3026},{},[3027],{"type":22,"tag":23,"props":3028,"children":3029},{},[3030],{"type":27,"value":3031},"In modern distributed systems, failures are inevitable. The circuit breaker pattern helps maintain system stability by preventing failures from cascading across service boundaries. In this post, we'll dive deep into circuit breakers, explore their importance, and demonstrate practical implementation using Resilience4j in Java.",{"type":22,"tag":30,"props":3033,"children":3035},{"id":3034},"understanding-the-circuit-breaker-pattern",[3036],{"type":27,"value":3037},"Understanding the Circuit Breaker Pattern",{"type":22,"tag":23,"props":3039,"children":3040},{},[3041],{"type":27,"value":3042},"The circuit breaker pattern prevents a service from making repeated calls to an external service that is experiencing issues. It has three main states:",{"type":22,"tag":207,"props":3044,"children":3045},{},[3046,3056,3066],{"type":22,"tag":66,"props":3047,"children":3048},{},[3049,3054],{"type":22,"tag":42,"props":3050,"children":3051},{},[3052],{"type":27,"value":3053},"Closed:",{"type":27,"value":3055}," All requests pass through normally.",{"type":22,"tag":66,"props":3057,"children":3058},{},[3059,3064],{"type":22,"tag":42,"props":3060,"children":3061},{},[3062],{"type":27,"value":3063},"Open:",{"type":27,"value":3065}," Requests fail fast, bypassing the problematic service.",{"type":22,"tag":66,"props":3067,"children":3068},{},[3069,3074],{"type":22,"tag":42,"props":3070,"children":3071},{},[3072],{"type":27,"value":3073},"Half-Open:",{"type":27,"value":3075}," A limited number of requests test if the external service has recovered.",{"type":22,"tag":23,"props":3077,"children":3078},{},[3079],{"type":27,"value":3080},"This mechanism helps improve the resilience and responsiveness of your systems.",{"type":22,"tag":30,"props":3082,"children":3084},{"id":3083},"when-to-use-circuit-breakers",[3085],{"type":27,"value":3086},"When to Use Circuit Breakers",{"type":22,"tag":23,"props":3088,"children":3089},{},[3090],{"type":27,"value":3091},"Circuit breakers are essential when:",{"type":22,"tag":207,"props":3093,"children":3094},{},[3095,3100,3105],{"type":22,"tag":66,"props":3096,"children":3097},{},[3098],{"type":27,"value":3099},"Your system relies on remote calls (microservices architecture, external APIs).",{"type":22,"tag":66,"props":3101,"children":3102},{},[3103],{"type":27,"value":3104},"You need to prevent failure propagation.",{"type":22,"tag":66,"props":3106,"children":3107},{},[3108],{"type":27,"value":3109},"You aim to improve user experience by quickly responding to failures.",{"type":22,"tag":30,"props":3111,"children":3113},{"id":3112},"implementing-circuit-breakers-with-resilience4j",[3114],{"type":27,"value":3115},"Implementing Circuit Breakers with Resilience4j",{"type":22,"tag":195,"props":3117,"children":3119},{"id":3118},"step-1-adding-dependencies",[3120],{"type":27,"value":3121},"Step 1: Adding Dependencies",{"type":22,"tag":23,"props":3123,"children":3124},{},[3125],{"type":27,"value":3126},"Add Resilience4j dependencies to your project (Maven example):",{"type":22,"tag":286,"props":3128,"children":3130},{"className":2772,"code":3129,"language":2774,"meta":7,"style":7},"\u003Cdependency>\n    \u003CgroupId>io.github.resilience4j\u003C/groupId>\n    \u003CartifactId>resilience4j-circuitbreaker\u003C/artifactId>\n    \u003Cversion>2.0.2\u003C/version>\n\u003C/dependency>\n",[3131],{"type":22,"tag":13,"props":3132,"children":3133},{"__ignoreMap":7},[3134,3150,3174,3198,3222],{"type":22,"tag":296,"props":3135,"children":3136},{"class":298,"line":299},[3137,3141,3146],{"type":22,"tag":296,"props":3138,"children":3139},{"style":852},[3140],{"type":27,"value":2786},{"type":22,"tag":296,"props":3142,"children":3143},{"style":2789},[3144],{"type":27,"value":3145},"dependency",{"type":22,"tag":296,"props":3147,"children":3148},{"style":852},[3149],{"type":27,"value":2797},{"type":22,"tag":296,"props":3151,"children":3152},{"class":298,"line":308},[3153,3157,3161,3166,3170],{"type":22,"tag":296,"props":3154,"children":3155},{"style":852},[3156],{"type":27,"value":2805},{"type":22,"tag":296,"props":3158,"children":3159},{"style":2789},[3160],{"type":27,"value":2810},{"type":22,"tag":296,"props":3162,"children":3163},{"style":852},[3164],{"type":27,"value":3165},">io.github.resilience4j\u003C/",{"type":22,"tag":296,"props":3167,"children":3168},{"style":2789},[3169],{"type":27,"value":2810},{"type":22,"tag":296,"props":3171,"children":3172},{"style":852},[3173],{"type":27,"value":2797},{"type":22,"tag":296,"props":3175,"children":3176},{"class":298,"line":317},[3177,3181,3185,3190,3194],{"type":22,"tag":296,"props":3178,"children":3179},{"style":852},[3180],{"type":27,"value":2805},{"type":22,"tag":296,"props":3182,"children":3183},{"style":2789},[3184],{"type":27,"value":2835},{"type":22,"tag":296,"props":3186,"children":3187},{"style":852},[3188],{"type":27,"value":3189},">resilience4j-circuitbreaker\u003C/",{"type":22,"tag":296,"props":3191,"children":3192},{"style":2789},[3193],{"type":27,"value":2835},{"type":22,"tag":296,"props":3195,"children":3196},{"style":852},[3197],{"type":27,"value":2797},{"type":22,"tag":296,"props":3199,"children":3200},{"class":298,"line":326},[3201,3205,3209,3214,3218],{"type":22,"tag":296,"props":3202,"children":3203},{"style":852},[3204],{"type":27,"value":2805},{"type":22,"tag":296,"props":3206,"children":3207},{"style":2789},[3208],{"type":27,"value":2860},{"type":22,"tag":296,"props":3210,"children":3211},{"style":852},[3212],{"type":27,"value":3213},">2.0.2\u003C/",{"type":22,"tag":296,"props":3215,"children":3216},{"style":2789},[3217],{"type":27,"value":2860},{"type":22,"tag":296,"props":3219,"children":3220},{"style":852},[3221],{"type":27,"value":2797},{"type":22,"tag":296,"props":3223,"children":3224},{"class":298,"line":335},[3225,3229,3233],{"type":22,"tag":296,"props":3226,"children":3227},{"style":852},[3228],{"type":27,"value":2881},{"type":22,"tag":296,"props":3230,"children":3231},{"style":2789},[3232],{"type":27,"value":3145},{"type":22,"tag":296,"props":3234,"children":3235},{"style":852},[3236],{"type":27,"value":2797},{"type":22,"tag":195,"props":3238,"children":3240},{"id":3239},"step-2-configuring-circuit-breaker",[3241],{"type":27,"value":3242},"Step 2: Configuring Circuit Breaker",{"type":22,"tag":286,"props":3244,"children":3246},{"className":2208,"code":3245,"language":15,"meta":7,"style":7},"CircuitBreakerConfig config = CircuitBreakerConfig.custom()\n    .failureRateThreshold(50)\n    .waitDurationInOpenState(Duration.ofMillis(1000))\n    .permittedNumberOfCallsInHalfOpenState(2)\n    .minimumNumberOfCalls(5)\n    .build();\n\nCircuitBreaker circuitBreaker = CircuitBreaker.of(\"myService\", config);\n",[3247],{"type":22,"tag":13,"props":3248,"children":3249},{"__ignoreMap":7},[3250,3277,3303,3339,3363,3388,3404,3411],{"type":22,"tag":296,"props":3251,"children":3252},{"class":298,"line":299},[3253,3258,3262,3267,3272],{"type":22,"tag":296,"props":3254,"children":3255},{"style":852},[3256],{"type":27,"value":3257},"CircuitBreakerConfig config ",{"type":22,"tag":296,"props":3259,"children":3260},{"style":846},[3261],{"type":27,"value":985},{"type":22,"tag":296,"props":3263,"children":3264},{"style":852},[3265],{"type":27,"value":3266}," CircuitBreakerConfig.",{"type":22,"tag":296,"props":3268,"children":3269},{"style":762},[3270],{"type":27,"value":3271},"custom",{"type":22,"tag":296,"props":3273,"children":3274},{"style":852},[3275],{"type":27,"value":3276},"()\n",{"type":22,"tag":296,"props":3278,"children":3279},{"class":298,"line":308},[3280,3285,3290,3294,3299],{"type":22,"tag":296,"props":3281,"children":3282},{"style":852},[3283],{"type":27,"value":3284},"    .",{"type":22,"tag":296,"props":3286,"children":3287},{"style":762},[3288],{"type":27,"value":3289},"failureRateThreshold",{"type":22,"tag":296,"props":3291,"children":3292},{"style":852},[3293],{"type":27,"value":1933},{"type":22,"tag":296,"props":3295,"children":3296},{"style":949},[3297],{"type":27,"value":3298},"50",{"type":22,"tag":296,"props":3300,"children":3301},{"style":852},[3302],{"type":27,"value":972},{"type":22,"tag":296,"props":3304,"children":3305},{"class":298,"line":317},[3306,3310,3315,3320,3325,3329,3334],{"type":22,"tag":296,"props":3307,"children":3308},{"style":852},[3309],{"type":27,"value":3284},{"type":22,"tag":296,"props":3311,"children":3312},{"style":762},[3313],{"type":27,"value":3314},"waitDurationInOpenState",{"type":22,"tag":296,"props":3316,"children":3317},{"style":852},[3318],{"type":27,"value":3319},"(Duration.",{"type":22,"tag":296,"props":3321,"children":3322},{"style":762},[3323],{"type":27,"value":3324},"ofMillis",{"type":22,"tag":296,"props":3326,"children":3327},{"style":852},[3328],{"type":27,"value":1933},{"type":22,"tag":296,"props":3330,"children":3331},{"style":949},[3332],{"type":27,"value":3333},"1000",{"type":22,"tag":296,"props":3335,"children":3336},{"style":852},[3337],{"type":27,"value":3338},"))\n",{"type":22,"tag":296,"props":3340,"children":3341},{"class":298,"line":326},[3342,3346,3351,3355,3359],{"type":22,"tag":296,"props":3343,"children":3344},{"style":852},[3345],{"type":27,"value":3284},{"type":22,"tag":296,"props":3347,"children":3348},{"style":762},[3349],{"type":27,"value":3350},"permittedNumberOfCallsInHalfOpenState",{"type":22,"tag":296,"props":3352,"children":3353},{"style":852},[3354],{"type":27,"value":1933},{"type":22,"tag":296,"props":3356,"children":3357},{"style":949},[3358],{"type":27,"value":2296},{"type":22,"tag":296,"props":3360,"children":3361},{"style":852},[3362],{"type":27,"value":972},{"type":22,"tag":296,"props":3364,"children":3365},{"class":298,"line":335},[3366,3370,3375,3379,3384],{"type":22,"tag":296,"props":3367,"children":3368},{"style":852},[3369],{"type":27,"value":3284},{"type":22,"tag":296,"props":3371,"children":3372},{"style":762},[3373],{"type":27,"value":3374},"minimumNumberOfCalls",{"type":22,"tag":296,"props":3376,"children":3377},{"style":852},[3378],{"type":27,"value":1933},{"type":22,"tag":296,"props":3380,"children":3381},{"style":949},[3382],{"type":27,"value":3383},"5",{"type":22,"tag":296,"props":3385,"children":3386},{"style":852},[3387],{"type":27,"value":972},{"type":22,"tag":296,"props":3389,"children":3390},{"class":298,"line":344},[3391,3395,3400],{"type":22,"tag":296,"props":3392,"children":3393},{"style":852},[3394],{"type":27,"value":3284},{"type":22,"tag":296,"props":3396,"children":3397},{"style":762},[3398],{"type":27,"value":3399},"build",{"type":22,"tag":296,"props":3401,"children":3402},{"style":852},[3403],{"type":27,"value":2328},{"type":22,"tag":296,"props":3405,"children":3406},{"class":298,"line":353},[3407],{"type":22,"tag":296,"props":3408,"children":3409},{"emptyLinePlaceholder":925},[3410],{"type":27,"value":928},{"type":22,"tag":296,"props":3412,"children":3413},{"class":298,"line":362},[3414,3419,3423,3428,3433,3437,3442],{"type":22,"tag":296,"props":3415,"children":3416},{"style":852},[3417],{"type":27,"value":3418},"CircuitBreaker circuitBreaker ",{"type":22,"tag":296,"props":3420,"children":3421},{"style":846},[3422],{"type":27,"value":985},{"type":22,"tag":296,"props":3424,"children":3425},{"style":852},[3426],{"type":27,"value":3427}," CircuitBreaker.",{"type":22,"tag":296,"props":3429,"children":3430},{"style":762},[3431],{"type":27,"value":3432},"of",{"type":22,"tag":296,"props":3434,"children":3435},{"style":852},[3436],{"type":27,"value":1933},{"type":22,"tag":296,"props":3438,"children":3439},{"style":768},[3440],{"type":27,"value":3441},"\"myService\"",{"type":22,"tag":296,"props":3443,"children":3444},{"style":852},[3445],{"type":27,"value":3446},", config);\n",{"type":22,"tag":195,"props":3448,"children":3450},{"id":3449},"step-3-using-circuit-breaker",[3451],{"type":27,"value":3452},"Step 3: Using Circuit Breaker",{"type":22,"tag":23,"props":3454,"children":3455},{},[3456],{"type":27,"value":3457},"Wrap service calls using the circuit breaker:",{"type":22,"tag":286,"props":3459,"children":3461},{"className":2208,"code":3460,"language":15,"meta":7,"style":7},"Supplier\u003CString> decoratedSupplier = CircuitBreaker.decorateSupplier(circuitBreaker, () -> myService.remoteCall());\n\nTry.ofSupplier(decoratedSupplier)\n    .recover(throwable -> \"Fallback response\")\n    .onSuccess(result -> System.out.println(\"Response: \" + result));\n",[3462],{"type":22,"tag":13,"props":3463,"children":3464},{"__ignoreMap":7},[3465,3520,3527,3545,3575],{"type":22,"tag":296,"props":3466,"children":3467},{"class":298,"line":299},[3468,3473,3478,3483,3487,3491,3496,3501,3506,3511,3516],{"type":22,"tag":296,"props":3469,"children":3470},{"style":852},[3471],{"type":27,"value":3472},"Supplier\u003C",{"type":22,"tag":296,"props":3474,"children":3475},{"style":846},[3476],{"type":27,"value":3477},"String",{"type":22,"tag":296,"props":3479,"children":3480},{"style":852},[3481],{"type":27,"value":3482},"> decoratedSupplier ",{"type":22,"tag":296,"props":3484,"children":3485},{"style":846},[3486],{"type":27,"value":985},{"type":22,"tag":296,"props":3488,"children":3489},{"style":852},[3490],{"type":27,"value":3427},{"type":22,"tag":296,"props":3492,"children":3493},{"style":762},[3494],{"type":27,"value":3495},"decorateSupplier",{"type":22,"tag":296,"props":3497,"children":3498},{"style":852},[3499],{"type":27,"value":3500},"(circuitBreaker, () ",{"type":22,"tag":296,"props":3502,"children":3503},{"style":846},[3504],{"type":27,"value":3505},"->",{"type":22,"tag":296,"props":3507,"children":3508},{"style":852},[3509],{"type":27,"value":3510}," myService.",{"type":22,"tag":296,"props":3512,"children":3513},{"style":762},[3514],{"type":27,"value":3515},"remoteCall",{"type":22,"tag":296,"props":3517,"children":3518},{"style":852},[3519],{"type":27,"value":2407},{"type":22,"tag":296,"props":3521,"children":3522},{"class":298,"line":308},[3523],{"type":22,"tag":296,"props":3524,"children":3525},{"emptyLinePlaceholder":925},[3526],{"type":27,"value":928},{"type":22,"tag":296,"props":3528,"children":3529},{"class":298,"line":317},[3530,3535,3540],{"type":22,"tag":296,"props":3531,"children":3532},{"style":852},[3533],{"type":27,"value":3534},"Try.",{"type":22,"tag":296,"props":3536,"children":3537},{"style":762},[3538],{"type":27,"value":3539},"ofSupplier",{"type":22,"tag":296,"props":3541,"children":3542},{"style":852},[3543],{"type":27,"value":3544},"(decoratedSupplier)\n",{"type":22,"tag":296,"props":3546,"children":3547},{"class":298,"line":326},[3548,3552,3557,3562,3566,3571],{"type":22,"tag":296,"props":3549,"children":3550},{"style":852},[3551],{"type":27,"value":3284},{"type":22,"tag":296,"props":3553,"children":3554},{"style":762},[3555],{"type":27,"value":3556},"recover",{"type":22,"tag":296,"props":3558,"children":3559},{"style":852},[3560],{"type":27,"value":3561},"(throwable ",{"type":22,"tag":296,"props":3563,"children":3564},{"style":846},[3565],{"type":27,"value":3505},{"type":22,"tag":296,"props":3567,"children":3568},{"style":768},[3569],{"type":27,"value":3570}," \"Fallback response\"",{"type":22,"tag":296,"props":3572,"children":3573},{"style":852},[3574],{"type":27,"value":972},{"type":22,"tag":296,"props":3576,"children":3577},{"class":298,"line":335},[3578,3582,3587,3592,3596,3601,3606,3610,3615,3620],{"type":22,"tag":296,"props":3579,"children":3580},{"style":852},[3581],{"type":27,"value":3284},{"type":22,"tag":296,"props":3583,"children":3584},{"style":762},[3585],{"type":27,"value":3586},"onSuccess",{"type":22,"tag":296,"props":3588,"children":3589},{"style":852},[3590],{"type":27,"value":3591},"(result ",{"type":22,"tag":296,"props":3593,"children":3594},{"style":846},[3595],{"type":27,"value":3505},{"type":22,"tag":296,"props":3597,"children":3598},{"style":852},[3599],{"type":27,"value":3600}," System.out.",{"type":22,"tag":296,"props":3602,"children":3603},{"style":762},[3604],{"type":27,"value":3605},"println",{"type":22,"tag":296,"props":3607,"children":3608},{"style":852},[3609],{"type":27,"value":1933},{"type":22,"tag":296,"props":3611,"children":3612},{"style":768},[3613],{"type":27,"value":3614},"\"Response: \"",{"type":22,"tag":296,"props":3616,"children":3617},{"style":846},[3618],{"type":27,"value":3619}," +",{"type":22,"tag":296,"props":3621,"children":3622},{"style":852},[3623],{"type":27,"value":3624}," result));\n",{"type":22,"tag":30,"props":3626,"children":3628},{"id":3627},"monitoring-and-metrics",[3629],{"type":27,"value":3630},"Monitoring and Metrics",{"type":22,"tag":23,"props":3632,"children":3633},{},[3634],{"type":27,"value":3635},"Resilience4j provides built-in support for metrics and monitoring:",{"type":22,"tag":286,"props":3637,"children":3639},{"className":2208,"code":3638,"language":15,"meta":7,"style":7},"CircuitBreakerRegistry registry = CircuitBreakerRegistry.ofDefaults();\nregistry.getEventPublisher()\n    .onStateTransition(event -> System.out.println(event.getStateTransition()));\n",[3640],{"type":22,"tag":13,"props":3641,"children":3642},{"__ignoreMap":7},[3643,3669,3686],{"type":22,"tag":296,"props":3644,"children":3645},{"class":298,"line":299},[3646,3651,3655,3660,3665],{"type":22,"tag":296,"props":3647,"children":3648},{"style":852},[3649],{"type":27,"value":3650},"CircuitBreakerRegistry registry ",{"type":22,"tag":296,"props":3652,"children":3653},{"style":846},[3654],{"type":27,"value":985},{"type":22,"tag":296,"props":3656,"children":3657},{"style":852},[3658],{"type":27,"value":3659}," CircuitBreakerRegistry.",{"type":22,"tag":296,"props":3661,"children":3662},{"style":762},[3663],{"type":27,"value":3664},"ofDefaults",{"type":22,"tag":296,"props":3666,"children":3667},{"style":852},[3668],{"type":27,"value":2328},{"type":22,"tag":296,"props":3670,"children":3671},{"class":298,"line":308},[3672,3677,3682],{"type":22,"tag":296,"props":3673,"children":3674},{"style":852},[3675],{"type":27,"value":3676},"registry.",{"type":22,"tag":296,"props":3678,"children":3679},{"style":762},[3680],{"type":27,"value":3681},"getEventPublisher",{"type":22,"tag":296,"props":3683,"children":3684},{"style":852},[3685],{"type":27,"value":3276},{"type":22,"tag":296,"props":3687,"children":3688},{"class":298,"line":317},[3689,3693,3698,3703,3707,3711,3715,3720,3725],{"type":22,"tag":296,"props":3690,"children":3691},{"style":852},[3692],{"type":27,"value":3284},{"type":22,"tag":296,"props":3694,"children":3695},{"style":762},[3696],{"type":27,"value":3697},"onStateTransition",{"type":22,"tag":296,"props":3699,"children":3700},{"style":852},[3701],{"type":27,"value":3702},"(event ",{"type":22,"tag":296,"props":3704,"children":3705},{"style":846},[3706],{"type":27,"value":3505},{"type":22,"tag":296,"props":3708,"children":3709},{"style":852},[3710],{"type":27,"value":3600},{"type":22,"tag":296,"props":3712,"children":3713},{"style":762},[3714],{"type":27,"value":3605},{"type":22,"tag":296,"props":3716,"children":3717},{"style":852},[3718],{"type":27,"value":3719},"(event.",{"type":22,"tag":296,"props":3721,"children":3722},{"style":762},[3723],{"type":27,"value":3724},"getStateTransition",{"type":22,"tag":296,"props":3726,"children":3727},{"style":852},[3728],{"type":27,"value":3729},"()));\n",{"type":22,"tag":23,"props":3731,"children":3732},{},[3733],{"type":27,"value":3734},"Integrate with Prometheus, Grafana, or other observability tools for comprehensive monitoring.",{"type":22,"tag":30,"props":3736,"children":3738},{"id":3737},"best-practices-for-circuit-breaking",[3739],{"type":27,"value":3740},"Best Practices for Circuit Breaking",{"type":22,"tag":207,"props":3742,"children":3743},{},[3744,3749,3754,3759],{"type":22,"tag":66,"props":3745,"children":3746},{},[3747],{"type":27,"value":3748},"Configure sensible thresholds to avoid premature circuit opening.",{"type":22,"tag":66,"props":3750,"children":3751},{},[3752],{"type":27,"value":3753},"Always define fallback mechanisms.",{"type":22,"tag":66,"props":3755,"children":3756},{},[3757],{"type":27,"value":3758},"Regularly monitor circuit breaker states and metrics.",{"type":22,"tag":66,"props":3760,"children":3761},{},[3762],{"type":27,"value":3763},"Test thoroughly to ensure reliability under failure conditions.",{"type":22,"tag":30,"props":3765,"children":3766},{"id":2946},[3767],{"type":27,"value":2949},{"type":22,"tag":23,"props":3769,"children":3770},{},[3771],{"type":27,"value":3772},"Implementing circuit breakers using Resilience4j significantly enhances the resilience of your Java-based distributed systems. This proactive approach ensures your systems gracefully handle failures, maintaining service availability and user satisfaction.",{"type":22,"tag":2048,"props":3774,"children":3775},{"id":618},[3776],{"type":27,"value":621},{"type":22,"tag":207,"props":3778,"children":3779},{},[3780,3790,3800],{"type":22,"tag":66,"props":3781,"children":3782},{},[3783],{"type":22,"tag":113,"props":3784,"children":3787},{"href":3785,"rel":3786},"https://resilience4j.readme.io/docs",[640],[3788],{"type":27,"value":3789},"Resilience4j Official Documentation",{"type":22,"tag":66,"props":3791,"children":3792},{},[3793],{"type":22,"tag":113,"props":3794,"children":3797},{"href":3795,"rel":3796},"https://martinfowler.com/bliki/CircuitBreaker.html",[640],[3798],{"type":27,"value":3799},"Circuit Breaker Pattern by Martin Fowler",{"type":22,"tag":66,"props":3801,"children":3802},{},[3803],{"type":22,"tag":113,"props":3804,"children":3807},{"href":3805,"rel":3806},"https://microservices.io/patterns/reliability/circuit-breaker.html",[640],[3808],{"type":27,"value":3809},"Microservices Patterns by Chris Richardson",{"type":22,"tag":667,"props":3811,"children":3812},{},[3813],{"type":27,"value":671},{"title":7,"searchDepth":308,"depth":308,"links":3815},[3816,3817,3818,3823,3824,3825],{"id":3034,"depth":308,"text":3037},{"id":3083,"depth":308,"text":3086},{"id":3112,"depth":308,"text":3115,"children":3819},[3820,3821,3822],{"id":3118,"depth":317,"text":3121},{"id":3239,"depth":317,"text":3242},{"id":3449,"depth":317,"text":3452},{"id":3627,"depth":308,"text":3630},{"id":3737,"depth":308,"text":3740},{"id":2946,"depth":308,"text":2949},"content:posts:circuit-breaking-resilience.md","posts/circuit-breaking-resilience.md","posts/circuit-breaking-resilience",[3830,3831,3832,3833,3837,3841,3845,3849,3853,3857,3861,3865,3866,3870,3874,3878,3882,3886,3889,3893,3897],{"_path":690,"title":691,"date":693},{"_path":2106,"title":2107,"date":2109},{"_path":3012,"title":3013,"date":3015},{"_path":3834,"title":3835,"date":3836},"/posts/maven-and-github-actions","Automating Java Builds with Maven and GitHub Actions CI/CD","2024-06-15T11:00:00.000Z",{"_path":3838,"title":3839,"date":3840},"/posts/pattern-matching-sealed-classes-java21","A Guide to Pattern Matching and Sealed Classes in Java 21","2024-05-15T11:00:00.000Z",{"_path":3842,"title":3843,"date":3844},"/posts/async-java-completable-vs-reactive","Asynchronous Programming in Java: CompletableFuture vs Reactive Streams","2024-04-15T11:00:00.000Z",{"_path":3846,"title":3847,"date":3848},"/posts/mastering-concurrency","Mastering Concurrency in Java: Threads, Executors, and Virtual Threads","2024-03-15T11:00:00.000Z",{"_path":3850,"title":3851,"date":3852},"/posts/microservices-mistakes","Common Mistakes When Developing Microservices","2024-02-15T11:00:00.000Z",{"_path":3854,"title":3855,"date":3856},"/posts/tdd-testing","Test-Driven Development (TDD) in Java with JUnit and Mockito","2024-01-15T11:00:00.000Z",{"_path":3858,"title":3859,"date":3860},"/posts/single-table-design","Single Table Design","2023-12-27T11:00:00.000Z",{"_path":3862,"title":3863,"date":3864},"/posts/java-17","Exploring Java 17's New Features","2023-10-08T11:00:00.000Z",{"_path":4,"title":8,"date":9},{"_path":3867,"title":3868,"date":3869},"/posts/terraform","Unleashing the Power of Infrastructure as Code (IaC)","2023-09-24 18:00:00",{"_path":3871,"title":3872,"date":3873},"/posts/python-virtual-environments","Python Virtual Environments (venv)","2023-09-17 22:00:00",{"_path":3875,"title":3876,"date":3877},"/posts/api-first-principles","API First principles","2023-09-01 22:15:18",{"_path":3879,"title":3880,"date":3881},"/posts/how-to-configure-ssh-key-based-authentication","How To Configure SSH Key-Based Authentication","2021-02-21 03:46:12",{"_path":3883,"title":3884,"date":3885},"/posts/algorithms-binary-search-tree","Algorithms - Binary Search Tree in kotlin","2020-12-06T11:00:00.000Z",{"_path":3887,"title":3888,"date":3885},"/posts/how-to-create-a-twitter-bot","How to create a Twitter bot",{"_path":3890,"title":3891,"date":3892},"/posts/manage-aws-infrastructure-with-terraform","Bootstrap complete Java application infrastructure in AWS with Terraform","2020-12-02T11:00:00.000Z",{"_path":3894,"title":3895,"date":3896},"/posts/algorithms-working-with-trees","Algorithms - Binary tree traversals in kotlin","2020-11-24T11:00:00.000Z",{"_path":3898,"title":3899,"date":3900},"/posts/playing-with-ocr-libraries","Playing with OCR libraries","2020-11-22T11:00:00.000Z",1790510065859]