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