[{"data":1,"prerenderedAt":12719},["ShallowReactive",2],{"cat-code":3},[4,1461,2371,3191,4201,5052,6836,8084,8264,9283,9673,10066,10698,11282,11569,12258],{"_path":5,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":9,"description":10,"date":11,"layout":12,"subtitle":13,"image":14,"optimized_image":14,"category":15,"tags":16,"author":22,"paginate":7,"body":23,"_type":1455,"_id":1456,"_source":1457,"_file":1458,"_stem":1459,"_extension":1460},"/posts/gpt-sql-integration","posts",false,"","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","post","Transforma preguntas naturales en consultas SQL automatizadas","/assets/img/uploads/gpt-sql-integration.png","code",[15,17,18,19,20,21],"gpt","openai","sql","ai","nlp","jaimedearcos",{"type":24,"children":25,"toc":1444},"root",[26,38,45,65,71,76,124,137,153,159,164,390,396,401,737,743,748,1099,1105,1110,1169,1175,1180,1361,1367,1385,1391,1396,1403,1438],{"type":27,"tag":28,"props":29,"children":30},"element","blockquote",{},[31],{"type":27,"tag":32,"props":33,"children":34},"p",{},[35],{"type":36,"value":37},"text","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":27,"tag":39,"props":40,"children":42},"h2",{"id":41},"requisitos-previos",[43],{"type":36,"value":44},"Requisitos Previos",{"type":27,"tag":46,"props":47,"children":48},"ul",{},[49,55,60],{"type":27,"tag":50,"props":51,"children":52},"li",{},[53],{"type":36,"value":54},"Cuenta y clave API de OpenAI",{"type":27,"tag":50,"props":56,"children":57},{},[58],{"type":36,"value":59},"Python instalado en tu entorno",{"type":27,"tag":50,"props":61,"children":62},{},[63],{"type":36,"value":64},"Base de datos SQL (ej.: PostgreSQL, MySQL)",{"type":27,"tag":39,"props":66,"children":68},{"id":67},"paso-1-configuración-del-entorno",[69],{"type":36,"value":70},"Paso 1: Configuración del entorno",{"type":27,"tag":32,"props":72,"children":73},{},[74],{"type":36,"value":75},"Primero, instala las dependencias necesarias:",{"type":27,"tag":77,"props":78,"children":82},"pre",{"className":79,"code":80,"language":81,"meta":8,"style":8},"language-bash shiki shiki-themes github-dark github-light","pip install openai python-dotenv sqlalchemy psycopg2-binary\n","bash",[83],{"type":27,"tag":15,"props":84,"children":85},{"__ignoreMap":8},[86],{"type":27,"tag":87,"props":88,"children":91},"span",{"class":89,"line":90},"line",1,[92,98,104,109,114,119],{"type":27,"tag":87,"props":93,"children":95},{"style":94},"--shiki-default:#B392F0;--shiki-light:#6F42C1",[96],{"type":36,"value":97},"pip",{"type":27,"tag":87,"props":99,"children":101},{"style":100},"--shiki-default:#9ECBFF;--shiki-light:#032F62",[102],{"type":36,"value":103}," install",{"type":27,"tag":87,"props":105,"children":106},{"style":100},[107],{"type":36,"value":108}," openai",{"type":27,"tag":87,"props":110,"children":111},{"style":100},[112],{"type":36,"value":113}," python-dotenv",{"type":27,"tag":87,"props":115,"children":116},{"style":100},[117],{"type":36,"value":118}," sqlalchemy",{"type":27,"tag":87,"props":120,"children":121},{"style":100},[122],{"type":36,"value":123}," psycopg2-binary\n",{"type":27,"tag":32,"props":125,"children":126},{},[127,129,135],{"type":36,"value":128},"Guarda tu clave API en un archivo ",{"type":27,"tag":15,"props":130,"children":132},{"className":131},[],[133],{"type":36,"value":134},".env",{"type":36,"value":136},":",{"type":27,"tag":77,"props":138,"children":142},{"className":139,"code":140,"language":141,"meta":8,"style":8},"language-env shiki shiki-themes github-dark github-light","OPENAI_API_KEY='tu-api-key'\n","env",[143],{"type":27,"tag":15,"props":144,"children":145},{"__ignoreMap":8},[146],{"type":27,"tag":87,"props":147,"children":148},{"class":89,"line":90},[149],{"type":27,"tag":87,"props":150,"children":151},{},[152],{"type":36,"value":140},{"type":27,"tag":39,"props":154,"children":156},{"id":155},"paso-2-conexión-a-la-base-de-datos",[157],{"type":36,"value":158},"Paso 2: Conexión a la base de datos",{"type":27,"tag":32,"props":160,"children":161},{},[162],{"type":36,"value":163},"Utiliza SQLAlchemy para conectarte a tu base de datos:",{"type":27,"tag":77,"props":165,"children":169},{"className":166,"code":167,"language":168,"meta":8,"style":8},"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",[170],{"type":27,"tag":15,"props":171,"children":172},{"__ignoreMap":8},[173,198,220,233,255,265,274,282,312,339,372],{"type":27,"tag":87,"props":174,"children":175},{"class":89,"line":90},[176,182,188,193],{"type":27,"tag":87,"props":177,"children":179},{"style":178},"--shiki-default:#F97583;--shiki-light:#D73A49",[180],{"type":36,"value":181},"from",{"type":27,"tag":87,"props":183,"children":185},{"style":184},"--shiki-default:#E1E4E8;--shiki-light:#24292E",[186],{"type":36,"value":187}," sqlalchemy ",{"type":27,"tag":87,"props":189,"children":190},{"style":178},[191],{"type":36,"value":192},"import",{"type":27,"tag":87,"props":194,"children":195},{"style":184},[196],{"type":36,"value":197}," create_engine\n",{"type":27,"tag":87,"props":199,"children":201},{"class":89,"line":200},2,[202,206,211,215],{"type":27,"tag":87,"props":203,"children":204},{"style":178},[205],{"type":36,"value":181},{"type":27,"tag":87,"props":207,"children":208},{"style":184},[209],{"type":36,"value":210}," sqlalchemy.orm ",{"type":27,"tag":87,"props":212,"children":213},{"style":178},[214],{"type":36,"value":192},{"type":27,"tag":87,"props":216,"children":217},{"style":184},[218],{"type":36,"value":219}," sessionmaker\n",{"type":27,"tag":87,"props":221,"children":223},{"class":89,"line":222},3,[224,228],{"type":27,"tag":87,"props":225,"children":226},{"style":178},[227],{"type":36,"value":192},{"type":27,"tag":87,"props":229,"children":230},{"style":184},[231],{"type":36,"value":232}," os\n",{"type":27,"tag":87,"props":234,"children":236},{"class":89,"line":235},4,[237,241,246,250],{"type":27,"tag":87,"props":238,"children":239},{"style":178},[240],{"type":36,"value":181},{"type":27,"tag":87,"props":242,"children":243},{"style":184},[244],{"type":36,"value":245}," dotenv ",{"type":27,"tag":87,"props":247,"children":248},{"style":178},[249],{"type":36,"value":192},{"type":27,"tag":87,"props":251,"children":252},{"style":184},[253],{"type":36,"value":254}," load_dotenv\n",{"type":27,"tag":87,"props":256,"children":258},{"class":89,"line":257},5,[259],{"type":27,"tag":87,"props":260,"children":262},{"emptyLinePlaceholder":261},true,[263],{"type":36,"value":264},"\n",{"type":27,"tag":87,"props":266,"children":268},{"class":89,"line":267},6,[269],{"type":27,"tag":87,"props":270,"children":271},{"style":184},[272],{"type":36,"value":273},"load_dotenv()\n",{"type":27,"tag":87,"props":275,"children":277},{"class":89,"line":276},7,[278],{"type":27,"tag":87,"props":279,"children":280},{"emptyLinePlaceholder":261},[281],{"type":36,"value":264},{"type":27,"tag":87,"props":283,"children":285},{"class":89,"line":284},8,[286,292,297,302,307],{"type":27,"tag":87,"props":287,"children":289},{"style":288},"--shiki-default:#79B8FF;--shiki-light:#005CC5",[290],{"type":36,"value":291},"DATABASE_URL",{"type":27,"tag":87,"props":293,"children":294},{"style":178},[295],{"type":36,"value":296}," =",{"type":27,"tag":87,"props":298,"children":299},{"style":184},[300],{"type":36,"value":301}," os.getenv(",{"type":27,"tag":87,"props":303,"children":304},{"style":100},[305],{"type":36,"value":306},"\"DATABASE_URL\"",{"type":27,"tag":87,"props":308,"children":309},{"style":184},[310],{"type":36,"value":311},")\n",{"type":27,"tag":87,"props":313,"children":315},{"class":89,"line":314},9,[316,321,326,331,335],{"type":27,"tag":87,"props":317,"children":318},{"style":184},[319],{"type":36,"value":320},"engine ",{"type":27,"tag":87,"props":322,"children":323},{"style":178},[324],{"type":36,"value":325},"=",{"type":27,"tag":87,"props":327,"children":328},{"style":184},[329],{"type":36,"value":330}," create_engine(",{"type":27,"tag":87,"props":332,"children":333},{"style":288},[334],{"type":36,"value":291},{"type":27,"tag":87,"props":336,"children":337},{"style":184},[338],{"type":36,"value":311},{"type":27,"tag":87,"props":340,"children":342},{"class":89,"line":341},10,[343,348,352,357,363,367],{"type":27,"tag":87,"props":344,"children":345},{"style":184},[346],{"type":36,"value":347},"Session ",{"type":27,"tag":87,"props":349,"children":350},{"style":178},[351],{"type":36,"value":325},{"type":27,"tag":87,"props":353,"children":354},{"style":184},[355],{"type":36,"value":356}," sessionmaker(",{"type":27,"tag":87,"props":358,"children":360},{"style":359},"--shiki-default:#FFAB70;--shiki-light:#E36209",[361],{"type":36,"value":362},"bind",{"type":27,"tag":87,"props":364,"children":365},{"style":178},[366],{"type":36,"value":325},{"type":27,"tag":87,"props":368,"children":369},{"style":184},[370],{"type":36,"value":371},"engine)\n",{"type":27,"tag":87,"props":373,"children":375},{"class":89,"line":374},11,[376,381,385],{"type":27,"tag":87,"props":377,"children":378},{"style":184},[379],{"type":36,"value":380},"session ",{"type":27,"tag":87,"props":382,"children":383},{"style":178},[384],{"type":36,"value":325},{"type":27,"tag":87,"props":386,"children":387},{"style":184},[388],{"type":36,"value":389}," Session()\n",{"type":27,"tag":39,"props":391,"children":393},{"id":392},"paso-3-obtener-esquema-de-la-base-de-datos",[394],{"type":36,"value":395},"Paso 3: Obtener esquema de la base de datos",{"type":27,"tag":32,"props":397,"children":398},{},[399],{"type":36,"value":400},"Genera una descripción del esquema que será utilizada por GPT:",{"type":27,"tag":77,"props":402,"children":404},{"className":166,"code":403,"language":168,"meta":8,"style":8},"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",[405],{"type":27,"tag":15,"props":406,"children":407},{"__ignoreMap":8},[408,428,435,453,470,487,510,553,575,660,684,697,705,723],{"type":27,"tag":87,"props":409,"children":410},{"class":89,"line":90},[411,415,419,423],{"type":27,"tag":87,"props":412,"children":413},{"style":178},[414],{"type":36,"value":181},{"type":27,"tag":87,"props":416,"children":417},{"style":184},[418],{"type":36,"value":187},{"type":27,"tag":87,"props":420,"children":421},{"style":178},[422],{"type":36,"value":192},{"type":27,"tag":87,"props":424,"children":425},{"style":184},[426],{"type":36,"value":427}," inspect\n",{"type":27,"tag":87,"props":429,"children":430},{"class":89,"line":200},[431],{"type":27,"tag":87,"props":432,"children":433},{"emptyLinePlaceholder":261},[434],{"type":36,"value":264},{"type":27,"tag":87,"props":436,"children":437},{"class":89,"line":222},[438,443,448],{"type":27,"tag":87,"props":439,"children":440},{"style":178},[441],{"type":36,"value":442},"def",{"type":27,"tag":87,"props":444,"children":445},{"style":94},[446],{"type":36,"value":447}," get_database_schema",{"type":27,"tag":87,"props":449,"children":450},{"style":184},[451],{"type":36,"value":452},"(engine):\n",{"type":27,"tag":87,"props":454,"children":455},{"class":89,"line":235},[456,461,465],{"type":27,"tag":87,"props":457,"children":458},{"style":184},[459],{"type":36,"value":460},"    inspector ",{"type":27,"tag":87,"props":462,"children":463},{"style":178},[464],{"type":36,"value":325},{"type":27,"tag":87,"props":466,"children":467},{"style":184},[468],{"type":36,"value":469}," inspect(engine)\n",{"type":27,"tag":87,"props":471,"children":472},{"class":89,"line":257},[473,478,482],{"type":27,"tag":87,"props":474,"children":475},{"style":184},[476],{"type":36,"value":477},"    schema_description ",{"type":27,"tag":87,"props":479,"children":480},{"style":178},[481],{"type":36,"value":325},{"type":27,"tag":87,"props":483,"children":484},{"style":100},[485],{"type":36,"value":486}," \"\"\n",{"type":27,"tag":87,"props":488,"children":489},{"class":89,"line":267},[490,495,500,505],{"type":27,"tag":87,"props":491,"children":492},{"style":178},[493],{"type":36,"value":494},"    for",{"type":27,"tag":87,"props":496,"children":497},{"style":184},[498],{"type":36,"value":499}," table_name ",{"type":27,"tag":87,"props":501,"children":502},{"style":178},[503],{"type":36,"value":504},"in",{"type":27,"tag":87,"props":506,"children":507},{"style":184},[508],{"type":36,"value":509}," inspector.get_table_names():\n",{"type":27,"tag":87,"props":511,"children":512},{"class":89,"line":276},[513,518,523,528,533,538,543,548],{"type":27,"tag":87,"props":514,"children":515},{"style":184},[516],{"type":36,"value":517},"        schema_description ",{"type":27,"tag":87,"props":519,"children":520},{"style":178},[521],{"type":36,"value":522},"+=",{"type":27,"tag":87,"props":524,"children":525},{"style":178},[526],{"type":36,"value":527}," f",{"type":27,"tag":87,"props":529,"children":530},{"style":100},[531],{"type":36,"value":532},"\"Table: ",{"type":27,"tag":87,"props":534,"children":535},{"style":288},[536],{"type":36,"value":537},"{",{"type":27,"tag":87,"props":539,"children":540},{"style":184},[541],{"type":36,"value":542},"table_name",{"type":27,"tag":87,"props":544,"children":545},{"style":288},[546],{"type":36,"value":547},"}\\n",{"type":27,"tag":87,"props":549,"children":550},{"style":100},[551],{"type":36,"value":552},"\"\n",{"type":27,"tag":87,"props":554,"children":555},{"class":89,"line":284},[556,561,566,570],{"type":27,"tag":87,"props":557,"children":558},{"style":178},[559],{"type":36,"value":560},"        for",{"type":27,"tag":87,"props":562,"children":563},{"style":184},[564],{"type":36,"value":565}," column ",{"type":27,"tag":87,"props":567,"children":568},{"style":178},[569],{"type":36,"value":504},{"type":27,"tag":87,"props":571,"children":572},{"style":184},[573],{"type":36,"value":574}," inspector.get_columns(table_name):\n",{"type":27,"tag":87,"props":576,"children":577},{"class":89,"line":314},[578,583,587,591,596,600,605,610,615,620,625,629,633,638,642,646,651,656],{"type":27,"tag":87,"props":579,"children":580},{"style":184},[581],{"type":36,"value":582},"            schema_description ",{"type":27,"tag":87,"props":584,"children":585},{"style":178},[586],{"type":36,"value":522},{"type":27,"tag":87,"props":588,"children":589},{"style":178},[590],{"type":36,"value":527},{"type":27,"tag":87,"props":592,"children":593},{"style":100},[594],{"type":36,"value":595},"\"- ",{"type":27,"tag":87,"props":597,"children":598},{"style":288},[599],{"type":36,"value":537},{"type":27,"tag":87,"props":601,"children":602},{"style":184},[603],{"type":36,"value":604},"column[",{"type":27,"tag":87,"props":606,"children":607},{"style":100},[608],{"type":36,"value":609},"'name'",{"type":27,"tag":87,"props":611,"children":612},{"style":184},[613],{"type":36,"value":614},"]",{"type":27,"tag":87,"props":616,"children":617},{"style":288},[618],{"type":36,"value":619},"}",{"type":27,"tag":87,"props":621,"children":622},{"style":100},[623],{"type":36,"value":624}," (",{"type":27,"tag":87,"props":626,"children":627},{"style":288},[628],{"type":36,"value":537},{"type":27,"tag":87,"props":630,"children":631},{"style":184},[632],{"type":36,"value":604},{"type":27,"tag":87,"props":634,"children":635},{"style":100},[636],{"type":36,"value":637},"'type'",{"type":27,"tag":87,"props":639,"children":640},{"style":184},[641],{"type":36,"value":614},{"type":27,"tag":87,"props":643,"children":644},{"style":288},[645],{"type":36,"value":619},{"type":27,"tag":87,"props":647,"children":648},{"style":100},[649],{"type":36,"value":650},")",{"type":27,"tag":87,"props":652,"children":653},{"style":288},[654],{"type":36,"value":655},"\\n",{"type":27,"tag":87,"props":657,"children":658},{"style":100},[659],{"type":36,"value":552},{"type":27,"tag":87,"props":661,"children":662},{"class":89,"line":341},[663,667,671,676,680],{"type":27,"tag":87,"props":664,"children":665},{"style":184},[666],{"type":36,"value":517},{"type":27,"tag":87,"props":668,"children":669},{"style":178},[670],{"type":36,"value":522},{"type":27,"tag":87,"props":672,"children":673},{"style":100},[674],{"type":36,"value":675}," \"",{"type":27,"tag":87,"props":677,"children":678},{"style":288},[679],{"type":36,"value":655},{"type":27,"tag":87,"props":681,"children":682},{"style":100},[683],{"type":36,"value":552},{"type":27,"tag":87,"props":685,"children":686},{"class":89,"line":374},[687,692],{"type":27,"tag":87,"props":688,"children":689},{"style":178},[690],{"type":36,"value":691},"    return",{"type":27,"tag":87,"props":693,"children":694},{"style":184},[695],{"type":36,"value":696}," schema_description\n",{"type":27,"tag":87,"props":698,"children":700},{"class":89,"line":699},12,[701],{"type":27,"tag":87,"props":702,"children":703},{"emptyLinePlaceholder":261},[704],{"type":36,"value":264},{"type":27,"tag":87,"props":706,"children":708},{"class":89,"line":707},13,[709,714,718],{"type":27,"tag":87,"props":710,"children":711},{"style":184},[712],{"type":36,"value":713},"schema_description ",{"type":27,"tag":87,"props":715,"children":716},{"style":178},[717],{"type":36,"value":325},{"type":27,"tag":87,"props":719,"children":720},{"style":184},[721],{"type":36,"value":722}," get_database_schema(engine)\n",{"type":27,"tag":87,"props":724,"children":726},{"class":89,"line":725},14,[727,732],{"type":27,"tag":87,"props":728,"children":729},{"style":288},[730],{"type":36,"value":731},"print",{"type":27,"tag":87,"props":733,"children":734},{"style":184},[735],{"type":36,"value":736},"(schema_description)\n",{"type":27,"tag":39,"props":738,"children":740},{"id":739},"paso-4-preparar-la-consulta-con-gpt",[741],{"type":36,"value":742},"Paso 4: Preparar la consulta con GPT",{"type":27,"tag":32,"props":744,"children":745},{},[746],{"type":36,"value":747},"Utiliza la API de OpenAI para transformar preguntas en consultas SQL, incluyendo el esquema de la base de datos:",{"type":27,"tag":77,"props":749,"children":751},{"className":166,"code":750,"language":168,"meta":8,"style":8},"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",[752],{"type":27,"tag":15,"props":753,"children":754},{"__ignoreMap":8},[755,767,778,785,810,817,834,851,873,890,961,994,1002,1010,1037,1050,1058,1086],{"type":27,"tag":87,"props":756,"children":757},{"class":89,"line":90},[758,762],{"type":27,"tag":87,"props":759,"children":760},{"style":178},[761],{"type":36,"value":192},{"type":27,"tag":87,"props":763,"children":764},{"style":184},[765],{"type":36,"value":766}," openai\n",{"type":27,"tag":87,"props":768,"children":769},{"class":89,"line":200},[770,774],{"type":27,"tag":87,"props":771,"children":772},{"style":178},[773],{"type":36,"value":192},{"type":27,"tag":87,"props":775,"children":776},{"style":184},[777],{"type":36,"value":232},{"type":27,"tag":87,"props":779,"children":780},{"class":89,"line":222},[781],{"type":27,"tag":87,"props":782,"children":783},{"emptyLinePlaceholder":261},[784],{"type":36,"value":264},{"type":27,"tag":87,"props":786,"children":787},{"class":89,"line":235},[788,793,797,801,806],{"type":27,"tag":87,"props":789,"children":790},{"style":184},[791],{"type":36,"value":792},"openai.api_key ",{"type":27,"tag":87,"props":794,"children":795},{"style":178},[796],{"type":36,"value":325},{"type":27,"tag":87,"props":798,"children":799},{"style":184},[800],{"type":36,"value":301},{"type":27,"tag":87,"props":802,"children":803},{"style":100},[804],{"type":36,"value":805},"\"OPENAI_API_KEY\"",{"type":27,"tag":87,"props":807,"children":808},{"style":184},[809],{"type":36,"value":311},{"type":27,"tag":87,"props":811,"children":812},{"class":89,"line":257},[813],{"type":27,"tag":87,"props":814,"children":815},{"emptyLinePlaceholder":261},[816],{"type":36,"value":264},{"type":27,"tag":87,"props":818,"children":819},{"class":89,"line":267},[820,824,829],{"type":27,"tag":87,"props":821,"children":822},{"style":178},[823],{"type":36,"value":442},{"type":27,"tag":87,"props":825,"children":826},{"style":94},[827],{"type":36,"value":828}," generate_sql",{"type":27,"tag":87,"props":830,"children":831},{"style":184},[832],{"type":36,"value":833},"(question, schema):\n",{"type":27,"tag":87,"props":835,"children":836},{"class":89,"line":276},[837,842,846],{"type":27,"tag":87,"props":838,"children":839},{"style":184},[840],{"type":36,"value":841},"    response ",{"type":27,"tag":87,"props":843,"children":844},{"style":178},[845],{"type":36,"value":325},{"type":27,"tag":87,"props":847,"children":848},{"style":184},[849],{"type":36,"value":850}," openai.ChatCompletion.create(\n",{"type":27,"tag":87,"props":852,"children":853},{"class":89,"line":284},[854,859,863,868],{"type":27,"tag":87,"props":855,"children":856},{"style":359},[857],{"type":36,"value":858},"        model",{"type":27,"tag":87,"props":860,"children":861},{"style":178},[862],{"type":36,"value":325},{"type":27,"tag":87,"props":864,"children":865},{"style":100},[866],{"type":36,"value":867},"\"gpt-4\"",{"type":27,"tag":87,"props":869,"children":870},{"style":184},[871],{"type":36,"value":872},",\n",{"type":27,"tag":87,"props":874,"children":875},{"class":89,"line":314},[876,881,885],{"type":27,"tag":87,"props":877,"children":878},{"style":359},[879],{"type":36,"value":880},"        messages",{"type":27,"tag":87,"props":882,"children":883},{"style":178},[884],{"type":36,"value":325},{"type":27,"tag":87,"props":886,"children":887},{"style":184},[888],{"type":36,"value":889},"[\n",{"type":27,"tag":87,"props":891,"children":892},{"class":89,"line":341},[893,898,903,908,913,918,923,927,932,937,942,947,951,956],{"type":27,"tag":87,"props":894,"children":895},{"style":184},[896],{"type":36,"value":897},"            {",{"type":27,"tag":87,"props":899,"children":900},{"style":100},[901],{"type":36,"value":902},"\"role\"",{"type":27,"tag":87,"props":904,"children":905},{"style":184},[906],{"type":36,"value":907},": ",{"type":27,"tag":87,"props":909,"children":910},{"style":100},[911],{"type":36,"value":912},"\"system\"",{"type":27,"tag":87,"props":914,"children":915},{"style":184},[916],{"type":36,"value":917},", ",{"type":27,"tag":87,"props":919,"children":920},{"style":100},[921],{"type":36,"value":922},"\"content\"",{"type":27,"tag":87,"props":924,"children":925},{"style":184},[926],{"type":36,"value":907},{"type":27,"tag":87,"props":928,"children":929},{"style":178},[930],{"type":36,"value":931},"f",{"type":27,"tag":87,"props":933,"children":934},{"style":100},[935],{"type":36,"value":936},"\"Convierte preguntas en lenguaje natural a consultas SQL. Esquema de la base de datos:",{"type":27,"tag":87,"props":938,"children":939},{"style":288},[940],{"type":36,"value":941},"\\n{",{"type":27,"tag":87,"props":943,"children":944},{"style":184},[945],{"type":36,"value":946},"schema",{"type":27,"tag":87,"props":948,"children":949},{"style":288},[950],{"type":36,"value":619},{"type":27,"tag":87,"props":952,"children":953},{"style":100},[954],{"type":36,"value":955},"\"",{"type":27,"tag":87,"props":957,"children":958},{"style":184},[959],{"type":36,"value":960},"},\n",{"type":27,"tag":87,"props":962,"children":963},{"class":89,"line":374},[964,968,972,976,981,985,989],{"type":27,"tag":87,"props":965,"children":966},{"style":184},[967],{"type":36,"value":897},{"type":27,"tag":87,"props":969,"children":970},{"style":100},[971],{"type":36,"value":902},{"type":27,"tag":87,"props":973,"children":974},{"style":184},[975],{"type":36,"value":907},{"type":27,"tag":87,"props":977,"children":978},{"style":100},[979],{"type":36,"value":980},"\"user\"",{"type":27,"tag":87,"props":982,"children":983},{"style":184},[984],{"type":36,"value":917},{"type":27,"tag":87,"props":986,"children":987},{"style":100},[988],{"type":36,"value":922},{"type":27,"tag":87,"props":990,"children":991},{"style":184},[992],{"type":36,"value":993},": question}\n",{"type":27,"tag":87,"props":995,"children":996},{"class":89,"line":699},[997],{"type":27,"tag":87,"props":998,"children":999},{"style":184},[1000],{"type":36,"value":1001},"        ]\n",{"type":27,"tag":87,"props":1003,"children":1004},{"class":89,"line":707},[1005],{"type":27,"tag":87,"props":1006,"children":1007},{"style":184},[1008],{"type":36,"value":1009},"    )\n",{"type":27,"tag":87,"props":1011,"children":1012},{"class":89,"line":725},[1013,1018,1022,1027,1032],{"type":27,"tag":87,"props":1014,"children":1015},{"style":184},[1016],{"type":36,"value":1017},"    sql_query ",{"type":27,"tag":87,"props":1019,"children":1020},{"style":178},[1021],{"type":36,"value":325},{"type":27,"tag":87,"props":1023,"children":1024},{"style":184},[1025],{"type":36,"value":1026}," response.choices[",{"type":27,"tag":87,"props":1028,"children":1029},{"style":288},[1030],{"type":36,"value":1031},"0",{"type":27,"tag":87,"props":1033,"children":1034},{"style":184},[1035],{"type":36,"value":1036},"].message.content.strip()\n",{"type":27,"tag":87,"props":1038,"children":1040},{"class":89,"line":1039},15,[1041,1045],{"type":27,"tag":87,"props":1042,"children":1043},{"style":178},[1044],{"type":36,"value":691},{"type":27,"tag":87,"props":1046,"children":1047},{"style":184},[1048],{"type":36,"value":1049}," sql_query\n",{"type":27,"tag":87,"props":1051,"children":1053},{"class":89,"line":1052},16,[1054],{"type":27,"tag":87,"props":1055,"children":1056},{"emptyLinePlaceholder":261},[1057],{"type":36,"value":264},{"type":27,"tag":87,"props":1059,"children":1061},{"class":89,"line":1060},17,[1062,1067,1071,1076,1081],{"type":27,"tag":87,"props":1063,"children":1064},{"style":184},[1065],{"type":36,"value":1066},"query ",{"type":27,"tag":87,"props":1068,"children":1069},{"style":178},[1070],{"type":36,"value":325},{"type":27,"tag":87,"props":1072,"children":1073},{"style":184},[1074],{"type":36,"value":1075}," generate_sql(",{"type":27,"tag":87,"props":1077,"children":1078},{"style":100},[1079],{"type":36,"value":1080},"\"¿Cuántos usuarios se registraron el último mes?\"",{"type":27,"tag":87,"props":1082,"children":1083},{"style":184},[1084],{"type":36,"value":1085},", schema_description)\n",{"type":27,"tag":87,"props":1087,"children":1089},{"class":89,"line":1088},18,[1090,1094],{"type":27,"tag":87,"props":1091,"children":1092},{"style":288},[1093],{"type":36,"value":731},{"type":27,"tag":87,"props":1095,"children":1096},{"style":184},[1097],{"type":36,"value":1098},"(query)\n",{"type":27,"tag":39,"props":1100,"children":1102},{"id":1101},"paso-5-ejecutar-consultas-generadas",[1103],{"type":36,"value":1104},"Paso 5: Ejecutar consultas generadas",{"type":27,"tag":32,"props":1106,"children":1107},{},[1108],{"type":36,"value":1109},"Ejecuta la consulta generada y obtiene resultados:",{"type":27,"tag":77,"props":1111,"children":1113},{"className":166,"code":1112,"language":168,"meta":8,"style":8},"result = session.execute(query)\nfor row in result:\n    print(row)\n",[1114],{"type":27,"tag":15,"props":1115,"children":1116},{"__ignoreMap":8},[1117,1134,1156],{"type":27,"tag":87,"props":1118,"children":1119},{"class":89,"line":90},[1120,1125,1129],{"type":27,"tag":87,"props":1121,"children":1122},{"style":184},[1123],{"type":36,"value":1124},"result ",{"type":27,"tag":87,"props":1126,"children":1127},{"style":178},[1128],{"type":36,"value":325},{"type":27,"tag":87,"props":1130,"children":1131},{"style":184},[1132],{"type":36,"value":1133}," session.execute(query)\n",{"type":27,"tag":87,"props":1135,"children":1136},{"class":89,"line":200},[1137,1142,1147,1151],{"type":27,"tag":87,"props":1138,"children":1139},{"style":178},[1140],{"type":36,"value":1141},"for",{"type":27,"tag":87,"props":1143,"children":1144},{"style":184},[1145],{"type":36,"value":1146}," row ",{"type":27,"tag":87,"props":1148,"children":1149},{"style":178},[1150],{"type":36,"value":504},{"type":27,"tag":87,"props":1152,"children":1153},{"style":184},[1154],{"type":36,"value":1155}," result:\n",{"type":27,"tag":87,"props":1157,"children":1158},{"class":89,"line":222},[1159,1164],{"type":27,"tag":87,"props":1160,"children":1161},{"style":288},[1162],{"type":36,"value":1163},"    print",{"type":27,"tag":87,"props":1165,"children":1166},{"style":184},[1167],{"type":36,"value":1168},"(row)\n",{"type":27,"tag":39,"props":1170,"children":1172},{"id":1171},"paso-6-manejo-de-errores-y-seguridad",[1173],{"type":36,"value":1174},"Paso 6: Manejo de errores y seguridad",{"type":27,"tag":32,"props":1176,"children":1177},{},[1178],{"type":36,"value":1179},"Para evitar problemas con consultas inseguras o errores, siempre valida las consultas generadas por GPT antes de ejecutarlas directamente:",{"type":27,"tag":77,"props":1181,"children":1183},{"className":166,"code":1182,"language":168,"meta":8,"style":8},"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",[1184],{"type":27,"tag":15,"props":1185,"children":1186},{"__ignoreMap":8},[1187,1204,1217,1234,1247,1270,1313,1325,1332,1349],{"type":27,"tag":87,"props":1188,"children":1189},{"class":89,"line":90},[1190,1194,1199],{"type":27,"tag":87,"props":1191,"children":1192},{"style":178},[1193],{"type":36,"value":442},{"type":27,"tag":87,"props":1195,"children":1196},{"style":94},[1197],{"type":36,"value":1198}," execute_safe_query",{"type":27,"tag":87,"props":1200,"children":1201},{"style":184},[1202],{"type":36,"value":1203},"(sql_query):\n",{"type":27,"tag":87,"props":1205,"children":1206},{"class":89,"line":200},[1207,1212],{"type":27,"tag":87,"props":1208,"children":1209},{"style":178},[1210],{"type":36,"value":1211},"    try",{"type":27,"tag":87,"props":1213,"children":1214},{"style":184},[1215],{"type":36,"value":1216},":\n",{"type":27,"tag":87,"props":1218,"children":1219},{"class":89,"line":222},[1220,1225,1229],{"type":27,"tag":87,"props":1221,"children":1222},{"style":184},[1223],{"type":36,"value":1224},"        result ",{"type":27,"tag":87,"props":1226,"children":1227},{"style":178},[1228],{"type":36,"value":325},{"type":27,"tag":87,"props":1230,"children":1231},{"style":184},[1232],{"type":36,"value":1233}," session.execute(sql_query)\n",{"type":27,"tag":87,"props":1235,"children":1236},{"class":89,"line":235},[1237,1242],{"type":27,"tag":87,"props":1238,"children":1239},{"style":178},[1240],{"type":36,"value":1241},"        return",{"type":27,"tag":87,"props":1243,"children":1244},{"style":184},[1245],{"type":36,"value":1246}," result.fetchall()\n",{"type":27,"tag":87,"props":1248,"children":1249},{"class":89,"line":257},[1250,1255,1260,1265],{"type":27,"tag":87,"props":1251,"children":1252},{"style":178},[1253],{"type":36,"value":1254},"    except",{"type":27,"tag":87,"props":1256,"children":1257},{"style":288},[1258],{"type":36,"value":1259}," Exception",{"type":27,"tag":87,"props":1261,"children":1262},{"style":178},[1263],{"type":36,"value":1264}," as",{"type":27,"tag":87,"props":1266,"children":1267},{"style":184},[1268],{"type":36,"value":1269}," e:\n",{"type":27,"tag":87,"props":1271,"children":1272},{"class":89,"line":267},[1273,1278,1283,1287,1292,1296,1301,1305,1309],{"type":27,"tag":87,"props":1274,"children":1275},{"style":288},[1276],{"type":36,"value":1277},"        print",{"type":27,"tag":87,"props":1279,"children":1280},{"style":184},[1281],{"type":36,"value":1282},"(",{"type":27,"tag":87,"props":1284,"children":1285},{"style":178},[1286],{"type":36,"value":931},{"type":27,"tag":87,"props":1288,"children":1289},{"style":100},[1290],{"type":36,"value":1291},"\"Error al ejecutar consulta: ",{"type":27,"tag":87,"props":1293,"children":1294},{"style":288},[1295],{"type":36,"value":537},{"type":27,"tag":87,"props":1297,"children":1298},{"style":184},[1299],{"type":36,"value":1300},"e",{"type":27,"tag":87,"props":1302,"children":1303},{"style":288},[1304],{"type":36,"value":619},{"type":27,"tag":87,"props":1306,"children":1307},{"style":100},[1308],{"type":36,"value":955},{"type":27,"tag":87,"props":1310,"children":1311},{"style":184},[1312],{"type":36,"value":311},{"type":27,"tag":87,"props":1314,"children":1315},{"class":89,"line":276},[1316,1320],{"type":27,"tag":87,"props":1317,"children":1318},{"style":178},[1319],{"type":36,"value":1241},{"type":27,"tag":87,"props":1321,"children":1322},{"style":288},[1323],{"type":36,"value":1324}," None\n",{"type":27,"tag":87,"props":1326,"children":1327},{"class":89,"line":284},[1328],{"type":27,"tag":87,"props":1329,"children":1330},{"emptyLinePlaceholder":261},[1331],{"type":36,"value":264},{"type":27,"tag":87,"props":1333,"children":1334},{"class":89,"line":314},[1335,1340,1344],{"type":27,"tag":87,"props":1336,"children":1337},{"style":184},[1338],{"type":36,"value":1339},"results ",{"type":27,"tag":87,"props":1341,"children":1342},{"style":178},[1343],{"type":36,"value":325},{"type":27,"tag":87,"props":1345,"children":1346},{"style":184},[1347],{"type":36,"value":1348}," execute_safe_query(query)\n",{"type":27,"tag":87,"props":1350,"children":1351},{"class":89,"line":341},[1352,1356],{"type":27,"tag":87,"props":1353,"children":1354},{"style":288},[1355],{"type":36,"value":731},{"type":27,"tag":87,"props":1357,"children":1358},{"style":184},[1359],{"type":36,"value":1360},"(results)\n",{"type":27,"tag":39,"props":1362,"children":1364},{"id":1363},"buenas-prácticas",[1365],{"type":36,"value":1366},"Buenas prácticas",{"type":27,"tag":46,"props":1368,"children":1369},{},[1370,1375,1380],{"type":27,"tag":50,"props":1371,"children":1372},{},[1373],{"type":36,"value":1374},"Siempre revisa o limita el acceso de los usuarios a consultas críticas o sensibles.",{"type":27,"tag":50,"props":1376,"children":1377},{},[1378],{"type":36,"value":1379},"Implementa validaciones adicionales para asegurar la integridad y seguridad de tu base de datos.",{"type":27,"tag":50,"props":1381,"children":1382},{},[1383],{"type":36,"value":1384},"Utiliza tokens y modelos específicos de OpenAI optimizados para tareas SQL.",{"type":27,"tag":39,"props":1386,"children":1388},{"id":1387},"conclusión",[1389],{"type":36,"value":1390},"Conclusión",{"type":27,"tag":32,"props":1392,"children":1393},{},[1394],{"type":36,"value":1395},"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":27,"tag":1397,"props":1398,"children":1400},"h1",{"id":1399},"recursos-adicionales",[1401],{"type":36,"value":1402},"Recursos adicionales",{"type":27,"tag":46,"props":1404,"children":1405},{},[1406,1418,1428],{"type":27,"tag":50,"props":1407,"children":1408},{},[1409],{"type":27,"tag":1410,"props":1411,"children":1415},"a",{"href":1412,"rel":1413},"https://platform.openai.com/docs/api-reference",[1414],"nofollow",[1416],{"type":36,"value":1417},"Documentación API OpenAI",{"type":27,"tag":50,"props":1419,"children":1420},{},[1421],{"type":27,"tag":1410,"props":1422,"children":1425},{"href":1423,"rel":1424},"https://docs.sqlalchemy.org/en/20/",[1414],[1426],{"type":36,"value":1427},"SQLAlchemy ORM Documentation",{"type":27,"tag":50,"props":1429,"children":1430},{},[1431],{"type":27,"tag":1410,"props":1432,"children":1435},{"href":1433,"rel":1434},"https://pypi.org/project/python-dotenv/",[1414],[1436],{"type":36,"value":1437},"Python Dotenv",{"type":27,"tag":1439,"props":1440,"children":1441},"style",{},[1442],{"type":36,"value":1443},"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":8,"searchDepth":200,"depth":200,"links":1445},[1446,1447,1448,1449,1450,1451,1452,1453,1454],{"id":41,"depth":200,"text":44},{"id":67,"depth":200,"text":70},{"id":155,"depth":200,"text":158},{"id":392,"depth":200,"text":395},{"id":739,"depth":200,"text":742},{"id":1101,"depth":200,"text":1104},{"id":1171,"depth":200,"text":1174},{"id":1363,"depth":200,"text":1366},{"id":1387,"depth":200,"text":1390},"markdown","content:posts:gpt-sql-integration.md","content","posts/gpt-sql-integration.md","posts/gpt-sql-integration","md",{"_path":1462,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":1463,"description":1464,"date":1465,"layout":12,"subtitle":1466,"image":1467,"optimized_image":1467,"category":15,"tags":1468,"author":22,"paginate":7,"body":1473,"_type":1455,"_id":2368,"_source":1457,"_file":2369,"_stem":2370,"_extension":1460},"/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",[15,1469,1470,1471,1472],"java","security","owasp","cybersecurity",{"type":24,"children":1474,"toc":2356},[1475,1483,1489,1494,1548,1553,1559,1564,1687,1692,1698,1703,1806,1812,1817,1940,1945,1951,1956,1981,1986,1992,1997,2013,2018,2024,2029,2112,2117,2123,2128,2248,2253,2259,2264,2297,2302,2308,2313,2319,2352],{"type":27,"tag":28,"props":1476,"children":1477},{},[1478],{"type":27,"tag":32,"props":1479,"children":1480},{},[1481],{"type":36,"value":1482},"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":27,"tag":39,"props":1484,"children":1486},{"id":1485},"understanding-owasp-top-10",[1487],{"type":36,"value":1488},"Understanding OWASP Top 10",{"type":27,"tag":32,"props":1490,"children":1491},{},[1492],{"type":36,"value":1493},"The OWASP Top 10 outlines the most critical web application security risks:",{"type":27,"tag":1495,"props":1496,"children":1497},"ol",{},[1498,1503,1508,1513,1518,1523,1528,1533,1538,1543],{"type":27,"tag":50,"props":1499,"children":1500},{},[1501],{"type":36,"value":1502},"Injection",{"type":27,"tag":50,"props":1504,"children":1505},{},[1506],{"type":36,"value":1507},"Broken Authentication",{"type":27,"tag":50,"props":1509,"children":1510},{},[1511],{"type":36,"value":1512},"Sensitive Data Exposure",{"type":27,"tag":50,"props":1514,"children":1515},{},[1516],{"type":36,"value":1517},"XML External Entities (XXE)",{"type":27,"tag":50,"props":1519,"children":1520},{},[1521],{"type":36,"value":1522},"Broken Access Control",{"type":27,"tag":50,"props":1524,"children":1525},{},[1526],{"type":36,"value":1527},"Security Misconfiguration",{"type":27,"tag":50,"props":1529,"children":1530},{},[1531],{"type":36,"value":1532},"Cross-Site Scripting (XSS)",{"type":27,"tag":50,"props":1534,"children":1535},{},[1536],{"type":36,"value":1537},"Insecure Deserialization",{"type":27,"tag":50,"props":1539,"children":1540},{},[1541],{"type":36,"value":1542},"Using Components with Known Vulnerabilities",{"type":27,"tag":50,"props":1544,"children":1545},{},[1546],{"type":36,"value":1547},"Insufficient Logging and Monitoring",{"type":27,"tag":32,"props":1549,"children":1550},{},[1551],{"type":36,"value":1552},"Let's delve into practical strategies and Java implementations for some of these threats.",{"type":27,"tag":39,"props":1554,"children":1556},{"id":1555},"_1-injection-prevention",[1557],{"type":36,"value":1558},"1. Injection Prevention",{"type":27,"tag":32,"props":1560,"children":1561},{},[1562],{"type":36,"value":1563},"Use Prepared Statements and parameterized queries:",{"type":27,"tag":77,"props":1565,"children":1568},{"className":1566,"code":1567,"language":1469,"meta":8,"style":8},"language-java shiki shiki-themes github-dark github-light","PreparedStatement stmt = connection.prepareStatement(\"SELECT * FROM users WHERE username=? AND password=?\");\nstmt.setString(1, username);\nstmt.setString(2, password);\nResultSet rs = stmt.executeQuery();\n",[1569],{"type":27,"tag":15,"props":1570,"children":1571},{"__ignoreMap":8},[1572,1608,1635,1660],{"type":27,"tag":87,"props":1573,"children":1574},{"class":89,"line":90},[1575,1580,1584,1589,1594,1598,1603],{"type":27,"tag":87,"props":1576,"children":1577},{"style":184},[1578],{"type":36,"value":1579},"PreparedStatement stmt ",{"type":27,"tag":87,"props":1581,"children":1582},{"style":178},[1583],{"type":36,"value":325},{"type":27,"tag":87,"props":1585,"children":1586},{"style":184},[1587],{"type":36,"value":1588}," connection.",{"type":27,"tag":87,"props":1590,"children":1591},{"style":94},[1592],{"type":36,"value":1593},"prepareStatement",{"type":27,"tag":87,"props":1595,"children":1596},{"style":184},[1597],{"type":36,"value":1282},{"type":27,"tag":87,"props":1599,"children":1600},{"style":100},[1601],{"type":36,"value":1602},"\"SELECT * FROM users WHERE username=? AND password=?\"",{"type":27,"tag":87,"props":1604,"children":1605},{"style":184},[1606],{"type":36,"value":1607},");\n",{"type":27,"tag":87,"props":1609,"children":1610},{"class":89,"line":200},[1611,1616,1621,1625,1630],{"type":27,"tag":87,"props":1612,"children":1613},{"style":184},[1614],{"type":36,"value":1615},"stmt.",{"type":27,"tag":87,"props":1617,"children":1618},{"style":94},[1619],{"type":36,"value":1620},"setString",{"type":27,"tag":87,"props":1622,"children":1623},{"style":184},[1624],{"type":36,"value":1282},{"type":27,"tag":87,"props":1626,"children":1627},{"style":288},[1628],{"type":36,"value":1629},"1",{"type":27,"tag":87,"props":1631,"children":1632},{"style":184},[1633],{"type":36,"value":1634},", username);\n",{"type":27,"tag":87,"props":1636,"children":1637},{"class":89,"line":222},[1638,1642,1646,1650,1655],{"type":27,"tag":87,"props":1639,"children":1640},{"style":184},[1641],{"type":36,"value":1615},{"type":27,"tag":87,"props":1643,"children":1644},{"style":94},[1645],{"type":36,"value":1620},{"type":27,"tag":87,"props":1647,"children":1648},{"style":184},[1649],{"type":36,"value":1282},{"type":27,"tag":87,"props":1651,"children":1652},{"style":288},[1653],{"type":36,"value":1654},"2",{"type":27,"tag":87,"props":1656,"children":1657},{"style":184},[1658],{"type":36,"value":1659},", password);\n",{"type":27,"tag":87,"props":1661,"children":1662},{"class":89,"line":235},[1663,1668,1672,1677,1682],{"type":27,"tag":87,"props":1664,"children":1665},{"style":184},[1666],{"type":36,"value":1667},"ResultSet rs ",{"type":27,"tag":87,"props":1669,"children":1670},{"style":178},[1671],{"type":36,"value":325},{"type":27,"tag":87,"props":1673,"children":1674},{"style":184},[1675],{"type":36,"value":1676}," stmt.",{"type":27,"tag":87,"props":1678,"children":1679},{"style":94},[1680],{"type":36,"value":1681},"executeQuery",{"type":27,"tag":87,"props":1683,"children":1684},{"style":184},[1685],{"type":36,"value":1686},"();\n",{"type":27,"tag":32,"props":1688,"children":1689},{},[1690],{"type":36,"value":1691},"This approach prevents SQL injection by ensuring that input data is treated as data, not executable code.",{"type":27,"tag":39,"props":1693,"children":1695},{"id":1694},"_2-secure-authentication",[1696],{"type":36,"value":1697},"2. Secure Authentication",{"type":27,"tag":32,"props":1699,"children":1700},{},[1701],{"type":36,"value":1702},"Implement robust authentication using secure password storage (bcrypt or Argon2):",{"type":27,"tag":77,"props":1704,"children":1706},{"className":1566,"code":1705,"language":1469,"meta":8,"style":8},"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",[1707],{"type":27,"tag":15,"props":1708,"children":1709},{"__ignoreMap":8},[1710,1722,1729,1766,1789,1798],{"type":27,"tag":87,"props":1711,"children":1712},{"class":89,"line":90},[1713,1717],{"type":27,"tag":87,"props":1714,"children":1715},{"style":178},[1716],{"type":36,"value":192},{"type":27,"tag":87,"props":1718,"children":1719},{"style":184},[1720],{"type":36,"value":1721}," org.springframework.security.crypto.bcrypt.BCrypt;\n",{"type":27,"tag":87,"props":1723,"children":1724},{"class":89,"line":200},[1725],{"type":27,"tag":87,"props":1726,"children":1727},{"emptyLinePlaceholder":261},[1728],{"type":36,"value":264},{"type":27,"tag":87,"props":1730,"children":1731},{"class":89,"line":222},[1732,1737,1741,1746,1751,1756,1761],{"type":27,"tag":87,"props":1733,"children":1734},{"style":184},[1735],{"type":36,"value":1736},"String hashedPassword ",{"type":27,"tag":87,"props":1738,"children":1739},{"style":178},[1740],{"type":36,"value":325},{"type":27,"tag":87,"props":1742,"children":1743},{"style":184},[1744],{"type":36,"value":1745}," BCrypt.",{"type":27,"tag":87,"props":1747,"children":1748},{"style":94},[1749],{"type":36,"value":1750},"hashpw",{"type":27,"tag":87,"props":1752,"children":1753},{"style":184},[1754],{"type":36,"value":1755},"(password, BCrypt.",{"type":27,"tag":87,"props":1757,"children":1758},{"style":94},[1759],{"type":36,"value":1760},"gensalt",{"type":27,"tag":87,"props":1762,"children":1763},{"style":184},[1764],{"type":36,"value":1765},"());\n",{"type":27,"tag":87,"props":1767,"children":1768},{"class":89,"line":235},[1769,1774,1779,1784],{"type":27,"tag":87,"props":1770,"children":1771},{"style":178},[1772],{"type":36,"value":1773},"if",{"type":27,"tag":87,"props":1775,"children":1776},{"style":184},[1777],{"type":36,"value":1778}," (BCrypt.",{"type":27,"tag":87,"props":1780,"children":1781},{"style":94},[1782],{"type":36,"value":1783},"checkpw",{"type":27,"tag":87,"props":1785,"children":1786},{"style":184},[1787],{"type":36,"value":1788},"(password, hashedPassword)) {\n",{"type":27,"tag":87,"props":1790,"children":1791},{"class":89,"line":257},[1792],{"type":27,"tag":87,"props":1793,"children":1795},{"style":1794},"--shiki-default:#6A737D;--shiki-light:#6A737D",[1796],{"type":36,"value":1797},"    // authentication successful\n",{"type":27,"tag":87,"props":1799,"children":1800},{"class":89,"line":267},[1801],{"type":27,"tag":87,"props":1802,"children":1803},{"style":184},[1804],{"type":36,"value":1805},"}\n",{"type":27,"tag":39,"props":1807,"children":1809},{"id":1808},"_3-sensitive-data-exposure",[1810],{"type":36,"value":1811},"3. Sensitive Data Exposure",{"type":27,"tag":32,"props":1813,"children":1814},{},[1815],{"type":36,"value":1816},"Use encryption for sensitive data storage:",{"type":27,"tag":77,"props":1818,"children":1820},{"className":1566,"code":1819,"language":1469,"meta":8,"style":8},"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",[1821],{"type":27,"tag":15,"props":1822,"children":1823},{"__ignoreMap":8},[1824,1859,1880,1898],{"type":27,"tag":87,"props":1825,"children":1826},{"class":89,"line":90},[1827,1832,1836,1841,1846,1850,1855],{"type":27,"tag":87,"props":1828,"children":1829},{"style":184},[1830],{"type":36,"value":1831},"Cipher cipher ",{"type":27,"tag":87,"props":1833,"children":1834},{"style":178},[1835],{"type":36,"value":325},{"type":27,"tag":87,"props":1837,"children":1838},{"style":184},[1839],{"type":36,"value":1840}," Cipher.",{"type":27,"tag":87,"props":1842,"children":1843},{"style":94},[1844],{"type":36,"value":1845},"getInstance",{"type":27,"tag":87,"props":1847,"children":1848},{"style":184},[1849],{"type":36,"value":1282},{"type":27,"tag":87,"props":1851,"children":1852},{"style":100},[1853],{"type":36,"value":1854},"\"AES/GCM/NoPadding\"",{"type":27,"tag":87,"props":1856,"children":1857},{"style":184},[1858],{"type":36,"value":1607},{"type":27,"tag":87,"props":1860,"children":1861},{"class":89,"line":200},[1862,1867,1871,1876],{"type":27,"tag":87,"props":1863,"children":1864},{"style":184},[1865],{"type":36,"value":1866},"SecretKey key ",{"type":27,"tag":87,"props":1868,"children":1869},{"style":178},[1870],{"type":36,"value":325},{"type":27,"tag":87,"props":1872,"children":1873},{"style":94},[1874],{"type":36,"value":1875}," generateSecretKey",{"type":27,"tag":87,"props":1877,"children":1878},{"style":184},[1879],{"type":36,"value":1686},{"type":27,"tag":87,"props":1881,"children":1882},{"class":89,"line":222},[1883,1888,1893],{"type":27,"tag":87,"props":1884,"children":1885},{"style":184},[1886],{"type":36,"value":1887},"cipher.",{"type":27,"tag":87,"props":1889,"children":1890},{"style":94},[1891],{"type":36,"value":1892},"init",{"type":27,"tag":87,"props":1894,"children":1895},{"style":184},[1896],{"type":36,"value":1897},"(Cipher.ENCRYPT_MODE, key);\n",{"type":27,"tag":87,"props":1899,"children":1900},{"class":89,"line":235},[1901,1906,1911,1915,1920,1925,1930,1935],{"type":27,"tag":87,"props":1902,"children":1903},{"style":178},[1904],{"type":36,"value":1905},"byte",{"type":27,"tag":87,"props":1907,"children":1908},{"style":184},[1909],{"type":36,"value":1910},"[] encryptedData ",{"type":27,"tag":87,"props":1912,"children":1913},{"style":178},[1914],{"type":36,"value":325},{"type":27,"tag":87,"props":1916,"children":1917},{"style":184},[1918],{"type":36,"value":1919}," cipher.",{"type":27,"tag":87,"props":1921,"children":1922},{"style":94},[1923],{"type":36,"value":1924},"doFinal",{"type":27,"tag":87,"props":1926,"children":1927},{"style":184},[1928],{"type":36,"value":1929},"(plainData.",{"type":27,"tag":87,"props":1931,"children":1932},{"style":94},[1933],{"type":36,"value":1934},"getBytes",{"type":27,"tag":87,"props":1936,"children":1937},{"style":184},[1938],{"type":36,"value":1939},"(StandardCharsets.UTF_8));\n",{"type":27,"tag":32,"props":1941,"children":1942},{},[1943],{"type":36,"value":1944},"Always encrypt data at rest and in transit (use HTTPS).",{"type":27,"tag":39,"props":1946,"children":1948},{"id":1947},"_4-security-misconfiguration",[1949],{"type":36,"value":1950},"4. Security Misconfiguration",{"type":27,"tag":32,"props":1952,"children":1953},{},[1954],{"type":36,"value":1955},"Adopt secure defaults, disable debugging, and avoid detailed error messages:",{"type":27,"tag":77,"props":1957,"children":1961},{"className":1958,"code":1959,"language":1960,"meta":8,"style":8},"language-properties shiki shiki-themes github-dark github-light","server.error.include-stacktrace=never\nserver.error.include-message=never\n","properties",[1962],{"type":27,"tag":15,"props":1963,"children":1964},{"__ignoreMap":8},[1965,1973],{"type":27,"tag":87,"props":1966,"children":1967},{"class":89,"line":90},[1968],{"type":27,"tag":87,"props":1969,"children":1970},{},[1971],{"type":36,"value":1972},"server.error.include-stacktrace=never\n",{"type":27,"tag":87,"props":1974,"children":1975},{"class":89,"line":200},[1976],{"type":27,"tag":87,"props":1977,"children":1978},{},[1979],{"type":36,"value":1980},"server.error.include-message=never\n",{"type":27,"tag":32,"props":1982,"children":1983},{},[1984],{"type":36,"value":1985},"Review and secure your Java application configuration regularly.",{"type":27,"tag":39,"props":1987,"children":1989},{"id":1988},"_5-cross-site-scripting-xss",[1990],{"type":36,"value":1991},"5. Cross-Site Scripting (XSS)",{"type":27,"tag":32,"props":1993,"children":1994},{},[1995],{"type":36,"value":1996},"Utilize proper encoding or frameworks that prevent XSS by default, such as Thymeleaf:",{"type":27,"tag":77,"props":1998,"children":2002},{"className":1999,"code":2000,"language":2001,"meta":8,"style":8},"language-html shiki shiki-themes github-dark github-light","\u003Cp th:text=\"${userInput}\">\u003C/p>\n","html",[2003],{"type":27,"tag":15,"props":2004,"children":2005},{"__ignoreMap":8},[2006],{"type":27,"tag":87,"props":2007,"children":2008},{"class":89,"line":90},[2009],{"type":27,"tag":87,"props":2010,"children":2011},{},[2012],{"type":36,"value":2000},{"type":27,"tag":32,"props":2014,"children":2015},{},[2016],{"type":36,"value":2017},"Avoid directly inserting user inputs into HTML without proper sanitization or encoding.",{"type":27,"tag":39,"props":2019,"children":2021},{"id":2020},"_6-insecure-deserialization",[2022],{"type":36,"value":2023},"6. Insecure Deserialization",{"type":27,"tag":32,"props":2025,"children":2026},{},[2027],{"type":36,"value":2028},"Limit deserialization to trusted sources only:",{"type":27,"tag":77,"props":2030,"children":2032},{"className":1566,"code":2031,"language":1469,"meta":8,"style":8},"ObjectInputStream ois = new ObjectInputStream(new FileInputStream(\"trusted_data.ser\"));\nMyObject obj = (MyObject) ois.readObject();\n",[2033],{"type":27,"tag":15,"props":2034,"children":2035},{"__ignoreMap":8},[2036,2086],{"type":27,"tag":87,"props":2037,"children":2038},{"class":89,"line":90},[2039,2044,2048,2053,2058,2062,2067,2072,2076,2081],{"type":27,"tag":87,"props":2040,"children":2041},{"style":184},[2042],{"type":36,"value":2043},"ObjectInputStream ois ",{"type":27,"tag":87,"props":2045,"children":2046},{"style":178},[2047],{"type":36,"value":325},{"type":27,"tag":87,"props":2049,"children":2050},{"style":178},[2051],{"type":36,"value":2052}," new",{"type":27,"tag":87,"props":2054,"children":2055},{"style":94},[2056],{"type":36,"value":2057}," ObjectInputStream",{"type":27,"tag":87,"props":2059,"children":2060},{"style":184},[2061],{"type":36,"value":1282},{"type":27,"tag":87,"props":2063,"children":2064},{"style":178},[2065],{"type":36,"value":2066},"new",{"type":27,"tag":87,"props":2068,"children":2069},{"style":94},[2070],{"type":36,"value":2071}," FileInputStream",{"type":27,"tag":87,"props":2073,"children":2074},{"style":184},[2075],{"type":36,"value":1282},{"type":27,"tag":87,"props":2077,"children":2078},{"style":100},[2079],{"type":36,"value":2080},"\"trusted_data.ser\"",{"type":27,"tag":87,"props":2082,"children":2083},{"style":184},[2084],{"type":36,"value":2085},"));\n",{"type":27,"tag":87,"props":2087,"children":2088},{"class":89,"line":200},[2089,2094,2098,2103,2108],{"type":27,"tag":87,"props":2090,"children":2091},{"style":184},[2092],{"type":36,"value":2093},"MyObject obj ",{"type":27,"tag":87,"props":2095,"children":2096},{"style":178},[2097],{"type":36,"value":325},{"type":27,"tag":87,"props":2099,"children":2100},{"style":184},[2101],{"type":36,"value":2102}," (MyObject) ois.",{"type":27,"tag":87,"props":2104,"children":2105},{"style":94},[2106],{"type":36,"value":2107},"readObject",{"type":27,"tag":87,"props":2109,"children":2110},{"style":184},[2111],{"type":36,"value":1686},{"type":27,"tag":32,"props":2113,"children":2114},{},[2115],{"type":36,"value":2116},"Always validate deserialized data.",{"type":27,"tag":39,"props":2118,"children":2120},{"id":2119},"_7-component-vulnerabilities",[2121],{"type":36,"value":2122},"7. Component Vulnerabilities",{"type":27,"tag":32,"props":2124,"children":2125},{},[2126],{"type":36,"value":2127},"Regularly update libraries and dependencies, and use tools like OWASP Dependency-Check to identify vulnerabilities:",{"type":27,"tag":77,"props":2129,"children":2133},{"className":2130,"code":2131,"language":2132,"meta":8,"style":8},"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",[2134],{"type":27,"tag":15,"props":2135,"children":2136},{"__ignoreMap":8},[2137,2156,2182,2207,2232],{"type":27,"tag":87,"props":2138,"children":2139},{"class":89,"line":90},[2140,2145,2151],{"type":27,"tag":87,"props":2141,"children":2142},{"style":184},[2143],{"type":36,"value":2144},"\u003C",{"type":27,"tag":87,"props":2146,"children":2148},{"style":2147},"--shiki-default:#85E89D;--shiki-light:#22863A",[2149],{"type":36,"value":2150},"plugin",{"type":27,"tag":87,"props":2152,"children":2153},{"style":184},[2154],{"type":36,"value":2155},">\n",{"type":27,"tag":87,"props":2157,"children":2158},{"class":89,"line":200},[2159,2164,2169,2174,2178],{"type":27,"tag":87,"props":2160,"children":2161},{"style":184},[2162],{"type":36,"value":2163},"    \u003C",{"type":27,"tag":87,"props":2165,"children":2166},{"style":2147},[2167],{"type":36,"value":2168},"groupId",{"type":27,"tag":87,"props":2170,"children":2171},{"style":184},[2172],{"type":36,"value":2173},">org.owasp\u003C/",{"type":27,"tag":87,"props":2175,"children":2176},{"style":2147},[2177],{"type":36,"value":2168},{"type":27,"tag":87,"props":2179,"children":2180},{"style":184},[2181],{"type":36,"value":2155},{"type":27,"tag":87,"props":2183,"children":2184},{"class":89,"line":222},[2185,2189,2194,2199,2203],{"type":27,"tag":87,"props":2186,"children":2187},{"style":184},[2188],{"type":36,"value":2163},{"type":27,"tag":87,"props":2190,"children":2191},{"style":2147},[2192],{"type":36,"value":2193},"artifactId",{"type":27,"tag":87,"props":2195,"children":2196},{"style":184},[2197],{"type":36,"value":2198},">dependency-check-maven\u003C/",{"type":27,"tag":87,"props":2200,"children":2201},{"style":2147},[2202],{"type":36,"value":2193},{"type":27,"tag":87,"props":2204,"children":2205},{"style":184},[2206],{"type":36,"value":2155},{"type":27,"tag":87,"props":2208,"children":2209},{"class":89,"line":235},[2210,2214,2219,2224,2228],{"type":27,"tag":87,"props":2211,"children":2212},{"style":184},[2213],{"type":36,"value":2163},{"type":27,"tag":87,"props":2215,"children":2216},{"style":2147},[2217],{"type":36,"value":2218},"version",{"type":27,"tag":87,"props":2220,"children":2221},{"style":184},[2222],{"type":36,"value":2223},">9.0.9\u003C/",{"type":27,"tag":87,"props":2225,"children":2226},{"style":2147},[2227],{"type":36,"value":2218},{"type":27,"tag":87,"props":2229,"children":2230},{"style":184},[2231],{"type":36,"value":2155},{"type":27,"tag":87,"props":2233,"children":2234},{"class":89,"line":257},[2235,2240,2244],{"type":27,"tag":87,"props":2236,"children":2237},{"style":184},[2238],{"type":36,"value":2239},"\u003C/",{"type":27,"tag":87,"props":2241,"children":2242},{"style":2147},[2243],{"type":36,"value":2150},{"type":27,"tag":87,"props":2245,"children":2246},{"style":184},[2247],{"type":36,"value":2155},{"type":27,"tag":32,"props":2249,"children":2250},{},[2251],{"type":36,"value":2252},"Execute dependency checks regularly in your CI/CD pipeline.",{"type":27,"tag":39,"props":2254,"children":2256},{"id":2255},"_8-logging-and-monitoring",[2257],{"type":36,"value":2258},"8. Logging and Monitoring",{"type":27,"tag":32,"props":2260,"children":2261},{},[2262],{"type":36,"value":2263},"Implement comprehensive logging and monitoring to detect and respond to security incidents:",{"type":27,"tag":77,"props":2265,"children":2267},{"className":1566,"code":2266,"language":1469,"meta":8,"style":8},"logger.warn(\"Failed login attempt for user: {}\", username);\n",[2268],{"type":27,"tag":15,"props":2269,"children":2270},{"__ignoreMap":8},[2271],{"type":27,"tag":87,"props":2272,"children":2273},{"class":89,"line":90},[2274,2279,2284,2288,2293],{"type":27,"tag":87,"props":2275,"children":2276},{"style":184},[2277],{"type":36,"value":2278},"logger.",{"type":27,"tag":87,"props":2280,"children":2281},{"style":94},[2282],{"type":36,"value":2283},"warn",{"type":27,"tag":87,"props":2285,"children":2286},{"style":184},[2287],{"type":36,"value":1282},{"type":27,"tag":87,"props":2289,"children":2290},{"style":100},[2291],{"type":36,"value":2292},"\"Failed login attempt for user: {}\"",{"type":27,"tag":87,"props":2294,"children":2295},{"style":184},[2296],{"type":36,"value":1634},{"type":27,"tag":32,"props":2298,"children":2299},{},[2300],{"type":36,"value":2301},"Aggregate logs centrally, and set up alerts for suspicious activities.",{"type":27,"tag":39,"props":2303,"children":2305},{"id":2304},"conclusion",[2306],{"type":36,"value":2307},"Conclusion",{"type":27,"tag":32,"props":2309,"children":2310},{},[2311],{"type":36,"value":2312},"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":27,"tag":1397,"props":2314,"children":2316},{"id":2315},"further-reading",[2317],{"type":36,"value":2318},"Further Reading",{"type":27,"tag":46,"props":2320,"children":2321},{},[2322,2332,2342],{"type":27,"tag":50,"props":2323,"children":2324},{},[2325],{"type":27,"tag":1410,"props":2326,"children":2329},{"href":2327,"rel":2328},"https://owasp.org/www-project-top-ten/",[1414],[2330],{"type":36,"value":2331},"OWASP Top 10",{"type":27,"tag":50,"props":2333,"children":2334},{},[2335],{"type":27,"tag":1410,"props":2336,"children":2339},{"href":2337,"rel":2338},"https://spring.io/projects/spring-security",[1414],[2340],{"type":36,"value":2341},"Spring Security",{"type":27,"tag":50,"props":2343,"children":2344},{},[2345],{"type":27,"tag":1410,"props":2346,"children":2349},{"href":2347,"rel":2348},"https://owasp.org/www-project-dependency-check/",[1414],[2350],{"type":36,"value":2351},"OWASP Dependency Check",{"type":27,"tag":1439,"props":2353,"children":2354},{},[2355],{"type":36,"value":1443},{"title":8,"searchDepth":200,"depth":200,"links":2357},[2358,2359,2360,2361,2362,2363,2364,2365,2366,2367],{"id":1485,"depth":200,"text":1488},{"id":1555,"depth":200,"text":1558},{"id":1694,"depth":200,"text":1697},{"id":1808,"depth":200,"text":1811},{"id":1947,"depth":200,"text":1950},{"id":1988,"depth":200,"text":1991},{"id":2020,"depth":200,"text":2023},{"id":2119,"depth":200,"text":2122},{"id":2255,"depth":200,"text":2258},{"id":2304,"depth":200,"text":2307},"content:posts:java-security-best-practices.md","posts/java-security-best-practices.md","posts/java-security-best-practices",{"_path":2372,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":2373,"description":2374,"date":2375,"layout":12,"subtitle":2376,"image":2377,"optimized_image":2377,"category":15,"tags":2378,"author":22,"paginate":7,"body":2382,"_type":1455,"_id":3188,"_source":1457,"_file":3189,"_stem":3190,"_extension":1460},"/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",[15,1469,2379,2380,2381],"resilience","circuit-breaker","distributed-systems",{"type":24,"children":2383,"toc":3176},[2384,2392,2398,2403,2437,2442,2448,2453,2471,2477,2484,2489,2599,2605,2809,2815,2820,2987,2993,2998,3092,3097,3103,3126,3130,3135,3139,3172],{"type":27,"tag":28,"props":2385,"children":2386},{},[2387],{"type":27,"tag":32,"props":2388,"children":2389},{},[2390],{"type":36,"value":2391},"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":27,"tag":39,"props":2393,"children":2395},{"id":2394},"understanding-the-circuit-breaker-pattern",[2396],{"type":36,"value":2397},"Understanding the Circuit Breaker Pattern",{"type":27,"tag":32,"props":2399,"children":2400},{},[2401],{"type":36,"value":2402},"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":27,"tag":46,"props":2404,"children":2405},{},[2406,2417,2427],{"type":27,"tag":50,"props":2407,"children":2408},{},[2409,2415],{"type":27,"tag":2410,"props":2411,"children":2412},"strong",{},[2413],{"type":36,"value":2414},"Closed:",{"type":36,"value":2416}," All requests pass through normally.",{"type":27,"tag":50,"props":2418,"children":2419},{},[2420,2425],{"type":27,"tag":2410,"props":2421,"children":2422},{},[2423],{"type":36,"value":2424},"Open:",{"type":36,"value":2426}," Requests fail fast, bypassing the problematic service.",{"type":27,"tag":50,"props":2428,"children":2429},{},[2430,2435],{"type":27,"tag":2410,"props":2431,"children":2432},{},[2433],{"type":36,"value":2434},"Half-Open:",{"type":36,"value":2436}," A limited number of requests test if the external service has recovered.",{"type":27,"tag":32,"props":2438,"children":2439},{},[2440],{"type":36,"value":2441},"This mechanism helps improve the resilience and responsiveness of your systems.",{"type":27,"tag":39,"props":2443,"children":2445},{"id":2444},"when-to-use-circuit-breakers",[2446],{"type":36,"value":2447},"When to Use Circuit Breakers",{"type":27,"tag":32,"props":2449,"children":2450},{},[2451],{"type":36,"value":2452},"Circuit breakers are essential when:",{"type":27,"tag":46,"props":2454,"children":2455},{},[2456,2461,2466],{"type":27,"tag":50,"props":2457,"children":2458},{},[2459],{"type":36,"value":2460},"Your system relies on remote calls (microservices architecture, external APIs).",{"type":27,"tag":50,"props":2462,"children":2463},{},[2464],{"type":36,"value":2465},"You need to prevent failure propagation.",{"type":27,"tag":50,"props":2467,"children":2468},{},[2469],{"type":36,"value":2470},"You aim to improve user experience by quickly responding to failures.",{"type":27,"tag":39,"props":2472,"children":2474},{"id":2473},"implementing-circuit-breakers-with-resilience4j",[2475],{"type":36,"value":2476},"Implementing Circuit Breakers with Resilience4j",{"type":27,"tag":2478,"props":2479,"children":2481},"h3",{"id":2480},"step-1-adding-dependencies",[2482],{"type":36,"value":2483},"Step 1: Adding Dependencies",{"type":27,"tag":32,"props":2485,"children":2486},{},[2487],{"type":36,"value":2488},"Add Resilience4j dependencies to your project (Maven example):",{"type":27,"tag":77,"props":2490,"children":2492},{"className":2130,"code":2491,"language":2132,"meta":8,"style":8},"\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",[2493],{"type":27,"tag":15,"props":2494,"children":2495},{"__ignoreMap":8},[2496,2512,2536,2560,2584],{"type":27,"tag":87,"props":2497,"children":2498},{"class":89,"line":90},[2499,2503,2508],{"type":27,"tag":87,"props":2500,"children":2501},{"style":184},[2502],{"type":36,"value":2144},{"type":27,"tag":87,"props":2504,"children":2505},{"style":2147},[2506],{"type":36,"value":2507},"dependency",{"type":27,"tag":87,"props":2509,"children":2510},{"style":184},[2511],{"type":36,"value":2155},{"type":27,"tag":87,"props":2513,"children":2514},{"class":89,"line":200},[2515,2519,2523,2528,2532],{"type":27,"tag":87,"props":2516,"children":2517},{"style":184},[2518],{"type":36,"value":2163},{"type":27,"tag":87,"props":2520,"children":2521},{"style":2147},[2522],{"type":36,"value":2168},{"type":27,"tag":87,"props":2524,"children":2525},{"style":184},[2526],{"type":36,"value":2527},">io.github.resilience4j\u003C/",{"type":27,"tag":87,"props":2529,"children":2530},{"style":2147},[2531],{"type":36,"value":2168},{"type":27,"tag":87,"props":2533,"children":2534},{"style":184},[2535],{"type":36,"value":2155},{"type":27,"tag":87,"props":2537,"children":2538},{"class":89,"line":222},[2539,2543,2547,2552,2556],{"type":27,"tag":87,"props":2540,"children":2541},{"style":184},[2542],{"type":36,"value":2163},{"type":27,"tag":87,"props":2544,"children":2545},{"style":2147},[2546],{"type":36,"value":2193},{"type":27,"tag":87,"props":2548,"children":2549},{"style":184},[2550],{"type":36,"value":2551},">resilience4j-circuitbreaker\u003C/",{"type":27,"tag":87,"props":2553,"children":2554},{"style":2147},[2555],{"type":36,"value":2193},{"type":27,"tag":87,"props":2557,"children":2558},{"style":184},[2559],{"type":36,"value":2155},{"type":27,"tag":87,"props":2561,"children":2562},{"class":89,"line":235},[2563,2567,2571,2576,2580],{"type":27,"tag":87,"props":2564,"children":2565},{"style":184},[2566],{"type":36,"value":2163},{"type":27,"tag":87,"props":2568,"children":2569},{"style":2147},[2570],{"type":36,"value":2218},{"type":27,"tag":87,"props":2572,"children":2573},{"style":184},[2574],{"type":36,"value":2575},">2.0.2\u003C/",{"type":27,"tag":87,"props":2577,"children":2578},{"style":2147},[2579],{"type":36,"value":2218},{"type":27,"tag":87,"props":2581,"children":2582},{"style":184},[2583],{"type":36,"value":2155},{"type":27,"tag":87,"props":2585,"children":2586},{"class":89,"line":257},[2587,2591,2595],{"type":27,"tag":87,"props":2588,"children":2589},{"style":184},[2590],{"type":36,"value":2239},{"type":27,"tag":87,"props":2592,"children":2593},{"style":2147},[2594],{"type":36,"value":2507},{"type":27,"tag":87,"props":2596,"children":2597},{"style":184},[2598],{"type":36,"value":2155},{"type":27,"tag":2478,"props":2600,"children":2602},{"id":2601},"step-2-configuring-circuit-breaker",[2603],{"type":36,"value":2604},"Step 2: Configuring Circuit Breaker",{"type":27,"tag":77,"props":2606,"children":2608},{"className":1566,"code":2607,"language":1469,"meta":8,"style":8},"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",[2609],{"type":27,"tag":15,"props":2610,"children":2611},{"__ignoreMap":8},[2612,2639,2665,2701,2725,2750,2766,2773],{"type":27,"tag":87,"props":2613,"children":2614},{"class":89,"line":90},[2615,2620,2624,2629,2634],{"type":27,"tag":87,"props":2616,"children":2617},{"style":184},[2618],{"type":36,"value":2619},"CircuitBreakerConfig config ",{"type":27,"tag":87,"props":2621,"children":2622},{"style":178},[2623],{"type":36,"value":325},{"type":27,"tag":87,"props":2625,"children":2626},{"style":184},[2627],{"type":36,"value":2628}," CircuitBreakerConfig.",{"type":27,"tag":87,"props":2630,"children":2631},{"style":94},[2632],{"type":36,"value":2633},"custom",{"type":27,"tag":87,"props":2635,"children":2636},{"style":184},[2637],{"type":36,"value":2638},"()\n",{"type":27,"tag":87,"props":2640,"children":2641},{"class":89,"line":200},[2642,2647,2652,2656,2661],{"type":27,"tag":87,"props":2643,"children":2644},{"style":184},[2645],{"type":36,"value":2646},"    .",{"type":27,"tag":87,"props":2648,"children":2649},{"style":94},[2650],{"type":36,"value":2651},"failureRateThreshold",{"type":27,"tag":87,"props":2653,"children":2654},{"style":184},[2655],{"type":36,"value":1282},{"type":27,"tag":87,"props":2657,"children":2658},{"style":288},[2659],{"type":36,"value":2660},"50",{"type":27,"tag":87,"props":2662,"children":2663},{"style":184},[2664],{"type":36,"value":311},{"type":27,"tag":87,"props":2666,"children":2667},{"class":89,"line":222},[2668,2672,2677,2682,2687,2691,2696],{"type":27,"tag":87,"props":2669,"children":2670},{"style":184},[2671],{"type":36,"value":2646},{"type":27,"tag":87,"props":2673,"children":2674},{"style":94},[2675],{"type":36,"value":2676},"waitDurationInOpenState",{"type":27,"tag":87,"props":2678,"children":2679},{"style":184},[2680],{"type":36,"value":2681},"(Duration.",{"type":27,"tag":87,"props":2683,"children":2684},{"style":94},[2685],{"type":36,"value":2686},"ofMillis",{"type":27,"tag":87,"props":2688,"children":2689},{"style":184},[2690],{"type":36,"value":1282},{"type":27,"tag":87,"props":2692,"children":2693},{"style":288},[2694],{"type":36,"value":2695},"1000",{"type":27,"tag":87,"props":2697,"children":2698},{"style":184},[2699],{"type":36,"value":2700},"))\n",{"type":27,"tag":87,"props":2702,"children":2703},{"class":89,"line":235},[2704,2708,2713,2717,2721],{"type":27,"tag":87,"props":2705,"children":2706},{"style":184},[2707],{"type":36,"value":2646},{"type":27,"tag":87,"props":2709,"children":2710},{"style":94},[2711],{"type":36,"value":2712},"permittedNumberOfCallsInHalfOpenState",{"type":27,"tag":87,"props":2714,"children":2715},{"style":184},[2716],{"type":36,"value":1282},{"type":27,"tag":87,"props":2718,"children":2719},{"style":288},[2720],{"type":36,"value":1654},{"type":27,"tag":87,"props":2722,"children":2723},{"style":184},[2724],{"type":36,"value":311},{"type":27,"tag":87,"props":2726,"children":2727},{"class":89,"line":257},[2728,2732,2737,2741,2746],{"type":27,"tag":87,"props":2729,"children":2730},{"style":184},[2731],{"type":36,"value":2646},{"type":27,"tag":87,"props":2733,"children":2734},{"style":94},[2735],{"type":36,"value":2736},"minimumNumberOfCalls",{"type":27,"tag":87,"props":2738,"children":2739},{"style":184},[2740],{"type":36,"value":1282},{"type":27,"tag":87,"props":2742,"children":2743},{"style":288},[2744],{"type":36,"value":2745},"5",{"type":27,"tag":87,"props":2747,"children":2748},{"style":184},[2749],{"type":36,"value":311},{"type":27,"tag":87,"props":2751,"children":2752},{"class":89,"line":267},[2753,2757,2762],{"type":27,"tag":87,"props":2754,"children":2755},{"style":184},[2756],{"type":36,"value":2646},{"type":27,"tag":87,"props":2758,"children":2759},{"style":94},[2760],{"type":36,"value":2761},"build",{"type":27,"tag":87,"props":2763,"children":2764},{"style":184},[2765],{"type":36,"value":1686},{"type":27,"tag":87,"props":2767,"children":2768},{"class":89,"line":276},[2769],{"type":27,"tag":87,"props":2770,"children":2771},{"emptyLinePlaceholder":261},[2772],{"type":36,"value":264},{"type":27,"tag":87,"props":2774,"children":2775},{"class":89,"line":284},[2776,2781,2785,2790,2795,2799,2804],{"type":27,"tag":87,"props":2777,"children":2778},{"style":184},[2779],{"type":36,"value":2780},"CircuitBreaker circuitBreaker ",{"type":27,"tag":87,"props":2782,"children":2783},{"style":178},[2784],{"type":36,"value":325},{"type":27,"tag":87,"props":2786,"children":2787},{"style":184},[2788],{"type":36,"value":2789}," CircuitBreaker.",{"type":27,"tag":87,"props":2791,"children":2792},{"style":94},[2793],{"type":36,"value":2794},"of",{"type":27,"tag":87,"props":2796,"children":2797},{"style":184},[2798],{"type":36,"value":1282},{"type":27,"tag":87,"props":2800,"children":2801},{"style":100},[2802],{"type":36,"value":2803},"\"myService\"",{"type":27,"tag":87,"props":2805,"children":2806},{"style":184},[2807],{"type":36,"value":2808},", config);\n",{"type":27,"tag":2478,"props":2810,"children":2812},{"id":2811},"step-3-using-circuit-breaker",[2813],{"type":36,"value":2814},"Step 3: Using Circuit Breaker",{"type":27,"tag":32,"props":2816,"children":2817},{},[2818],{"type":36,"value":2819},"Wrap service calls using the circuit breaker:",{"type":27,"tag":77,"props":2821,"children":2823},{"className":1566,"code":2822,"language":1469,"meta":8,"style":8},"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",[2824],{"type":27,"tag":15,"props":2825,"children":2826},{"__ignoreMap":8},[2827,2882,2889,2907,2937],{"type":27,"tag":87,"props":2828,"children":2829},{"class":89,"line":90},[2830,2835,2840,2845,2849,2853,2858,2863,2868,2873,2878],{"type":27,"tag":87,"props":2831,"children":2832},{"style":184},[2833],{"type":36,"value":2834},"Supplier\u003C",{"type":27,"tag":87,"props":2836,"children":2837},{"style":178},[2838],{"type":36,"value":2839},"String",{"type":27,"tag":87,"props":2841,"children":2842},{"style":184},[2843],{"type":36,"value":2844},"> decoratedSupplier ",{"type":27,"tag":87,"props":2846,"children":2847},{"style":178},[2848],{"type":36,"value":325},{"type":27,"tag":87,"props":2850,"children":2851},{"style":184},[2852],{"type":36,"value":2789},{"type":27,"tag":87,"props":2854,"children":2855},{"style":94},[2856],{"type":36,"value":2857},"decorateSupplier",{"type":27,"tag":87,"props":2859,"children":2860},{"style":184},[2861],{"type":36,"value":2862},"(circuitBreaker, () ",{"type":27,"tag":87,"props":2864,"children":2865},{"style":178},[2866],{"type":36,"value":2867},"->",{"type":27,"tag":87,"props":2869,"children":2870},{"style":184},[2871],{"type":36,"value":2872}," myService.",{"type":27,"tag":87,"props":2874,"children":2875},{"style":94},[2876],{"type":36,"value":2877},"remoteCall",{"type":27,"tag":87,"props":2879,"children":2880},{"style":184},[2881],{"type":36,"value":1765},{"type":27,"tag":87,"props":2883,"children":2884},{"class":89,"line":200},[2885],{"type":27,"tag":87,"props":2886,"children":2887},{"emptyLinePlaceholder":261},[2888],{"type":36,"value":264},{"type":27,"tag":87,"props":2890,"children":2891},{"class":89,"line":222},[2892,2897,2902],{"type":27,"tag":87,"props":2893,"children":2894},{"style":184},[2895],{"type":36,"value":2896},"Try.",{"type":27,"tag":87,"props":2898,"children":2899},{"style":94},[2900],{"type":36,"value":2901},"ofSupplier",{"type":27,"tag":87,"props":2903,"children":2904},{"style":184},[2905],{"type":36,"value":2906},"(decoratedSupplier)\n",{"type":27,"tag":87,"props":2908,"children":2909},{"class":89,"line":235},[2910,2914,2919,2924,2928,2933],{"type":27,"tag":87,"props":2911,"children":2912},{"style":184},[2913],{"type":36,"value":2646},{"type":27,"tag":87,"props":2915,"children":2916},{"style":94},[2917],{"type":36,"value":2918},"recover",{"type":27,"tag":87,"props":2920,"children":2921},{"style":184},[2922],{"type":36,"value":2923},"(throwable ",{"type":27,"tag":87,"props":2925,"children":2926},{"style":178},[2927],{"type":36,"value":2867},{"type":27,"tag":87,"props":2929,"children":2930},{"style":100},[2931],{"type":36,"value":2932}," \"Fallback response\"",{"type":27,"tag":87,"props":2934,"children":2935},{"style":184},[2936],{"type":36,"value":311},{"type":27,"tag":87,"props":2938,"children":2939},{"class":89,"line":257},[2940,2944,2949,2954,2958,2963,2968,2972,2977,2982],{"type":27,"tag":87,"props":2941,"children":2942},{"style":184},[2943],{"type":36,"value":2646},{"type":27,"tag":87,"props":2945,"children":2946},{"style":94},[2947],{"type":36,"value":2948},"onSuccess",{"type":27,"tag":87,"props":2950,"children":2951},{"style":184},[2952],{"type":36,"value":2953},"(result ",{"type":27,"tag":87,"props":2955,"children":2956},{"style":178},[2957],{"type":36,"value":2867},{"type":27,"tag":87,"props":2959,"children":2960},{"style":184},[2961],{"type":36,"value":2962}," System.out.",{"type":27,"tag":87,"props":2964,"children":2965},{"style":94},[2966],{"type":36,"value":2967},"println",{"type":27,"tag":87,"props":2969,"children":2970},{"style":184},[2971],{"type":36,"value":1282},{"type":27,"tag":87,"props":2973,"children":2974},{"style":100},[2975],{"type":36,"value":2976},"\"Response: \"",{"type":27,"tag":87,"props":2978,"children":2979},{"style":178},[2980],{"type":36,"value":2981}," +",{"type":27,"tag":87,"props":2983,"children":2984},{"style":184},[2985],{"type":36,"value":2986}," result));\n",{"type":27,"tag":39,"props":2988,"children":2990},{"id":2989},"monitoring-and-metrics",[2991],{"type":36,"value":2992},"Monitoring and Metrics",{"type":27,"tag":32,"props":2994,"children":2995},{},[2996],{"type":36,"value":2997},"Resilience4j provides built-in support for metrics and monitoring:",{"type":27,"tag":77,"props":2999,"children":3001},{"className":1566,"code":3000,"language":1469,"meta":8,"style":8},"CircuitBreakerRegistry registry = CircuitBreakerRegistry.ofDefaults();\nregistry.getEventPublisher()\n    .onStateTransition(event -> System.out.println(event.getStateTransition()));\n",[3002],{"type":27,"tag":15,"props":3003,"children":3004},{"__ignoreMap":8},[3005,3031,3048],{"type":27,"tag":87,"props":3006,"children":3007},{"class":89,"line":90},[3008,3013,3017,3022,3027],{"type":27,"tag":87,"props":3009,"children":3010},{"style":184},[3011],{"type":36,"value":3012},"CircuitBreakerRegistry registry ",{"type":27,"tag":87,"props":3014,"children":3015},{"style":178},[3016],{"type":36,"value":325},{"type":27,"tag":87,"props":3018,"children":3019},{"style":184},[3020],{"type":36,"value":3021}," CircuitBreakerRegistry.",{"type":27,"tag":87,"props":3023,"children":3024},{"style":94},[3025],{"type":36,"value":3026},"ofDefaults",{"type":27,"tag":87,"props":3028,"children":3029},{"style":184},[3030],{"type":36,"value":1686},{"type":27,"tag":87,"props":3032,"children":3033},{"class":89,"line":200},[3034,3039,3044],{"type":27,"tag":87,"props":3035,"children":3036},{"style":184},[3037],{"type":36,"value":3038},"registry.",{"type":27,"tag":87,"props":3040,"children":3041},{"style":94},[3042],{"type":36,"value":3043},"getEventPublisher",{"type":27,"tag":87,"props":3045,"children":3046},{"style":184},[3047],{"type":36,"value":2638},{"type":27,"tag":87,"props":3049,"children":3050},{"class":89,"line":222},[3051,3055,3060,3065,3069,3073,3077,3082,3087],{"type":27,"tag":87,"props":3052,"children":3053},{"style":184},[3054],{"type":36,"value":2646},{"type":27,"tag":87,"props":3056,"children":3057},{"style":94},[3058],{"type":36,"value":3059},"onStateTransition",{"type":27,"tag":87,"props":3061,"children":3062},{"style":184},[3063],{"type":36,"value":3064},"(event ",{"type":27,"tag":87,"props":3066,"children":3067},{"style":178},[3068],{"type":36,"value":2867},{"type":27,"tag":87,"props":3070,"children":3071},{"style":184},[3072],{"type":36,"value":2962},{"type":27,"tag":87,"props":3074,"children":3075},{"style":94},[3076],{"type":36,"value":2967},{"type":27,"tag":87,"props":3078,"children":3079},{"style":184},[3080],{"type":36,"value":3081},"(event.",{"type":27,"tag":87,"props":3083,"children":3084},{"style":94},[3085],{"type":36,"value":3086},"getStateTransition",{"type":27,"tag":87,"props":3088,"children":3089},{"style":184},[3090],{"type":36,"value":3091},"()));\n",{"type":27,"tag":32,"props":3093,"children":3094},{},[3095],{"type":36,"value":3096},"Integrate with Prometheus, Grafana, or other observability tools for comprehensive monitoring.",{"type":27,"tag":39,"props":3098,"children":3100},{"id":3099},"best-practices-for-circuit-breaking",[3101],{"type":36,"value":3102},"Best Practices for Circuit Breaking",{"type":27,"tag":46,"props":3104,"children":3105},{},[3106,3111,3116,3121],{"type":27,"tag":50,"props":3107,"children":3108},{},[3109],{"type":36,"value":3110},"Configure sensible thresholds to avoid premature circuit opening.",{"type":27,"tag":50,"props":3112,"children":3113},{},[3114],{"type":36,"value":3115},"Always define fallback mechanisms.",{"type":27,"tag":50,"props":3117,"children":3118},{},[3119],{"type":36,"value":3120},"Regularly monitor circuit breaker states and metrics.",{"type":27,"tag":50,"props":3122,"children":3123},{},[3124],{"type":36,"value":3125},"Test thoroughly to ensure reliability under failure conditions.",{"type":27,"tag":39,"props":3127,"children":3128},{"id":2304},[3129],{"type":36,"value":2307},{"type":27,"tag":32,"props":3131,"children":3132},{},[3133],{"type":36,"value":3134},"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":27,"tag":1397,"props":3136,"children":3137},{"id":2315},[3138],{"type":36,"value":2318},{"type":27,"tag":46,"props":3140,"children":3141},{},[3142,3152,3162],{"type":27,"tag":50,"props":3143,"children":3144},{},[3145],{"type":27,"tag":1410,"props":3146,"children":3149},{"href":3147,"rel":3148},"https://resilience4j.readme.io/docs",[1414],[3150],{"type":36,"value":3151},"Resilience4j Official Documentation",{"type":27,"tag":50,"props":3153,"children":3154},{},[3155],{"type":27,"tag":1410,"props":3156,"children":3159},{"href":3157,"rel":3158},"https://martinfowler.com/bliki/CircuitBreaker.html",[1414],[3160],{"type":36,"value":3161},"Circuit Breaker Pattern by Martin Fowler",{"type":27,"tag":50,"props":3163,"children":3164},{},[3165],{"type":27,"tag":1410,"props":3166,"children":3169},{"href":3167,"rel":3168},"https://microservices.io/patterns/reliability/circuit-breaker.html",[1414],[3170],{"type":36,"value":3171},"Microservices Patterns by Chris Richardson",{"type":27,"tag":1439,"props":3173,"children":3174},{},[3175],{"type":36,"value":1443},{"title":8,"searchDepth":200,"depth":200,"links":3177},[3178,3179,3180,3185,3186,3187],{"id":2394,"depth":200,"text":2397},{"id":2444,"depth":200,"text":2447},{"id":2473,"depth":200,"text":2476,"children":3181},[3182,3183,3184],{"id":2480,"depth":222,"text":2483},{"id":2601,"depth":222,"text":2604},{"id":2811,"depth":222,"text":2814},{"id":2989,"depth":200,"text":2992},{"id":3099,"depth":200,"text":3102},{"id":2304,"depth":200,"text":2307},"content:posts:circuit-breaking-resilience.md","posts/circuit-breaking-resilience.md","posts/circuit-breaking-resilience",{"_path":3192,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":3193,"description":3194,"date":3195,"layout":12,"subtitle":3196,"image":3197,"optimized_image":3197,"category":15,"tags":3198,"author":22,"paginate":7,"body":3202,"_type":1455,"_id":4198,"_source":1457,"_file":4199,"_stem":4200,"_extension":1460},"/posts/maven-and-github-actions","Automating Java Builds with Maven and GitHub Actions CI/CD","Learn how to set up automated Java build pipelines using Maven and GitHub Actions, including practical examples and detailed instructions.","2024-06-15T11:00:00.000Z","A Step-by-Step Guide to Continuous Integration and Deployment","/assets/img/uploads/java-maven-github-actions.png",[15,1469,3199,3200,3201],"maven","github-actions","cicd",{"type":24,"children":3203,"toc":4187},[3204,3226,3232,3253,3259,3264,3272,3285,3616,3622,3681,3687,3692,3852,3858,3863,3935,3947,3953,3958,4017,4029,4035,4058,4064,4069,4124,4137,4141,4146,4150,4183],{"type":27,"tag":28,"props":3205,"children":3206},{},[3207],{"type":27,"tag":32,"props":3208,"children":3209},{},[3210,3212,3217,3219,3224],{"type":36,"value":3211},"Continuous Integration and Continuous Deployment (CI/CD) streamline development workflows, improve software quality, and accelerate delivery. This tutorial guides you through setting up automated Java builds using ",{"type":27,"tag":2410,"props":3213,"children":3214},{},[3215],{"type":36,"value":3216},"Maven",{"type":36,"value":3218}," and ",{"type":27,"tag":2410,"props":3220,"children":3221},{},[3222],{"type":36,"value":3223},"GitHub Actions",{"type":36,"value":3225},".",{"type":27,"tag":39,"props":3227,"children":3229},{"id":3228},"prerequisites",[3230],{"type":36,"value":3231},"Prerequisites",{"type":27,"tag":46,"props":3233,"children":3234},{},[3235,3248],{"type":27,"tag":50,"props":3236,"children":3237},{},[3238,3240,3246],{"type":36,"value":3239},"A Java project with Maven configured (",{"type":27,"tag":15,"props":3241,"children":3243},{"className":3242},[],[3244],{"type":36,"value":3245},"pom.xml",{"type":36,"value":3247},").",{"type":27,"tag":50,"props":3249,"children":3250},{},[3251],{"type":36,"value":3252},"GitHub repository.",{"type":27,"tag":39,"props":3254,"children":3256},{"id":3255},"step-1-setting-up-your-github-actions-workflow",[3257],{"type":36,"value":3258},"Step 1: Setting Up Your GitHub Actions Workflow",{"type":27,"tag":32,"props":3260,"children":3261},{},[3262],{"type":36,"value":3263},"In your repository, create the following directory structure:",{"type":27,"tag":77,"props":3265,"children":3267},{"code":3266},".github/workflows/\n",[3268],{"type":27,"tag":15,"props":3269,"children":3270},{"__ignoreMap":8},[3271],{"type":36,"value":3266},{"type":27,"tag":32,"props":3273,"children":3274},{},[3275,3277,3283],{"type":36,"value":3276},"Create a new file named ",{"type":27,"tag":15,"props":3278,"children":3280},{"className":3279},[],[3281],{"type":36,"value":3282},"maven-ci.yml",{"type":36,"value":3284}," within this directory:",{"type":27,"tag":77,"props":3286,"children":3290},{"code":3287,"language":3288,"meta":8,"className":3289,"style":8},"name: Maven CI\n\non:\n  push:\n    branches: [ \"main\" ]\n  pull_request:\n    branches: [ \"main\" ]\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n\n    steps:\n      - uses: actions/checkout@v4\n      - name: Set up JDK 21\n        uses: actions/setup-java@v4\n        with:\n          java-version: '21'\n          distribution: 'temurin'\n\n      - name: Build with Maven\n        run: mvn clean install\n","yml","language-yml shiki shiki-themes github-dark github-light",[3291],{"type":27,"tag":15,"props":3292,"children":3293},{"__ignoreMap":8},[3294,3311,3318,3330,3342,3365,3377,3396,3403,3415,3427,3444,3451,3463,3485,3505,3522,3534,3551,3569,3577,3598],{"type":27,"tag":87,"props":3295,"children":3296},{"class":89,"line":90},[3297,3302,3306],{"type":27,"tag":87,"props":3298,"children":3299},{"style":2147},[3300],{"type":36,"value":3301},"name",{"type":27,"tag":87,"props":3303,"children":3304},{"style":184},[3305],{"type":36,"value":907},{"type":27,"tag":87,"props":3307,"children":3308},{"style":100},[3309],{"type":36,"value":3310},"Maven CI\n",{"type":27,"tag":87,"props":3312,"children":3313},{"class":89,"line":200},[3314],{"type":27,"tag":87,"props":3315,"children":3316},{"emptyLinePlaceholder":261},[3317],{"type":36,"value":264},{"type":27,"tag":87,"props":3319,"children":3320},{"class":89,"line":222},[3321,3326],{"type":27,"tag":87,"props":3322,"children":3323},{"style":288},[3324],{"type":36,"value":3325},"on",{"type":27,"tag":87,"props":3327,"children":3328},{"style":184},[3329],{"type":36,"value":1216},{"type":27,"tag":87,"props":3331,"children":3332},{"class":89,"line":235},[3333,3338],{"type":27,"tag":87,"props":3334,"children":3335},{"style":2147},[3336],{"type":36,"value":3337},"  push",{"type":27,"tag":87,"props":3339,"children":3340},{"style":184},[3341],{"type":36,"value":1216},{"type":27,"tag":87,"props":3343,"children":3344},{"class":89,"line":257},[3345,3350,3355,3360],{"type":27,"tag":87,"props":3346,"children":3347},{"style":2147},[3348],{"type":36,"value":3349},"    branches",{"type":27,"tag":87,"props":3351,"children":3352},{"style":184},[3353],{"type":36,"value":3354},": [ ",{"type":27,"tag":87,"props":3356,"children":3357},{"style":100},[3358],{"type":36,"value":3359},"\"main\"",{"type":27,"tag":87,"props":3361,"children":3362},{"style":184},[3363],{"type":36,"value":3364}," ]\n",{"type":27,"tag":87,"props":3366,"children":3367},{"class":89,"line":267},[3368,3373],{"type":27,"tag":87,"props":3369,"children":3370},{"style":2147},[3371],{"type":36,"value":3372},"  pull_request",{"type":27,"tag":87,"props":3374,"children":3375},{"style":184},[3376],{"type":36,"value":1216},{"type":27,"tag":87,"props":3378,"children":3379},{"class":89,"line":276},[3380,3384,3388,3392],{"type":27,"tag":87,"props":3381,"children":3382},{"style":2147},[3383],{"type":36,"value":3349},{"type":27,"tag":87,"props":3385,"children":3386},{"style":184},[3387],{"type":36,"value":3354},{"type":27,"tag":87,"props":3389,"children":3390},{"style":100},[3391],{"type":36,"value":3359},{"type":27,"tag":87,"props":3393,"children":3394},{"style":184},[3395],{"type":36,"value":3364},{"type":27,"tag":87,"props":3397,"children":3398},{"class":89,"line":284},[3399],{"type":27,"tag":87,"props":3400,"children":3401},{"emptyLinePlaceholder":261},[3402],{"type":36,"value":264},{"type":27,"tag":87,"props":3404,"children":3405},{"class":89,"line":314},[3406,3411],{"type":27,"tag":87,"props":3407,"children":3408},{"style":2147},[3409],{"type":36,"value":3410},"jobs",{"type":27,"tag":87,"props":3412,"children":3413},{"style":184},[3414],{"type":36,"value":1216},{"type":27,"tag":87,"props":3416,"children":3417},{"class":89,"line":341},[3418,3423],{"type":27,"tag":87,"props":3419,"children":3420},{"style":2147},[3421],{"type":36,"value":3422},"  build",{"type":27,"tag":87,"props":3424,"children":3425},{"style":184},[3426],{"type":36,"value":1216},{"type":27,"tag":87,"props":3428,"children":3429},{"class":89,"line":374},[3430,3435,3439],{"type":27,"tag":87,"props":3431,"children":3432},{"style":2147},[3433],{"type":36,"value":3434},"    runs-on",{"type":27,"tag":87,"props":3436,"children":3437},{"style":184},[3438],{"type":36,"value":907},{"type":27,"tag":87,"props":3440,"children":3441},{"style":100},[3442],{"type":36,"value":3443},"ubuntu-latest\n",{"type":27,"tag":87,"props":3445,"children":3446},{"class":89,"line":699},[3447],{"type":27,"tag":87,"props":3448,"children":3449},{"emptyLinePlaceholder":261},[3450],{"type":36,"value":264},{"type":27,"tag":87,"props":3452,"children":3453},{"class":89,"line":707},[3454,3459],{"type":27,"tag":87,"props":3455,"children":3456},{"style":2147},[3457],{"type":36,"value":3458},"    steps",{"type":27,"tag":87,"props":3460,"children":3461},{"style":184},[3462],{"type":36,"value":1216},{"type":27,"tag":87,"props":3464,"children":3465},{"class":89,"line":725},[3466,3471,3476,3480],{"type":27,"tag":87,"props":3467,"children":3468},{"style":184},[3469],{"type":36,"value":3470},"      - ",{"type":27,"tag":87,"props":3472,"children":3473},{"style":2147},[3474],{"type":36,"value":3475},"uses",{"type":27,"tag":87,"props":3477,"children":3478},{"style":184},[3479],{"type":36,"value":907},{"type":27,"tag":87,"props":3481,"children":3482},{"style":100},[3483],{"type":36,"value":3484},"actions/checkout@v4\n",{"type":27,"tag":87,"props":3486,"children":3487},{"class":89,"line":1039},[3488,3492,3496,3500],{"type":27,"tag":87,"props":3489,"children":3490},{"style":184},[3491],{"type":36,"value":3470},{"type":27,"tag":87,"props":3493,"children":3494},{"style":2147},[3495],{"type":36,"value":3301},{"type":27,"tag":87,"props":3497,"children":3498},{"style":184},[3499],{"type":36,"value":907},{"type":27,"tag":87,"props":3501,"children":3502},{"style":100},[3503],{"type":36,"value":3504},"Set up JDK 21\n",{"type":27,"tag":87,"props":3506,"children":3507},{"class":89,"line":1052},[3508,3513,3517],{"type":27,"tag":87,"props":3509,"children":3510},{"style":2147},[3511],{"type":36,"value":3512},"        uses",{"type":27,"tag":87,"props":3514,"children":3515},{"style":184},[3516],{"type":36,"value":907},{"type":27,"tag":87,"props":3518,"children":3519},{"style":100},[3520],{"type":36,"value":3521},"actions/setup-java@v4\n",{"type":27,"tag":87,"props":3523,"children":3524},{"class":89,"line":1060},[3525,3530],{"type":27,"tag":87,"props":3526,"children":3527},{"style":2147},[3528],{"type":36,"value":3529},"        with",{"type":27,"tag":87,"props":3531,"children":3532},{"style":184},[3533],{"type":36,"value":1216},{"type":27,"tag":87,"props":3535,"children":3536},{"class":89,"line":1088},[3537,3542,3546],{"type":27,"tag":87,"props":3538,"children":3539},{"style":2147},[3540],{"type":36,"value":3541},"          java-version",{"type":27,"tag":87,"props":3543,"children":3544},{"style":184},[3545],{"type":36,"value":907},{"type":27,"tag":87,"props":3547,"children":3548},{"style":100},[3549],{"type":36,"value":3550},"'21'\n",{"type":27,"tag":87,"props":3552,"children":3554},{"class":89,"line":3553},19,[3555,3560,3564],{"type":27,"tag":87,"props":3556,"children":3557},{"style":2147},[3558],{"type":36,"value":3559},"          distribution",{"type":27,"tag":87,"props":3561,"children":3562},{"style":184},[3563],{"type":36,"value":907},{"type":27,"tag":87,"props":3565,"children":3566},{"style":100},[3567],{"type":36,"value":3568},"'temurin'\n",{"type":27,"tag":87,"props":3570,"children":3572},{"class":89,"line":3571},20,[3573],{"type":27,"tag":87,"props":3574,"children":3575},{"emptyLinePlaceholder":261},[3576],{"type":36,"value":264},{"type":27,"tag":87,"props":3578,"children":3580},{"class":89,"line":3579},21,[3581,3585,3589,3593],{"type":27,"tag":87,"props":3582,"children":3583},{"style":184},[3584],{"type":36,"value":3470},{"type":27,"tag":87,"props":3586,"children":3587},{"style":2147},[3588],{"type":36,"value":3301},{"type":27,"tag":87,"props":3590,"children":3591},{"style":184},[3592],{"type":36,"value":907},{"type":27,"tag":87,"props":3594,"children":3595},{"style":100},[3596],{"type":36,"value":3597},"Build with Maven\n",{"type":27,"tag":87,"props":3599,"children":3601},{"class":89,"line":3600},22,[3602,3607,3611],{"type":27,"tag":87,"props":3603,"children":3604},{"style":2147},[3605],{"type":36,"value":3606},"        run",{"type":27,"tag":87,"props":3608,"children":3609},{"style":184},[3610],{"type":36,"value":907},{"type":27,"tag":87,"props":3612,"children":3613},{"style":100},[3614],{"type":36,"value":3615},"mvn clean install\n",{"type":27,"tag":39,"props":3617,"children":3619},{"id":3618},"step-2-understanding-the-workflow",[3620],{"type":36,"value":3621},"Step 2: Understanding the Workflow",{"type":27,"tag":46,"props":3623,"children":3624},{},[3625,3643,3653,3663],{"type":27,"tag":50,"props":3626,"children":3627},{},[3628,3633,3635,3641],{"type":27,"tag":2410,"props":3629,"children":3630},{},[3631],{"type":36,"value":3632},"Trigger:",{"type":36,"value":3634}," Activated on push or pull request to the ",{"type":27,"tag":15,"props":3636,"children":3638},{"className":3637},[],[3639],{"type":36,"value":3640},"main",{"type":36,"value":3642}," branch.",{"type":27,"tag":50,"props":3644,"children":3645},{},[3646,3651],{"type":27,"tag":2410,"props":3647,"children":3648},{},[3649],{"type":36,"value":3650},"Checkout:",{"type":36,"value":3652}," Retrieves the source code from your repository.",{"type":27,"tag":50,"props":3654,"children":3655},{},[3656,3661],{"type":27,"tag":2410,"props":3657,"children":3658},{},[3659],{"type":36,"value":3660},"JDK Setup:",{"type":36,"value":3662}," Installs Java 21 from Temurin.",{"type":27,"tag":50,"props":3664,"children":3665},{},[3666,3671,3673,3679],{"type":27,"tag":2410,"props":3667,"children":3668},{},[3669],{"type":36,"value":3670},"Maven Build:",{"type":36,"value":3672}," Executes Maven goals (",{"type":27,"tag":15,"props":3674,"children":3676},{"className":3675},[],[3677],{"type":36,"value":3678},"clean install",{"type":36,"value":3680},") to compile, test, and package your Java application.",{"type":27,"tag":39,"props":3682,"children":3684},{"id":3683},"step-3-add-maven-test-reports",[3685],{"type":36,"value":3686},"Step 3: Add Maven Test Reports",{"type":27,"tag":32,"props":3688,"children":3689},{},[3690],{"type":36,"value":3691},"Enhance your workflow by generating and uploading test reports:",{"type":27,"tag":77,"props":3693,"children":3695},{"code":3694,"language":3288,"meta":8,"className":3289,"style":8},"- name: Run tests and upload reports\n  run: |\n    mvn test\n  continue-on-error: true\n\n- name: Upload test report\n  uses: actions/upload-artifact@v4\n  with:\n    name: test-report\n    path: target/surefire-reports/\n",[3696],{"type":27,"tag":15,"props":3697,"children":3698},{"__ignoreMap":8},[3699,3720,3737,3745,3762,3769,3789,3806,3818,3835],{"type":27,"tag":87,"props":3700,"children":3701},{"class":89,"line":90},[3702,3707,3711,3715],{"type":27,"tag":87,"props":3703,"children":3704},{"style":184},[3705],{"type":36,"value":3706},"- ",{"type":27,"tag":87,"props":3708,"children":3709},{"style":2147},[3710],{"type":36,"value":3301},{"type":27,"tag":87,"props":3712,"children":3713},{"style":184},[3714],{"type":36,"value":907},{"type":27,"tag":87,"props":3716,"children":3717},{"style":100},[3718],{"type":36,"value":3719},"Run tests and upload reports\n",{"type":27,"tag":87,"props":3721,"children":3722},{"class":89,"line":200},[3723,3728,3732],{"type":27,"tag":87,"props":3724,"children":3725},{"style":2147},[3726],{"type":36,"value":3727},"  run",{"type":27,"tag":87,"props":3729,"children":3730},{"style":184},[3731],{"type":36,"value":907},{"type":27,"tag":87,"props":3733,"children":3734},{"style":178},[3735],{"type":36,"value":3736},"|\n",{"type":27,"tag":87,"props":3738,"children":3739},{"class":89,"line":222},[3740],{"type":27,"tag":87,"props":3741,"children":3742},{"style":100},[3743],{"type":36,"value":3744},"    mvn test\n",{"type":27,"tag":87,"props":3746,"children":3747},{"class":89,"line":235},[3748,3753,3757],{"type":27,"tag":87,"props":3749,"children":3750},{"style":2147},[3751],{"type":36,"value":3752},"  continue-on-error",{"type":27,"tag":87,"props":3754,"children":3755},{"style":184},[3756],{"type":36,"value":907},{"type":27,"tag":87,"props":3758,"children":3759},{"style":288},[3760],{"type":36,"value":3761},"true\n",{"type":27,"tag":87,"props":3763,"children":3764},{"class":89,"line":257},[3765],{"type":27,"tag":87,"props":3766,"children":3767},{"emptyLinePlaceholder":261},[3768],{"type":36,"value":264},{"type":27,"tag":87,"props":3770,"children":3771},{"class":89,"line":267},[3772,3776,3780,3784],{"type":27,"tag":87,"props":3773,"children":3774},{"style":184},[3775],{"type":36,"value":3706},{"type":27,"tag":87,"props":3777,"children":3778},{"style":2147},[3779],{"type":36,"value":3301},{"type":27,"tag":87,"props":3781,"children":3782},{"style":184},[3783],{"type":36,"value":907},{"type":27,"tag":87,"props":3785,"children":3786},{"style":100},[3787],{"type":36,"value":3788},"Upload test report\n",{"type":27,"tag":87,"props":3790,"children":3791},{"class":89,"line":276},[3792,3797,3801],{"type":27,"tag":87,"props":3793,"children":3794},{"style":2147},[3795],{"type":36,"value":3796},"  uses",{"type":27,"tag":87,"props":3798,"children":3799},{"style":184},[3800],{"type":36,"value":907},{"type":27,"tag":87,"props":3802,"children":3803},{"style":100},[3804],{"type":36,"value":3805},"actions/upload-artifact@v4\n",{"type":27,"tag":87,"props":3807,"children":3808},{"class":89,"line":284},[3809,3814],{"type":27,"tag":87,"props":3810,"children":3811},{"style":2147},[3812],{"type":36,"value":3813},"  with",{"type":27,"tag":87,"props":3815,"children":3816},{"style":184},[3817],{"type":36,"value":1216},{"type":27,"tag":87,"props":3819,"children":3820},{"class":89,"line":314},[3821,3826,3830],{"type":27,"tag":87,"props":3822,"children":3823},{"style":2147},[3824],{"type":36,"value":3825},"    name",{"type":27,"tag":87,"props":3827,"children":3828},{"style":184},[3829],{"type":36,"value":907},{"type":27,"tag":87,"props":3831,"children":3832},{"style":100},[3833],{"type":36,"value":3834},"test-report\n",{"type":27,"tag":87,"props":3836,"children":3837},{"class":89,"line":341},[3838,3843,3847],{"type":27,"tag":87,"props":3839,"children":3840},{"style":2147},[3841],{"type":36,"value":3842},"    path",{"type":27,"tag":87,"props":3844,"children":3845},{"style":184},[3846],{"type":36,"value":907},{"type":27,"tag":87,"props":3848,"children":3849},{"style":100},[3850],{"type":36,"value":3851},"target/surefire-reports/\n",{"type":27,"tag":39,"props":3853,"children":3855},{"id":3854},"step-4-deploy-artifacts-optional",[3856],{"type":36,"value":3857},"Step 4: Deploy Artifacts (Optional)",{"type":27,"tag":32,"props":3859,"children":3860},{},[3861],{"type":36,"value":3862},"To automatically deploy artifacts, include the deployment steps:",{"type":27,"tag":77,"props":3864,"children":3866},{"code":3865,"language":3288,"meta":8,"className":3289,"style":8},"- name: Deploy package\n  env:\n    GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n  run: mvn deploy\n",[3867],{"type":27,"tag":15,"props":3868,"children":3869},{"__ignoreMap":8},[3870,3890,3902,3919],{"type":27,"tag":87,"props":3871,"children":3872},{"class":89,"line":90},[3873,3877,3881,3885],{"type":27,"tag":87,"props":3874,"children":3875},{"style":184},[3876],{"type":36,"value":3706},{"type":27,"tag":87,"props":3878,"children":3879},{"style":2147},[3880],{"type":36,"value":3301},{"type":27,"tag":87,"props":3882,"children":3883},{"style":184},[3884],{"type":36,"value":907},{"type":27,"tag":87,"props":3886,"children":3887},{"style":100},[3888],{"type":36,"value":3889},"Deploy package\n",{"type":27,"tag":87,"props":3891,"children":3892},{"class":89,"line":200},[3893,3898],{"type":27,"tag":87,"props":3894,"children":3895},{"style":2147},[3896],{"type":36,"value":3897},"  env",{"type":27,"tag":87,"props":3899,"children":3900},{"style":184},[3901],{"type":36,"value":1216},{"type":27,"tag":87,"props":3903,"children":3904},{"class":89,"line":222},[3905,3910,3914],{"type":27,"tag":87,"props":3906,"children":3907},{"style":2147},[3908],{"type":36,"value":3909},"    GITHUB_TOKEN",{"type":27,"tag":87,"props":3911,"children":3912},{"style":184},[3913],{"type":36,"value":907},{"type":27,"tag":87,"props":3915,"children":3916},{"style":100},[3917],{"type":36,"value":3918},"${{ secrets.GITHUB_TOKEN }}\n",{"type":27,"tag":87,"props":3920,"children":3921},{"class":89,"line":235},[3922,3926,3930],{"type":27,"tag":87,"props":3923,"children":3924},{"style":2147},[3925],{"type":36,"value":3727},{"type":27,"tag":87,"props":3927,"children":3928},{"style":184},[3929],{"type":36,"value":907},{"type":27,"tag":87,"props":3931,"children":3932},{"style":100},[3933],{"type":36,"value":3934},"mvn deploy\n",{"type":27,"tag":32,"props":3936,"children":3937},{},[3938,3940,3945],{"type":36,"value":3939},"Ensure your ",{"type":27,"tag":15,"props":3941,"children":3943},{"className":3942},[],[3944],{"type":36,"value":3245},{"type":36,"value":3946}," is configured for deployment (e.g., GitHub Packages).",{"type":27,"tag":39,"props":3948,"children":3950},{"id":3949},"step-5-committing-and-running-your-workflow",[3951],{"type":36,"value":3952},"Step 5: Committing and Running Your Workflow",{"type":27,"tag":32,"props":3954,"children":3955},{},[3956],{"type":36,"value":3957},"Commit your workflow file and push the changes:",{"type":27,"tag":77,"props":3959,"children":3961},{"code":3960,"language":81,"meta":8,"className":79,"style":8},"git add .github/workflows/maven-ci.yml\ngit commit -m \"Add Maven CI GitHub Actions workflow\"\ngit push\n",[3962],{"type":27,"tag":15,"props":3963,"children":3964},{"__ignoreMap":8},[3965,3983,4005],{"type":27,"tag":87,"props":3966,"children":3967},{"class":89,"line":90},[3968,3973,3978],{"type":27,"tag":87,"props":3969,"children":3970},{"style":94},[3971],{"type":36,"value":3972},"git",{"type":27,"tag":87,"props":3974,"children":3975},{"style":100},[3976],{"type":36,"value":3977}," add",{"type":27,"tag":87,"props":3979,"children":3980},{"style":100},[3981],{"type":36,"value":3982}," .github/workflows/maven-ci.yml\n",{"type":27,"tag":87,"props":3984,"children":3985},{"class":89,"line":200},[3986,3990,3995,4000],{"type":27,"tag":87,"props":3987,"children":3988},{"style":94},[3989],{"type":36,"value":3972},{"type":27,"tag":87,"props":3991,"children":3992},{"style":100},[3993],{"type":36,"value":3994}," commit",{"type":27,"tag":87,"props":3996,"children":3997},{"style":288},[3998],{"type":36,"value":3999}," -m",{"type":27,"tag":87,"props":4001,"children":4002},{"style":100},[4003],{"type":36,"value":4004}," \"Add Maven CI GitHub Actions workflow\"\n",{"type":27,"tag":87,"props":4006,"children":4007},{"class":89,"line":222},[4008,4012],{"type":27,"tag":87,"props":4009,"children":4010},{"style":94},[4011],{"type":36,"value":3972},{"type":27,"tag":87,"props":4013,"children":4014},{"style":100},[4015],{"type":36,"value":4016}," push\n",{"type":27,"tag":32,"props":4018,"children":4019},{},[4020,4022,4027],{"type":36,"value":4021},"Navigate to the ",{"type":27,"tag":2410,"props":4023,"children":4024},{},[4025],{"type":36,"value":4026},"Actions",{"type":36,"value":4028}," tab on your GitHub repository to view and monitor your pipeline.",{"type":27,"tag":39,"props":4030,"children":4032},{"id":4031},"advantages-of-automating-java-builds",[4033],{"type":36,"value":4034},"Advantages of Automating Java Builds",{"type":27,"tag":46,"props":4036,"children":4037},{},[4038,4043,4048,4053],{"type":27,"tag":50,"props":4039,"children":4040},{},[4041],{"type":36,"value":4042},"Rapid feedback on code integration.",{"type":27,"tag":50,"props":4044,"children":4045},{},[4046],{"type":36,"value":4047},"Early identification of bugs and issues.",{"type":27,"tag":50,"props":4049,"children":4050},{},[4051],{"type":36,"value":4052},"Automated testing and deployment.",{"type":27,"tag":50,"props":4054,"children":4055},{},[4056],{"type":36,"value":4057},"Improved reliability and consistency.",{"type":27,"tag":39,"props":4059,"children":4061},{"id":4060},"pricing",[4062],{"type":36,"value":4063},"Pricing",{"type":27,"tag":32,"props":4065,"children":4066},{},[4067],{"type":36,"value":4068},"GitHub Actions offers a generous free tier suitable for most projects:",{"type":27,"tag":46,"props":4070,"children":4071},{},[4072,4098],{"type":27,"tag":50,"props":4073,"children":4074},{},[4075,4080],{"type":27,"tag":2410,"props":4076,"children":4077},{},[4078],{"type":36,"value":4079},"Free Tier:",{"type":27,"tag":46,"props":4081,"children":4082},{},[4083,4088,4093],{"type":27,"tag":50,"props":4084,"children":4085},{},[4086],{"type":36,"value":4087},"2,000 minutes per month (private repositories).",{"type":27,"tag":50,"props":4089,"children":4090},{},[4091],{"type":36,"value":4092},"Unlimited minutes for public repositories.",{"type":27,"tag":50,"props":4094,"children":4095},{},[4096],{"type":36,"value":4097},"Free usage of GitHub-hosted runners for most common tasks.",{"type":27,"tag":50,"props":4099,"children":4100},{},[4101,4106],{"type":27,"tag":2410,"props":4102,"children":4103},{},[4104],{"type":36,"value":4105},"Additional Minutes:",{"type":27,"tag":46,"props":4107,"children":4108},{},[4109,4114,4119],{"type":27,"tag":50,"props":4110,"children":4111},{},[4112],{"type":36,"value":4113},"$0.008 per minute for Linux runners.",{"type":27,"tag":50,"props":4115,"children":4116},{},[4117],{"type":36,"value":4118},"$0.016 per minute for Windows runners.",{"type":27,"tag":50,"props":4120,"children":4121},{},[4122],{"type":36,"value":4123},"$0.08 per minute for macOS runners.",{"type":27,"tag":32,"props":4125,"children":4126},{},[4127,4129,4136],{"type":36,"value":4128},"For detailed and up-to-date pricing, visit ",{"type":27,"tag":1410,"props":4130,"children":4133},{"href":4131,"rel":4132},"https://github.com/pricing#actions",[1414],[4134],{"type":36,"value":4135},"GitHub Actions Pricing",{"type":36,"value":3225},{"type":27,"tag":39,"props":4138,"children":4139},{"id":2304},[4140],{"type":36,"value":2307},{"type":27,"tag":32,"props":4142,"children":4143},{},[4144],{"type":36,"value":4145},"Using GitHub Actions with Maven provides an efficient and robust CI/CD pipeline, significantly improving your development lifecycle. Start implementing these practices today and streamline your Java application delivery.",{"type":27,"tag":1397,"props":4147,"children":4148},{"id":2315},[4149],{"type":36,"value":2318},{"type":27,"tag":46,"props":4151,"children":4152},{},[4153,4163,4173],{"type":27,"tag":50,"props":4154,"children":4155},{},[4156],{"type":27,"tag":1410,"props":4157,"children":4160},{"href":4158,"rel":4159},"https://docs.github.com/en/actions",[1414],[4161],{"type":36,"value":4162},"GitHub Actions Documentation",{"type":27,"tag":50,"props":4164,"children":4165},{},[4166],{"type":27,"tag":1410,"props":4167,"children":4170},{"href":4168,"rel":4169},"https://maven.apache.org/guides/",[1414],[4171],{"type":36,"value":4172},"Maven Official Documentation",{"type":27,"tag":50,"props":4174,"children":4175},{},[4176],{"type":27,"tag":1410,"props":4177,"children":4180},{"href":4178,"rel":4179},"https://docs.github.com/en/packages/working-with-a-github-packages-registry",[1414],[4181],{"type":36,"value":4182},"Publishing Java Packages with GitHub Packages",{"type":27,"tag":1439,"props":4184,"children":4185},{},[4186],{"type":36,"value":1443},{"title":8,"searchDepth":200,"depth":200,"links":4188},[4189,4190,4191,4192,4193,4194,4195,4196,4197],{"id":3228,"depth":200,"text":3231},{"id":3255,"depth":200,"text":3258},{"id":3618,"depth":200,"text":3621},{"id":3683,"depth":200,"text":3686},{"id":3854,"depth":200,"text":3857},{"id":3949,"depth":200,"text":3952},{"id":4031,"depth":200,"text":4034},{"id":4060,"depth":200,"text":4063},{"id":2304,"depth":200,"text":2307},"content:posts:maven-and-github-actions.md","posts/maven-and-github-actions.md","posts/maven-and-github-actions",{"_path":4202,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":4203,"description":4204,"date":4205,"layout":12,"subtitle":4206,"image":4207,"optimized_image":4207,"category":15,"tags":4208,"author":22,"paginate":7,"body":4212,"_type":1455,"_id":5049,"_source":1457,"_file":5050,"_stem":5051,"_extension":1460},"/posts/pattern-matching-sealed-classes-java21","A Guide to Pattern Matching and Sealed Classes in Java 21","A comprehensive introduction to pattern matching and sealed classes in Java 21, including practical examples and best practices.","2024-05-15T11:00:00.000Z","Writing Safer and More Expressive Java Code","/assets/img/uploads/java-pattern.matching.png",[15,1469,4209,4210,4211],"pattern-matching","sealed-classes","java21",{"type":24,"children":4213,"toc":5035},[4214,4235,4241,4254,4260,4368,4374,4540,4546,4564,4569,4574,4580,4762,4768,4948,4953,4971,4977,4995,4999,5004,5008,5031],{"type":27,"tag":28,"props":4215,"children":4216},{},[4217],{"type":27,"tag":32,"props":4218,"children":4219},{},[4220,4222,4227,4228,4233],{"type":36,"value":4221},"Java 21 introduces powerful enhancements that improve readability, safety, and expressiveness in your code. Among these, ",{"type":27,"tag":2410,"props":4223,"children":4224},{},[4225],{"type":36,"value":4226},"pattern matching",{"type":36,"value":3218},{"type":27,"tag":2410,"props":4229,"children":4230},{},[4231],{"type":36,"value":4232},"sealed classes",{"type":36,"value":4234}," stand out, allowing developers to write concise, readable, and safe code. Let's explore both concepts with practical examples.",{"type":27,"tag":39,"props":4236,"children":4238},{"id":4237},"pattern-matching-for-switch",[4239],{"type":36,"value":4240},"Pattern Matching for Switch",{"type":27,"tag":32,"props":4242,"children":4243},{},[4244,4246,4252],{"type":36,"value":4245},"Pattern matching extends the classic ",{"type":27,"tag":15,"props":4247,"children":4249},{"className":4248},[],[4250],{"type":36,"value":4251},"switch",{"type":36,"value":4253}," statement, making code simpler and clearer by reducing the need for explicit casting and type checking.",{"type":27,"tag":2478,"props":4255,"children":4257},{"id":4256},"traditional-switch",[4258],{"type":36,"value":4259},"Traditional Switch",{"type":27,"tag":77,"props":4261,"children":4263},{"className":1566,"code":4262,"language":1469,"meta":8,"style":8},"Object obj = \"Hello\";\n\nif (obj instanceof String) {\n    String s = (String) obj;\n    System.out.println(s.toLowerCase());\n}\n",[4264],{"type":27,"tag":15,"props":4265,"children":4266},{"__ignoreMap":8},[4267,4289,4296,4318,4335,4361],{"type":27,"tag":87,"props":4268,"children":4269},{"class":89,"line":90},[4270,4275,4279,4284],{"type":27,"tag":87,"props":4271,"children":4272},{"style":184},[4273],{"type":36,"value":4274},"Object obj ",{"type":27,"tag":87,"props":4276,"children":4277},{"style":178},[4278],{"type":36,"value":325},{"type":27,"tag":87,"props":4280,"children":4281},{"style":100},[4282],{"type":36,"value":4283}," \"Hello\"",{"type":27,"tag":87,"props":4285,"children":4286},{"style":184},[4287],{"type":36,"value":4288},";\n",{"type":27,"tag":87,"props":4290,"children":4291},{"class":89,"line":200},[4292],{"type":27,"tag":87,"props":4293,"children":4294},{"emptyLinePlaceholder":261},[4295],{"type":36,"value":264},{"type":27,"tag":87,"props":4297,"children":4298},{"class":89,"line":222},[4299,4303,4308,4313],{"type":27,"tag":87,"props":4300,"children":4301},{"style":178},[4302],{"type":36,"value":1773},{"type":27,"tag":87,"props":4304,"children":4305},{"style":184},[4306],{"type":36,"value":4307}," (obj ",{"type":27,"tag":87,"props":4309,"children":4310},{"style":178},[4311],{"type":36,"value":4312},"instanceof",{"type":27,"tag":87,"props":4314,"children":4315},{"style":184},[4316],{"type":36,"value":4317}," String) {\n",{"type":27,"tag":87,"props":4319,"children":4320},{"class":89,"line":235},[4321,4326,4330],{"type":27,"tag":87,"props":4322,"children":4323},{"style":184},[4324],{"type":36,"value":4325},"    String s ",{"type":27,"tag":87,"props":4327,"children":4328},{"style":178},[4329],{"type":36,"value":325},{"type":27,"tag":87,"props":4331,"children":4332},{"style":184},[4333],{"type":36,"value":4334}," (String) obj;\n",{"type":27,"tag":87,"props":4336,"children":4337},{"class":89,"line":257},[4338,4343,4347,4352,4357],{"type":27,"tag":87,"props":4339,"children":4340},{"style":184},[4341],{"type":36,"value":4342},"    System.out.",{"type":27,"tag":87,"props":4344,"children":4345},{"style":94},[4346],{"type":36,"value":2967},{"type":27,"tag":87,"props":4348,"children":4349},{"style":184},[4350],{"type":36,"value":4351},"(s.",{"type":27,"tag":87,"props":4353,"children":4354},{"style":94},[4355],{"type":36,"value":4356},"toLowerCase",{"type":27,"tag":87,"props":4358,"children":4359},{"style":184},[4360],{"type":36,"value":1765},{"type":27,"tag":87,"props":4362,"children":4363},{"class":89,"line":267},[4364],{"type":27,"tag":87,"props":4365,"children":4366},{"style":184},[4367],{"type":36,"value":1805},{"type":27,"tag":2478,"props":4369,"children":4371},{"id":4370},"pattern-matching-switch",[4372],{"type":36,"value":4373},"Pattern Matching Switch",{"type":27,"tag":77,"props":4375,"children":4377},{"className":1566,"code":4376,"language":1469,"meta":8,"style":8},"Object obj = \"Hello\";\n\nswitch (obj) {\n    case String s -> System.out.println(s.toLowerCase());\n    case Integer i -> System.out.println(i + 1);\n    default -> System.out.println(\"Unknown type\");\n}\n",[4378],{"type":27,"tag":15,"props":4379,"children":4380},{"__ignoreMap":8},[4381,4400,4407,4419,4456,4499,4533],{"type":27,"tag":87,"props":4382,"children":4383},{"class":89,"line":90},[4384,4388,4392,4396],{"type":27,"tag":87,"props":4385,"children":4386},{"style":184},[4387],{"type":36,"value":4274},{"type":27,"tag":87,"props":4389,"children":4390},{"style":178},[4391],{"type":36,"value":325},{"type":27,"tag":87,"props":4393,"children":4394},{"style":100},[4395],{"type":36,"value":4283},{"type":27,"tag":87,"props":4397,"children":4398},{"style":184},[4399],{"type":36,"value":4288},{"type":27,"tag":87,"props":4401,"children":4402},{"class":89,"line":200},[4403],{"type":27,"tag":87,"props":4404,"children":4405},{"emptyLinePlaceholder":261},[4406],{"type":36,"value":264},{"type":27,"tag":87,"props":4408,"children":4409},{"class":89,"line":222},[4410,4414],{"type":27,"tag":87,"props":4411,"children":4412},{"style":178},[4413],{"type":36,"value":4251},{"type":27,"tag":87,"props":4415,"children":4416},{"style":184},[4417],{"type":36,"value":4418}," (obj) {\n",{"type":27,"tag":87,"props":4420,"children":4421},{"class":89,"line":235},[4422,4427,4432,4436,4440,4444,4448,4452],{"type":27,"tag":87,"props":4423,"children":4424},{"style":178},[4425],{"type":36,"value":4426},"    case",{"type":27,"tag":87,"props":4428,"children":4429},{"style":184},[4430],{"type":36,"value":4431}," String s ",{"type":27,"tag":87,"props":4433,"children":4434},{"style":178},[4435],{"type":36,"value":2867},{"type":27,"tag":87,"props":4437,"children":4438},{"style":184},[4439],{"type":36,"value":2962},{"type":27,"tag":87,"props":4441,"children":4442},{"style":94},[4443],{"type":36,"value":2967},{"type":27,"tag":87,"props":4445,"children":4446},{"style":184},[4447],{"type":36,"value":4351},{"type":27,"tag":87,"props":4449,"children":4450},{"style":94},[4451],{"type":36,"value":4356},{"type":27,"tag":87,"props":4453,"children":4454},{"style":184},[4455],{"type":36,"value":1765},{"type":27,"tag":87,"props":4457,"children":4458},{"class":89,"line":257},[4459,4463,4468,4472,4476,4480,4485,4490,4495],{"type":27,"tag":87,"props":4460,"children":4461},{"style":178},[4462],{"type":36,"value":4426},{"type":27,"tag":87,"props":4464,"children":4465},{"style":184},[4466],{"type":36,"value":4467}," Integer i ",{"type":27,"tag":87,"props":4469,"children":4470},{"style":178},[4471],{"type":36,"value":2867},{"type":27,"tag":87,"props":4473,"children":4474},{"style":184},[4475],{"type":36,"value":2962},{"type":27,"tag":87,"props":4477,"children":4478},{"style":94},[4479],{"type":36,"value":2967},{"type":27,"tag":87,"props":4481,"children":4482},{"style":184},[4483],{"type":36,"value":4484},"(i ",{"type":27,"tag":87,"props":4486,"children":4487},{"style":178},[4488],{"type":36,"value":4489},"+",{"type":27,"tag":87,"props":4491,"children":4492},{"style":288},[4493],{"type":36,"value":4494}," 1",{"type":27,"tag":87,"props":4496,"children":4497},{"style":184},[4498],{"type":36,"value":1607},{"type":27,"tag":87,"props":4500,"children":4501},{"class":89,"line":267},[4502,4507,4512,4516,4520,4524,4529],{"type":27,"tag":87,"props":4503,"children":4504},{"style":178},[4505],{"type":36,"value":4506},"    default",{"type":27,"tag":87,"props":4508,"children":4509},{"style":178},[4510],{"type":36,"value":4511}," ->",{"type":27,"tag":87,"props":4513,"children":4514},{"style":184},[4515],{"type":36,"value":2962},{"type":27,"tag":87,"props":4517,"children":4518},{"style":94},[4519],{"type":36,"value":2967},{"type":27,"tag":87,"props":4521,"children":4522},{"style":184},[4523],{"type":36,"value":1282},{"type":27,"tag":87,"props":4525,"children":4526},{"style":100},[4527],{"type":36,"value":4528},"\"Unknown type\"",{"type":27,"tag":87,"props":4530,"children":4531},{"style":184},[4532],{"type":36,"value":1607},{"type":27,"tag":87,"props":4534,"children":4535},{"class":89,"line":276},[4536],{"type":27,"tag":87,"props":4537,"children":4538},{"style":184},[4539],{"type":36,"value":1805},{"type":27,"tag":2478,"props":4541,"children":4543},{"id":4542},"benefits",[4544],{"type":36,"value":4545},"Benefits:",{"type":27,"tag":46,"props":4547,"children":4548},{},[4549,4554,4559],{"type":27,"tag":50,"props":4550,"children":4551},{},[4552],{"type":36,"value":4553},"Reduced boilerplate code",{"type":27,"tag":50,"props":4555,"children":4556},{},[4557],{"type":36,"value":4558},"Enhanced readability",{"type":27,"tag":50,"props":4560,"children":4561},{},[4562],{"type":36,"value":4563},"Improved type safety",{"type":27,"tag":39,"props":4565,"children":4566},{"id":4210},[4567],{"type":36,"value":4568},"Sealed Classes",{"type":27,"tag":32,"props":4570,"children":4571},{},[4572],{"type":36,"value":4573},"Sealed classes allow you to define which subclasses or implementations are permitted. This helps in modeling clear and controlled domain hierarchies.",{"type":27,"tag":2478,"props":4575,"children":4577},{"id":4576},"declaring-a-sealed-class",[4578],{"type":36,"value":4579},"Declaring a Sealed Class",{"type":27,"tag":77,"props":4581,"children":4583},{"className":1566,"code":4582,"language":1469,"meta":8,"style":8},"public sealed abstract class Shape\n    permits Circle, Rectangle {}\n\npublic final class Circle extends Shape {\n    double radius;\n}\n\npublic final class Rectangle extends Shape {\n    double length, width;\n}\n",[4584],{"type":27,"tag":15,"props":4585,"children":4586},{"__ignoreMap":8},[4587,4615,4642,4649,4684,4697,4704,4711,4743,4755],{"type":27,"tag":87,"props":4588,"children":4589},{"class":89,"line":90},[4590,4595,4600,4605,4610],{"type":27,"tag":87,"props":4591,"children":4592},{"style":178},[4593],{"type":36,"value":4594},"public",{"type":27,"tag":87,"props":4596,"children":4597},{"style":178},[4598],{"type":36,"value":4599}," sealed",{"type":27,"tag":87,"props":4601,"children":4602},{"style":178},[4603],{"type":36,"value":4604}," abstract",{"type":27,"tag":87,"props":4606,"children":4607},{"style":178},[4608],{"type":36,"value":4609}," class",{"type":27,"tag":87,"props":4611,"children":4612},{"style":94},[4613],{"type":36,"value":4614}," Shape\n",{"type":27,"tag":87,"props":4616,"children":4617},{"class":89,"line":200},[4618,4623,4628,4632,4637],{"type":27,"tag":87,"props":4619,"children":4620},{"style":178},[4621],{"type":36,"value":4622},"    permits",{"type":27,"tag":87,"props":4624,"children":4625},{"style":94},[4626],{"type":36,"value":4627}," Circle",{"type":27,"tag":87,"props":4629,"children":4630},{"style":184},[4631],{"type":36,"value":917},{"type":27,"tag":87,"props":4633,"children":4634},{"style":94},[4635],{"type":36,"value":4636},"Rectangle",{"type":27,"tag":87,"props":4638,"children":4639},{"style":184},[4640],{"type":36,"value":4641}," {}\n",{"type":27,"tag":87,"props":4643,"children":4644},{"class":89,"line":222},[4645],{"type":27,"tag":87,"props":4646,"children":4647},{"emptyLinePlaceholder":261},[4648],{"type":36,"value":264},{"type":27,"tag":87,"props":4650,"children":4651},{"class":89,"line":235},[4652,4656,4661,4665,4669,4674,4679],{"type":27,"tag":87,"props":4653,"children":4654},{"style":178},[4655],{"type":36,"value":4594},{"type":27,"tag":87,"props":4657,"children":4658},{"style":178},[4659],{"type":36,"value":4660}," final",{"type":27,"tag":87,"props":4662,"children":4663},{"style":178},[4664],{"type":36,"value":4609},{"type":27,"tag":87,"props":4666,"children":4667},{"style":94},[4668],{"type":36,"value":4627},{"type":27,"tag":87,"props":4670,"children":4671},{"style":178},[4672],{"type":36,"value":4673}," extends",{"type":27,"tag":87,"props":4675,"children":4676},{"style":94},[4677],{"type":36,"value":4678}," Shape",{"type":27,"tag":87,"props":4680,"children":4681},{"style":184},[4682],{"type":36,"value":4683}," {\n",{"type":27,"tag":87,"props":4685,"children":4686},{"class":89,"line":257},[4687,4692],{"type":27,"tag":87,"props":4688,"children":4689},{"style":178},[4690],{"type":36,"value":4691},"    double",{"type":27,"tag":87,"props":4693,"children":4694},{"style":184},[4695],{"type":36,"value":4696}," radius;\n",{"type":27,"tag":87,"props":4698,"children":4699},{"class":89,"line":267},[4700],{"type":27,"tag":87,"props":4701,"children":4702},{"style":184},[4703],{"type":36,"value":1805},{"type":27,"tag":87,"props":4705,"children":4706},{"class":89,"line":276},[4707],{"type":27,"tag":87,"props":4708,"children":4709},{"emptyLinePlaceholder":261},[4710],{"type":36,"value":264},{"type":27,"tag":87,"props":4712,"children":4713},{"class":89,"line":284},[4714,4718,4722,4726,4731,4735,4739],{"type":27,"tag":87,"props":4715,"children":4716},{"style":178},[4717],{"type":36,"value":4594},{"type":27,"tag":87,"props":4719,"children":4720},{"style":178},[4721],{"type":36,"value":4660},{"type":27,"tag":87,"props":4723,"children":4724},{"style":178},[4725],{"type":36,"value":4609},{"type":27,"tag":87,"props":4727,"children":4728},{"style":94},[4729],{"type":36,"value":4730}," Rectangle",{"type":27,"tag":87,"props":4732,"children":4733},{"style":178},[4734],{"type":36,"value":4673},{"type":27,"tag":87,"props":4736,"children":4737},{"style":94},[4738],{"type":36,"value":4678},{"type":27,"tag":87,"props":4740,"children":4741},{"style":184},[4742],{"type":36,"value":4683},{"type":27,"tag":87,"props":4744,"children":4745},{"class":89,"line":314},[4746,4750],{"type":27,"tag":87,"props":4747,"children":4748},{"style":178},[4749],{"type":36,"value":4691},{"type":27,"tag":87,"props":4751,"children":4752},{"style":184},[4753],{"type":36,"value":4754}," length, width;\n",{"type":27,"tag":87,"props":4756,"children":4757},{"class":89,"line":341},[4758],{"type":27,"tag":87,"props":4759,"children":4760},{"style":184},[4761],{"type":36,"value":1805},{"type":27,"tag":2478,"props":4763,"children":4765},{"id":4764},"using-pattern-matching-with-sealed-classes",[4766],{"type":36,"value":4767},"Using Pattern Matching with Sealed Classes",{"type":27,"tag":77,"props":4769,"children":4771},{"className":1566,"code":4770,"language":1469,"meta":8,"style":8},"Shape shape = new Circle();\n\ndouble area = switch (shape) {\n    case Circle c -> Math.PI * c.radius * c.radius;\n    case Rectangle r -> r.length * r.width;\n};\n\nSystem.out.println(\"Area: \" + area);\n",[4772],{"type":27,"tag":15,"props":4773,"children":4774},{"__ignoreMap":8},[4775,4799,4806,4833,4873,4903,4911,4918],{"type":27,"tag":87,"props":4776,"children":4777},{"class":89,"line":90},[4778,4783,4787,4791,4795],{"type":27,"tag":87,"props":4779,"children":4780},{"style":184},[4781],{"type":36,"value":4782},"Shape shape ",{"type":27,"tag":87,"props":4784,"children":4785},{"style":178},[4786],{"type":36,"value":325},{"type":27,"tag":87,"props":4788,"children":4789},{"style":178},[4790],{"type":36,"value":2052},{"type":27,"tag":87,"props":4792,"children":4793},{"style":94},[4794],{"type":36,"value":4627},{"type":27,"tag":87,"props":4796,"children":4797},{"style":184},[4798],{"type":36,"value":1686},{"type":27,"tag":87,"props":4800,"children":4801},{"class":89,"line":200},[4802],{"type":27,"tag":87,"props":4803,"children":4804},{"emptyLinePlaceholder":261},[4805],{"type":36,"value":264},{"type":27,"tag":87,"props":4807,"children":4808},{"class":89,"line":222},[4809,4814,4819,4823,4828],{"type":27,"tag":87,"props":4810,"children":4811},{"style":178},[4812],{"type":36,"value":4813},"double",{"type":27,"tag":87,"props":4815,"children":4816},{"style":184},[4817],{"type":36,"value":4818}," area ",{"type":27,"tag":87,"props":4820,"children":4821},{"style":178},[4822],{"type":36,"value":325},{"type":27,"tag":87,"props":4824,"children":4825},{"style":178},[4826],{"type":36,"value":4827}," switch",{"type":27,"tag":87,"props":4829,"children":4830},{"style":184},[4831],{"type":36,"value":4832}," (shape) {\n",{"type":27,"tag":87,"props":4834,"children":4835},{"class":89,"line":235},[4836,4840,4845,4849,4854,4859,4864,4868],{"type":27,"tag":87,"props":4837,"children":4838},{"style":178},[4839],{"type":36,"value":4426},{"type":27,"tag":87,"props":4841,"children":4842},{"style":184},[4843],{"type":36,"value":4844}," Circle c ",{"type":27,"tag":87,"props":4846,"children":4847},{"style":178},[4848],{"type":36,"value":2867},{"type":27,"tag":87,"props":4850,"children":4851},{"style":184},[4852],{"type":36,"value":4853}," Math.PI ",{"type":27,"tag":87,"props":4855,"children":4856},{"style":178},[4857],{"type":36,"value":4858},"*",{"type":27,"tag":87,"props":4860,"children":4861},{"style":184},[4862],{"type":36,"value":4863}," c.radius ",{"type":27,"tag":87,"props":4865,"children":4866},{"style":178},[4867],{"type":36,"value":4858},{"type":27,"tag":87,"props":4869,"children":4870},{"style":184},[4871],{"type":36,"value":4872}," c.radius;\n",{"type":27,"tag":87,"props":4874,"children":4875},{"class":89,"line":257},[4876,4880,4885,4889,4894,4898],{"type":27,"tag":87,"props":4877,"children":4878},{"style":178},[4879],{"type":36,"value":4426},{"type":27,"tag":87,"props":4881,"children":4882},{"style":184},[4883],{"type":36,"value":4884}," Rectangle r ",{"type":27,"tag":87,"props":4886,"children":4887},{"style":178},[4888],{"type":36,"value":2867},{"type":27,"tag":87,"props":4890,"children":4891},{"style":184},[4892],{"type":36,"value":4893}," r.length ",{"type":27,"tag":87,"props":4895,"children":4896},{"style":178},[4897],{"type":36,"value":4858},{"type":27,"tag":87,"props":4899,"children":4900},{"style":184},[4901],{"type":36,"value":4902}," r.width;\n",{"type":27,"tag":87,"props":4904,"children":4905},{"class":89,"line":267},[4906],{"type":27,"tag":87,"props":4907,"children":4908},{"style":184},[4909],{"type":36,"value":4910},"};\n",{"type":27,"tag":87,"props":4912,"children":4913},{"class":89,"line":276},[4914],{"type":27,"tag":87,"props":4915,"children":4916},{"emptyLinePlaceholder":261},[4917],{"type":36,"value":264},{"type":27,"tag":87,"props":4919,"children":4920},{"class":89,"line":284},[4921,4926,4930,4934,4939,4943],{"type":27,"tag":87,"props":4922,"children":4923},{"style":184},[4924],{"type":36,"value":4925},"System.out.",{"type":27,"tag":87,"props":4927,"children":4928},{"style":94},[4929],{"type":36,"value":2967},{"type":27,"tag":87,"props":4931,"children":4932},{"style":184},[4933],{"type":36,"value":1282},{"type":27,"tag":87,"props":4935,"children":4936},{"style":100},[4937],{"type":36,"value":4938},"\"Area: \"",{"type":27,"tag":87,"props":4940,"children":4941},{"style":178},[4942],{"type":36,"value":2981},{"type":27,"tag":87,"props":4944,"children":4945},{"style":184},[4946],{"type":36,"value":4947}," area);\n",{"type":27,"tag":2478,"props":4949,"children":4951},{"id":4950},"benefits-1",[4952],{"type":36,"value":4545},{"type":27,"tag":46,"props":4954,"children":4955},{},[4956,4961,4966],{"type":27,"tag":50,"props":4957,"children":4958},{},[4959],{"type":36,"value":4960},"Enhanced clarity of inheritance hierarchies",{"type":27,"tag":50,"props":4962,"children":4963},{},[4964],{"type":36,"value":4965},"Compile-time enforcement of permitted subclasses",{"type":27,"tag":50,"props":4967,"children":4968},{},[4969],{"type":36,"value":4970},"Simplified, safer code when used with pattern matching",{"type":27,"tag":39,"props":4972,"children":4974},{"id":4973},"practical-applications",[4975],{"type":36,"value":4976},"Practical Applications",{"type":27,"tag":46,"props":4978,"children":4979},{},[4980,4985,4990],{"type":27,"tag":50,"props":4981,"children":4982},{},[4983],{"type":36,"value":4984},"Domain modeling with restricted class hierarchies",{"type":27,"tag":50,"props":4986,"children":4987},{},[4988],{"type":36,"value":4989},"Type-safe parsing and processing of structured data",{"type":27,"tag":50,"props":4991,"children":4992},{},[4993],{"type":36,"value":4994},"Cleaner implementations of polymorphic behavior",{"type":27,"tag":39,"props":4996,"children":4997},{"id":2304},[4998],{"type":36,"value":2307},{"type":27,"tag":32,"props":5000,"children":5001},{},[5002],{"type":36,"value":5003},"Pattern matching and sealed classes provide significant improvements in Java 21, helping you write cleaner, safer, and more maintainable code. Mastering these tools allows developers to leverage the full expressive power of modern Java.",{"type":27,"tag":1397,"props":5005,"children":5006},{"id":2315},[5007],{"type":36,"value":2318},{"type":27,"tag":46,"props":5009,"children":5010},{},[5011,5021],{"type":27,"tag":50,"props":5012,"children":5013},{},[5014],{"type":27,"tag":1410,"props":5015,"children":5018},{"href":5016,"rel":5017},"https://openjdk.org/jeps/441",[1414],[5019],{"type":36,"value":5020},"Java 21 Pattern Matching JEP",{"type":27,"tag":50,"props":5022,"children":5023},{},[5024],{"type":27,"tag":1410,"props":5025,"children":5028},{"href":5026,"rel":5027},"https://openjdk.org/jeps/409",[1414],[5029],{"type":36,"value":5030},"Java 21 Sealed Classes JEP",{"type":27,"tag":1439,"props":5032,"children":5033},{},[5034],{"type":36,"value":1443},{"title":8,"searchDepth":200,"depth":200,"links":5036},[5037,5042,5047,5048],{"id":4237,"depth":200,"text":4240,"children":5038},[5039,5040,5041],{"id":4256,"depth":222,"text":4259},{"id":4370,"depth":222,"text":4373},{"id":4542,"depth":222,"text":4545},{"id":4210,"depth":200,"text":4568,"children":5043},[5044,5045,5046],{"id":4576,"depth":222,"text":4579},{"id":4764,"depth":222,"text":4767},{"id":4950,"depth":222,"text":4545},{"id":4973,"depth":200,"text":4976},{"id":2304,"depth":200,"text":2307},"content:posts:pattern-matching-sealed-classes-java21.md","posts/pattern-matching-sealed-classes-java21.md","posts/pattern-matching-sealed-classes-java21",{"_path":5053,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":5054,"description":5055,"date":5056,"layout":12,"subtitle":5057,"image":5058,"optimized_image":5058,"category":15,"tags":5059,"author":22,"paginate":7,"body":5063,"_type":1455,"_id":6833,"_source":1457,"_file":6834,"_stem":6835,"_extension":1460},"/posts/async-java-completable-vs-reactive","Asynchronous Programming in Java: CompletableFuture vs Reactive Streams","A deep dive into asynchronous programming in Java comparing CompletableFuture and Reactive Streams, with examples and output.","2024-04-15T11:00:00.000Z","Choosing the Right Tool for Concurrency in Modern Java","/assets/img/uploads/java-async.png",[15,1469,5060,5061,5062],"asynchronous","reactive","concurrency",{"type":24,"children":5064,"toc":6819},[5065,5087,5093,5103,5109,5458,5466,5474,5480,5762,5769,5777,5783,5791,5809,5817,5835,5839,5845,5878,5884,6185,6192,6200,6206,6538,6545,6553,6559,6566,6584,6591,6609,6612,6618,6747,6750,6754,6773,6778,6782,6815],{"type":27,"tag":28,"props":5066,"children":5067},{},[5068],{"type":27,"tag":32,"props":5069,"children":5070},{},[5071,5073,5079,5080,5085],{"type":36,"value":5072},"Asynchronous programming enables applications to execute non-blocking operations, crucial for performance in modern, concurrent systems. In Java, two powerful tools are commonly used: ",{"type":27,"tag":15,"props":5074,"children":5076},{"className":5075},[],[5077],{"type":36,"value":5078},"CompletableFuture",{"type":36,"value":3218},{"type":27,"tag":2410,"props":5081,"children":5082},{},[5083],{"type":36,"value":5084},"Reactive Streams",{"type":36,"value":5086}," (e.g., Project Reactor or RxJava). In this post, we’ll compare both approaches through real code examples and output results.",{"type":27,"tag":39,"props":5088,"children":5090},{"id":5089},"_1-completablefuture-javas-built-in-promise-api",[5091],{"type":36,"value":5092},"1. CompletableFuture: Java’s Built-in Promise API",{"type":27,"tag":32,"props":5094,"children":5095},{},[5096,5101],{"type":27,"tag":15,"props":5097,"children":5099},{"className":5098},[],[5100],{"type":36,"value":5078},{"type":36,"value":5102}," is a class introduced in Java 8 to write asynchronous, non-blocking code. It's suitable for simple async flows and integrates well with imperative codebases.",{"type":27,"tag":2478,"props":5104,"children":5106},{"id":5105},"example-1-basic-async-execution",[5107],{"type":36,"value":5108},"Example 1: Basic Async Execution",{"type":27,"tag":77,"props":5110,"children":5112},{"code":5111,"language":1469,"meta":8,"className":1566,"style":8},"import java.util.concurrent.CompletableFuture;\n\npublic class CompletableFutureDemo {\n    public static void main(String[] args) {\n        CompletableFuture\u003CString> future = CompletableFuture.supplyAsync(() -> {\n            sleep(1000);\n            return \"Hello from CompletableFuture!\";\n        });\n\n        future.thenAccept(System.out::println);\n        sleep(1500); // wait for completion\n    }\n\n    static void sleep(long millis) {\n        try { Thread.sleep(millis); } catch (InterruptedException e) { }\n    }\n}\n",[5113],{"type":27,"tag":15,"props":5114,"children":5115},{"__ignoreMap":8},[5116,5128,5135,5155,5201,5245,5265,5282,5290,5297,5325,5352,5360,5367,5402,5444,5451],{"type":27,"tag":87,"props":5117,"children":5118},{"class":89,"line":90},[5119,5123],{"type":27,"tag":87,"props":5120,"children":5121},{"style":178},[5122],{"type":36,"value":192},{"type":27,"tag":87,"props":5124,"children":5125},{"style":184},[5126],{"type":36,"value":5127}," java.util.concurrent.CompletableFuture;\n",{"type":27,"tag":87,"props":5129,"children":5130},{"class":89,"line":200},[5131],{"type":27,"tag":87,"props":5132,"children":5133},{"emptyLinePlaceholder":261},[5134],{"type":36,"value":264},{"type":27,"tag":87,"props":5136,"children":5137},{"class":89,"line":222},[5138,5142,5146,5151],{"type":27,"tag":87,"props":5139,"children":5140},{"style":178},[5141],{"type":36,"value":4594},{"type":27,"tag":87,"props":5143,"children":5144},{"style":178},[5145],{"type":36,"value":4609},{"type":27,"tag":87,"props":5147,"children":5148},{"style":94},[5149],{"type":36,"value":5150}," CompletableFutureDemo",{"type":27,"tag":87,"props":5152,"children":5153},{"style":184},[5154],{"type":36,"value":4683},{"type":27,"tag":87,"props":5156,"children":5157},{"class":89,"line":235},[5158,5163,5168,5173,5178,5182,5186,5191,5196],{"type":27,"tag":87,"props":5159,"children":5160},{"style":178},[5161],{"type":36,"value":5162},"    public",{"type":27,"tag":87,"props":5164,"children":5165},{"style":178},[5166],{"type":36,"value":5167}," static",{"type":27,"tag":87,"props":5169,"children":5170},{"style":178},[5171],{"type":36,"value":5172}," void",{"type":27,"tag":87,"props":5174,"children":5175},{"style":94},[5176],{"type":36,"value":5177}," main",{"type":27,"tag":87,"props":5179,"children":5180},{"style":184},[5181],{"type":36,"value":1282},{"type":27,"tag":87,"props":5183,"children":5184},{"style":178},[5185],{"type":36,"value":2839},{"type":27,"tag":87,"props":5187,"children":5188},{"style":184},[5189],{"type":36,"value":5190},"[] ",{"type":27,"tag":87,"props":5192,"children":5193},{"style":359},[5194],{"type":36,"value":5195},"args",{"type":27,"tag":87,"props":5197,"children":5198},{"style":184},[5199],{"type":36,"value":5200},") {\n",{"type":27,"tag":87,"props":5202,"children":5203},{"class":89,"line":257},[5204,5209,5213,5218,5222,5227,5232,5237,5241],{"type":27,"tag":87,"props":5205,"children":5206},{"style":184},[5207],{"type":36,"value":5208},"        CompletableFuture\u003C",{"type":27,"tag":87,"props":5210,"children":5211},{"style":178},[5212],{"type":36,"value":2839},{"type":27,"tag":87,"props":5214,"children":5215},{"style":184},[5216],{"type":36,"value":5217},"> future ",{"type":27,"tag":87,"props":5219,"children":5220},{"style":178},[5221],{"type":36,"value":325},{"type":27,"tag":87,"props":5223,"children":5224},{"style":184},[5225],{"type":36,"value":5226}," CompletableFuture.",{"type":27,"tag":87,"props":5228,"children":5229},{"style":94},[5230],{"type":36,"value":5231},"supplyAsync",{"type":27,"tag":87,"props":5233,"children":5234},{"style":184},[5235],{"type":36,"value":5236},"(() ",{"type":27,"tag":87,"props":5238,"children":5239},{"style":178},[5240],{"type":36,"value":2867},{"type":27,"tag":87,"props":5242,"children":5243},{"style":184},[5244],{"type":36,"value":4683},{"type":27,"tag":87,"props":5246,"children":5247},{"class":89,"line":267},[5248,5253,5257,5261],{"type":27,"tag":87,"props":5249,"children":5250},{"style":94},[5251],{"type":36,"value":5252},"            sleep",{"type":27,"tag":87,"props":5254,"children":5255},{"style":184},[5256],{"type":36,"value":1282},{"type":27,"tag":87,"props":5258,"children":5259},{"style":288},[5260],{"type":36,"value":2695},{"type":27,"tag":87,"props":5262,"children":5263},{"style":184},[5264],{"type":36,"value":1607},{"type":27,"tag":87,"props":5266,"children":5267},{"class":89,"line":276},[5268,5273,5278],{"type":27,"tag":87,"props":5269,"children":5270},{"style":178},[5271],{"type":36,"value":5272},"            return",{"type":27,"tag":87,"props":5274,"children":5275},{"style":100},[5276],{"type":36,"value":5277}," \"Hello from CompletableFuture!\"",{"type":27,"tag":87,"props":5279,"children":5280},{"style":184},[5281],{"type":36,"value":4288},{"type":27,"tag":87,"props":5283,"children":5284},{"class":89,"line":284},[5285],{"type":27,"tag":87,"props":5286,"children":5287},{"style":184},[5288],{"type":36,"value":5289},"        });\n",{"type":27,"tag":87,"props":5291,"children":5292},{"class":89,"line":314},[5293],{"type":27,"tag":87,"props":5294,"children":5295},{"emptyLinePlaceholder":261},[5296],{"type":36,"value":264},{"type":27,"tag":87,"props":5298,"children":5299},{"class":89,"line":341},[5300,5305,5310,5315,5320],{"type":27,"tag":87,"props":5301,"children":5302},{"style":184},[5303],{"type":36,"value":5304},"        future.",{"type":27,"tag":87,"props":5306,"children":5307},{"style":94},[5308],{"type":36,"value":5309},"thenAccept",{"type":27,"tag":87,"props":5311,"children":5312},{"style":184},[5313],{"type":36,"value":5314},"(System.out",{"type":27,"tag":87,"props":5316,"children":5317},{"style":178},[5318],{"type":36,"value":5319},"::",{"type":27,"tag":87,"props":5321,"children":5322},{"style":184},[5323],{"type":36,"value":5324},"println);\n",{"type":27,"tag":87,"props":5326,"children":5327},{"class":89,"line":374},[5328,5333,5337,5342,5347],{"type":27,"tag":87,"props":5329,"children":5330},{"style":94},[5331],{"type":36,"value":5332},"        sleep",{"type":27,"tag":87,"props":5334,"children":5335},{"style":184},[5336],{"type":36,"value":1282},{"type":27,"tag":87,"props":5338,"children":5339},{"style":288},[5340],{"type":36,"value":5341},"1500",{"type":27,"tag":87,"props":5343,"children":5344},{"style":184},[5345],{"type":36,"value":5346},"); ",{"type":27,"tag":87,"props":5348,"children":5349},{"style":1794},[5350],{"type":36,"value":5351},"// wait for completion\n",{"type":27,"tag":87,"props":5353,"children":5354},{"class":89,"line":699},[5355],{"type":27,"tag":87,"props":5356,"children":5357},{"style":184},[5358],{"type":36,"value":5359},"    }\n",{"type":27,"tag":87,"props":5361,"children":5362},{"class":89,"line":707},[5363],{"type":27,"tag":87,"props":5364,"children":5365},{"emptyLinePlaceholder":261},[5366],{"type":36,"value":264},{"type":27,"tag":87,"props":5368,"children":5369},{"class":89,"line":725},[5370,5375,5379,5384,5388,5393,5398],{"type":27,"tag":87,"props":5371,"children":5372},{"style":178},[5373],{"type":36,"value":5374},"    static",{"type":27,"tag":87,"props":5376,"children":5377},{"style":178},[5378],{"type":36,"value":5172},{"type":27,"tag":87,"props":5380,"children":5381},{"style":94},[5382],{"type":36,"value":5383}," sleep",{"type":27,"tag":87,"props":5385,"children":5386},{"style":184},[5387],{"type":36,"value":1282},{"type":27,"tag":87,"props":5389,"children":5390},{"style":178},[5391],{"type":36,"value":5392},"long",{"type":27,"tag":87,"props":5394,"children":5395},{"style":359},[5396],{"type":36,"value":5397}," millis",{"type":27,"tag":87,"props":5399,"children":5400},{"style":184},[5401],{"type":36,"value":5200},{"type":27,"tag":87,"props":5403,"children":5404},{"class":89,"line":1039},[5405,5410,5415,5420,5425,5430,5435,5439],{"type":27,"tag":87,"props":5406,"children":5407},{"style":178},[5408],{"type":36,"value":5409},"        try",{"type":27,"tag":87,"props":5411,"children":5412},{"style":184},[5413],{"type":36,"value":5414}," { Thread.",{"type":27,"tag":87,"props":5416,"children":5417},{"style":94},[5418],{"type":36,"value":5419},"sleep",{"type":27,"tag":87,"props":5421,"children":5422},{"style":184},[5423],{"type":36,"value":5424},"(millis); } ",{"type":27,"tag":87,"props":5426,"children":5427},{"style":178},[5428],{"type":36,"value":5429},"catch",{"type":27,"tag":87,"props":5431,"children":5432},{"style":184},[5433],{"type":36,"value":5434}," (InterruptedException ",{"type":27,"tag":87,"props":5436,"children":5437},{"style":359},[5438],{"type":36,"value":1300},{"type":27,"tag":87,"props":5440,"children":5441},{"style":184},[5442],{"type":36,"value":5443},") { }\n",{"type":27,"tag":87,"props":5445,"children":5446},{"class":89,"line":1052},[5447],{"type":27,"tag":87,"props":5448,"children":5449},{"style":184},[5450],{"type":36,"value":5359},{"type":27,"tag":87,"props":5452,"children":5453},{"class":89,"line":1060},[5454],{"type":27,"tag":87,"props":5455,"children":5456},{"style":184},[5457],{"type":36,"value":1805},{"type":27,"tag":32,"props":5459,"children":5460},{},[5461],{"type":27,"tag":2410,"props":5462,"children":5463},{},[5464],{"type":36,"value":5465},"Output:",{"type":27,"tag":77,"props":5467,"children":5469},{"code":5468},"Hello from CompletableFuture!\n",[5470],{"type":27,"tag":15,"props":5471,"children":5472},{"__ignoreMap":8},[5473],{"type":36,"value":5468},{"type":27,"tag":2478,"props":5475,"children":5477},{"id":5476},"example-2-chaining-and-combining",[5478],{"type":36,"value":5479},"Example 2: Chaining and Combining",{"type":27,"tag":77,"props":5481,"children":5483},{"code":5482,"language":1469,"meta":8,"className":1566,"style":8},"import java.util.concurrent.CompletableFuture;\n\npublic class CompletableFutureCombineDemo {\n    public static void main(String[] args) {\n        CompletableFuture\u003CString> greeting = CompletableFuture.supplyAsync(() -> \"Hello\");\n        CompletableFuture\u003CString> name = CompletableFuture.supplyAsync(() -> \"World\");\n\n        CompletableFuture\u003CString> result = greeting.thenCombine(name, (g, n) -> g + \", \" + n);\n        System.out.println(result.join());\n    }\n}\n",[5484],{"type":27,"tag":15,"props":5485,"children":5486},{"__ignoreMap":8},[5487,5498,5505,5525,5564,5608,5653,5660,5722,5748,5755],{"type":27,"tag":87,"props":5488,"children":5489},{"class":89,"line":90},[5490,5494],{"type":27,"tag":87,"props":5491,"children":5492},{"style":178},[5493],{"type":36,"value":192},{"type":27,"tag":87,"props":5495,"children":5496},{"style":184},[5497],{"type":36,"value":5127},{"type":27,"tag":87,"props":5499,"children":5500},{"class":89,"line":200},[5501],{"type":27,"tag":87,"props":5502,"children":5503},{"emptyLinePlaceholder":261},[5504],{"type":36,"value":264},{"type":27,"tag":87,"props":5506,"children":5507},{"class":89,"line":222},[5508,5512,5516,5521],{"type":27,"tag":87,"props":5509,"children":5510},{"style":178},[5511],{"type":36,"value":4594},{"type":27,"tag":87,"props":5513,"children":5514},{"style":178},[5515],{"type":36,"value":4609},{"type":27,"tag":87,"props":5517,"children":5518},{"style":94},[5519],{"type":36,"value":5520}," CompletableFutureCombineDemo",{"type":27,"tag":87,"props":5522,"children":5523},{"style":184},[5524],{"type":36,"value":4683},{"type":27,"tag":87,"props":5526,"children":5527},{"class":89,"line":235},[5528,5532,5536,5540,5544,5548,5552,5556,5560],{"type":27,"tag":87,"props":5529,"children":5530},{"style":178},[5531],{"type":36,"value":5162},{"type":27,"tag":87,"props":5533,"children":5534},{"style":178},[5535],{"type":36,"value":5167},{"type":27,"tag":87,"props":5537,"children":5538},{"style":178},[5539],{"type":36,"value":5172},{"type":27,"tag":87,"props":5541,"children":5542},{"style":94},[5543],{"type":36,"value":5177},{"type":27,"tag":87,"props":5545,"children":5546},{"style":184},[5547],{"type":36,"value":1282},{"type":27,"tag":87,"props":5549,"children":5550},{"style":178},[5551],{"type":36,"value":2839},{"type":27,"tag":87,"props":5553,"children":5554},{"style":184},[5555],{"type":36,"value":5190},{"type":27,"tag":87,"props":5557,"children":5558},{"style":359},[5559],{"type":36,"value":5195},{"type":27,"tag":87,"props":5561,"children":5562},{"style":184},[5563],{"type":36,"value":5200},{"type":27,"tag":87,"props":5565,"children":5566},{"class":89,"line":257},[5567,5571,5575,5580,5584,5588,5592,5596,5600,5604],{"type":27,"tag":87,"props":5568,"children":5569},{"style":184},[5570],{"type":36,"value":5208},{"type":27,"tag":87,"props":5572,"children":5573},{"style":178},[5574],{"type":36,"value":2839},{"type":27,"tag":87,"props":5576,"children":5577},{"style":184},[5578],{"type":36,"value":5579},"> greeting ",{"type":27,"tag":87,"props":5581,"children":5582},{"style":178},[5583],{"type":36,"value":325},{"type":27,"tag":87,"props":5585,"children":5586},{"style":184},[5587],{"type":36,"value":5226},{"type":27,"tag":87,"props":5589,"children":5590},{"style":94},[5591],{"type":36,"value":5231},{"type":27,"tag":87,"props":5593,"children":5594},{"style":184},[5595],{"type":36,"value":5236},{"type":27,"tag":87,"props":5597,"children":5598},{"style":178},[5599],{"type":36,"value":2867},{"type":27,"tag":87,"props":5601,"children":5602},{"style":100},[5603],{"type":36,"value":4283},{"type":27,"tag":87,"props":5605,"children":5606},{"style":184},[5607],{"type":36,"value":1607},{"type":27,"tag":87,"props":5609,"children":5610},{"class":89,"line":267},[5611,5615,5619,5624,5628,5632,5636,5640,5644,5649],{"type":27,"tag":87,"props":5612,"children":5613},{"style":184},[5614],{"type":36,"value":5208},{"type":27,"tag":87,"props":5616,"children":5617},{"style":178},[5618],{"type":36,"value":2839},{"type":27,"tag":87,"props":5620,"children":5621},{"style":184},[5622],{"type":36,"value":5623},"> name ",{"type":27,"tag":87,"props":5625,"children":5626},{"style":178},[5627],{"type":36,"value":325},{"type":27,"tag":87,"props":5629,"children":5630},{"style":184},[5631],{"type":36,"value":5226},{"type":27,"tag":87,"props":5633,"children":5634},{"style":94},[5635],{"type":36,"value":5231},{"type":27,"tag":87,"props":5637,"children":5638},{"style":184},[5639],{"type":36,"value":5236},{"type":27,"tag":87,"props":5641,"children":5642},{"style":178},[5643],{"type":36,"value":2867},{"type":27,"tag":87,"props":5645,"children":5646},{"style":100},[5647],{"type":36,"value":5648}," \"World\"",{"type":27,"tag":87,"props":5650,"children":5651},{"style":184},[5652],{"type":36,"value":1607},{"type":27,"tag":87,"props":5654,"children":5655},{"class":89,"line":276},[5656],{"type":27,"tag":87,"props":5657,"children":5658},{"emptyLinePlaceholder":261},[5659],{"type":36,"value":264},{"type":27,"tag":87,"props":5661,"children":5662},{"class":89,"line":284},[5663,5667,5671,5676,5680,5685,5690,5695,5699,5704,5708,5713,5717],{"type":27,"tag":87,"props":5664,"children":5665},{"style":184},[5666],{"type":36,"value":5208},{"type":27,"tag":87,"props":5668,"children":5669},{"style":178},[5670],{"type":36,"value":2839},{"type":27,"tag":87,"props":5672,"children":5673},{"style":184},[5674],{"type":36,"value":5675},"> result ",{"type":27,"tag":87,"props":5677,"children":5678},{"style":178},[5679],{"type":36,"value":325},{"type":27,"tag":87,"props":5681,"children":5682},{"style":184},[5683],{"type":36,"value":5684}," greeting.",{"type":27,"tag":87,"props":5686,"children":5687},{"style":94},[5688],{"type":36,"value":5689},"thenCombine",{"type":27,"tag":87,"props":5691,"children":5692},{"style":184},[5693],{"type":36,"value":5694},"(name, (g, n) ",{"type":27,"tag":87,"props":5696,"children":5697},{"style":178},[5698],{"type":36,"value":2867},{"type":27,"tag":87,"props":5700,"children":5701},{"style":184},[5702],{"type":36,"value":5703}," g ",{"type":27,"tag":87,"props":5705,"children":5706},{"style":178},[5707],{"type":36,"value":4489},{"type":27,"tag":87,"props":5709,"children":5710},{"style":100},[5711],{"type":36,"value":5712}," \", \"",{"type":27,"tag":87,"props":5714,"children":5715},{"style":178},[5716],{"type":36,"value":2981},{"type":27,"tag":87,"props":5718,"children":5719},{"style":184},[5720],{"type":36,"value":5721}," n);\n",{"type":27,"tag":87,"props":5723,"children":5724},{"class":89,"line":314},[5725,5730,5734,5739,5744],{"type":27,"tag":87,"props":5726,"children":5727},{"style":184},[5728],{"type":36,"value":5729},"        System.out.",{"type":27,"tag":87,"props":5731,"children":5732},{"style":94},[5733],{"type":36,"value":2967},{"type":27,"tag":87,"props":5735,"children":5736},{"style":184},[5737],{"type":36,"value":5738},"(result.",{"type":27,"tag":87,"props":5740,"children":5741},{"style":94},[5742],{"type":36,"value":5743},"join",{"type":27,"tag":87,"props":5745,"children":5746},{"style":184},[5747],{"type":36,"value":1765},{"type":27,"tag":87,"props":5749,"children":5750},{"class":89,"line":341},[5751],{"type":27,"tag":87,"props":5752,"children":5753},{"style":184},[5754],{"type":36,"value":5359},{"type":27,"tag":87,"props":5756,"children":5757},{"class":89,"line":374},[5758],{"type":27,"tag":87,"props":5759,"children":5760},{"style":184},[5761],{"type":36,"value":1805},{"type":27,"tag":32,"props":5763,"children":5764},{},[5765],{"type":27,"tag":2410,"props":5766,"children":5767},{},[5768],{"type":36,"value":5465},{"type":27,"tag":77,"props":5770,"children":5772},{"code":5771},"Hello, World\n",[5773],{"type":27,"tag":15,"props":5774,"children":5775},{"__ignoreMap":8},[5776],{"type":36,"value":5771},{"type":27,"tag":2478,"props":5778,"children":5780},{"id":5779},"pros-and-cons-of-completablefuture",[5781],{"type":36,"value":5782},"Pros and Cons of CompletableFuture",{"type":27,"tag":32,"props":5784,"children":5785},{},[5786],{"type":27,"tag":2410,"props":5787,"children":5788},{},[5789],{"type":36,"value":5790},"Pros:",{"type":27,"tag":46,"props":5792,"children":5793},{},[5794,5799,5804],{"type":27,"tag":50,"props":5795,"children":5796},{},[5797],{"type":36,"value":5798},"Native Java API, no dependencies",{"type":27,"tag":50,"props":5800,"children":5801},{},[5802],{"type":36,"value":5803},"Familiar to imperative developers",{"type":27,"tag":50,"props":5805,"children":5806},{},[5807],{"type":36,"value":5808},"Easy for linear async flows",{"type":27,"tag":32,"props":5810,"children":5811},{},[5812],{"type":27,"tag":2410,"props":5813,"children":5814},{},[5815],{"type":36,"value":5816},"Cons:",{"type":27,"tag":46,"props":5818,"children":5819},{},[5820,5825,5830],{"type":27,"tag":50,"props":5821,"children":5822},{},[5823],{"type":36,"value":5824},"Limited operators compared to reactive libraries",{"type":27,"tag":50,"props":5826,"children":5827},{},[5828],{"type":36,"value":5829},"Complex error handling in larger flows",{"type":27,"tag":50,"props":5831,"children":5832},{},[5833],{"type":36,"value":5834},"Not suitable for high-throughput event streams",{"type":27,"tag":5836,"props":5837,"children":5838},"hr",{},[],{"type":27,"tag":39,"props":5840,"children":5842},{"id":5841},"_2-reactive-streams-declarative-and-event-driven",[5843],{"type":36,"value":5844},"2. Reactive Streams: Declarative and Event-Driven",{"type":27,"tag":32,"props":5846,"children":5847},{},[5848,5850,5855,5856,5862,5863,5869,5871,5876],{"type":36,"value":5849},"Reactive programming models async execution as a stream of data. With libraries like ",{"type":27,"tag":2410,"props":5851,"children":5852},{},[5853],{"type":36,"value":5854},"Project Reactor",{"type":36,"value":624},{"type":27,"tag":15,"props":5857,"children":5859},{"className":5858},[],[5860],{"type":36,"value":5861},"Mono",{"type":36,"value":917},{"type":27,"tag":15,"props":5864,"children":5866},{"className":5865},[],[5867],{"type":36,"value":5868},"Flux",{"type":36,"value":5870},") or ",{"type":27,"tag":2410,"props":5872,"children":5873},{},[5874],{"type":36,"value":5875},"RxJava",{"type":36,"value":5877},", you can build pipelines to transform, filter, and combine async data.",{"type":27,"tag":2478,"props":5879,"children":5881},{"id":5880},"example-1-mono-single-async-value",[5882],{"type":36,"value":5883},"Example 1: Mono (Single Async Value)",{"type":27,"tag":77,"props":5885,"children":5887},{"code":5886,"language":1469,"meta":8,"className":1566,"style":8},"import reactor.core.publisher.Mono;\nimport java.time.Duration;\n\npublic class ReactorMonoExample {\n    public static void main(String[] args) {\n        Mono.just(\"Hello from Mono!\")\n            .delayElement(Duration.ofMillis(500))\n            .subscribe(System.out::println);\n\n        sleep(1000);\n    }\n\n    static void sleep(long millis) {\n        try { Thread.sleep(millis); } catch (InterruptedException e) { }\n    }\n}\n",[5888],{"type":27,"tag":15,"props":5889,"children":5890},{"__ignoreMap":8},[5891,5903,5915,5922,5942,5981,6007,6041,6065,6072,6091,6098,6105,6136,6171,6178],{"type":27,"tag":87,"props":5892,"children":5893},{"class":89,"line":90},[5894,5898],{"type":27,"tag":87,"props":5895,"children":5896},{"style":178},[5897],{"type":36,"value":192},{"type":27,"tag":87,"props":5899,"children":5900},{"style":184},[5901],{"type":36,"value":5902}," reactor.core.publisher.Mono;\n",{"type":27,"tag":87,"props":5904,"children":5905},{"class":89,"line":200},[5906,5910],{"type":27,"tag":87,"props":5907,"children":5908},{"style":178},[5909],{"type":36,"value":192},{"type":27,"tag":87,"props":5911,"children":5912},{"style":184},[5913],{"type":36,"value":5914}," java.time.Duration;\n",{"type":27,"tag":87,"props":5916,"children":5917},{"class":89,"line":222},[5918],{"type":27,"tag":87,"props":5919,"children":5920},{"emptyLinePlaceholder":261},[5921],{"type":36,"value":264},{"type":27,"tag":87,"props":5923,"children":5924},{"class":89,"line":235},[5925,5929,5933,5938],{"type":27,"tag":87,"props":5926,"children":5927},{"style":178},[5928],{"type":36,"value":4594},{"type":27,"tag":87,"props":5930,"children":5931},{"style":178},[5932],{"type":36,"value":4609},{"type":27,"tag":87,"props":5934,"children":5935},{"style":94},[5936],{"type":36,"value":5937}," ReactorMonoExample",{"type":27,"tag":87,"props":5939,"children":5940},{"style":184},[5941],{"type":36,"value":4683},{"type":27,"tag":87,"props":5943,"children":5944},{"class":89,"line":257},[5945,5949,5953,5957,5961,5965,5969,5973,5977],{"type":27,"tag":87,"props":5946,"children":5947},{"style":178},[5948],{"type":36,"value":5162},{"type":27,"tag":87,"props":5950,"children":5951},{"style":178},[5952],{"type":36,"value":5167},{"type":27,"tag":87,"props":5954,"children":5955},{"style":178},[5956],{"type":36,"value":5172},{"type":27,"tag":87,"props":5958,"children":5959},{"style":94},[5960],{"type":36,"value":5177},{"type":27,"tag":87,"props":5962,"children":5963},{"style":184},[5964],{"type":36,"value":1282},{"type":27,"tag":87,"props":5966,"children":5967},{"style":178},[5968],{"type":36,"value":2839},{"type":27,"tag":87,"props":5970,"children":5971},{"style":184},[5972],{"type":36,"value":5190},{"type":27,"tag":87,"props":5974,"children":5975},{"style":359},[5976],{"type":36,"value":5195},{"type":27,"tag":87,"props":5978,"children":5979},{"style":184},[5980],{"type":36,"value":5200},{"type":27,"tag":87,"props":5982,"children":5983},{"class":89,"line":267},[5984,5989,5994,5998,6003],{"type":27,"tag":87,"props":5985,"children":5986},{"style":184},[5987],{"type":36,"value":5988},"        Mono.",{"type":27,"tag":87,"props":5990,"children":5991},{"style":94},[5992],{"type":36,"value":5993},"just",{"type":27,"tag":87,"props":5995,"children":5996},{"style":184},[5997],{"type":36,"value":1282},{"type":27,"tag":87,"props":5999,"children":6000},{"style":100},[6001],{"type":36,"value":6002},"\"Hello from Mono!\"",{"type":27,"tag":87,"props":6004,"children":6005},{"style":184},[6006],{"type":36,"value":311},{"type":27,"tag":87,"props":6008,"children":6009},{"class":89,"line":276},[6010,6015,6020,6024,6028,6032,6037],{"type":27,"tag":87,"props":6011,"children":6012},{"style":184},[6013],{"type":36,"value":6014},"            .",{"type":27,"tag":87,"props":6016,"children":6017},{"style":94},[6018],{"type":36,"value":6019},"delayElement",{"type":27,"tag":87,"props":6021,"children":6022},{"style":184},[6023],{"type":36,"value":2681},{"type":27,"tag":87,"props":6025,"children":6026},{"style":94},[6027],{"type":36,"value":2686},{"type":27,"tag":87,"props":6029,"children":6030},{"style":184},[6031],{"type":36,"value":1282},{"type":27,"tag":87,"props":6033,"children":6034},{"style":288},[6035],{"type":36,"value":6036},"500",{"type":27,"tag":87,"props":6038,"children":6039},{"style":184},[6040],{"type":36,"value":2700},{"type":27,"tag":87,"props":6042,"children":6043},{"class":89,"line":284},[6044,6048,6053,6057,6061],{"type":27,"tag":87,"props":6045,"children":6046},{"style":184},[6047],{"type":36,"value":6014},{"type":27,"tag":87,"props":6049,"children":6050},{"style":94},[6051],{"type":36,"value":6052},"subscribe",{"type":27,"tag":87,"props":6054,"children":6055},{"style":184},[6056],{"type":36,"value":5314},{"type":27,"tag":87,"props":6058,"children":6059},{"style":178},[6060],{"type":36,"value":5319},{"type":27,"tag":87,"props":6062,"children":6063},{"style":184},[6064],{"type":36,"value":5324},{"type":27,"tag":87,"props":6066,"children":6067},{"class":89,"line":314},[6068],{"type":27,"tag":87,"props":6069,"children":6070},{"emptyLinePlaceholder":261},[6071],{"type":36,"value":264},{"type":27,"tag":87,"props":6073,"children":6074},{"class":89,"line":341},[6075,6079,6083,6087],{"type":27,"tag":87,"props":6076,"children":6077},{"style":94},[6078],{"type":36,"value":5332},{"type":27,"tag":87,"props":6080,"children":6081},{"style":184},[6082],{"type":36,"value":1282},{"type":27,"tag":87,"props":6084,"children":6085},{"style":288},[6086],{"type":36,"value":2695},{"type":27,"tag":87,"props":6088,"children":6089},{"style":184},[6090],{"type":36,"value":1607},{"type":27,"tag":87,"props":6092,"children":6093},{"class":89,"line":374},[6094],{"type":27,"tag":87,"props":6095,"children":6096},{"style":184},[6097],{"type":36,"value":5359},{"type":27,"tag":87,"props":6099,"children":6100},{"class":89,"line":699},[6101],{"type":27,"tag":87,"props":6102,"children":6103},{"emptyLinePlaceholder":261},[6104],{"type":36,"value":264},{"type":27,"tag":87,"props":6106,"children":6107},{"class":89,"line":707},[6108,6112,6116,6120,6124,6128,6132],{"type":27,"tag":87,"props":6109,"children":6110},{"style":178},[6111],{"type":36,"value":5374},{"type":27,"tag":87,"props":6113,"children":6114},{"style":178},[6115],{"type":36,"value":5172},{"type":27,"tag":87,"props":6117,"children":6118},{"style":94},[6119],{"type":36,"value":5383},{"type":27,"tag":87,"props":6121,"children":6122},{"style":184},[6123],{"type":36,"value":1282},{"type":27,"tag":87,"props":6125,"children":6126},{"style":178},[6127],{"type":36,"value":5392},{"type":27,"tag":87,"props":6129,"children":6130},{"style":359},[6131],{"type":36,"value":5397},{"type":27,"tag":87,"props":6133,"children":6134},{"style":184},[6135],{"type":36,"value":5200},{"type":27,"tag":87,"props":6137,"children":6138},{"class":89,"line":725},[6139,6143,6147,6151,6155,6159,6163,6167],{"type":27,"tag":87,"props":6140,"children":6141},{"style":178},[6142],{"type":36,"value":5409},{"type":27,"tag":87,"props":6144,"children":6145},{"style":184},[6146],{"type":36,"value":5414},{"type":27,"tag":87,"props":6148,"children":6149},{"style":94},[6150],{"type":36,"value":5419},{"type":27,"tag":87,"props":6152,"children":6153},{"style":184},[6154],{"type":36,"value":5424},{"type":27,"tag":87,"props":6156,"children":6157},{"style":178},[6158],{"type":36,"value":5429},{"type":27,"tag":87,"props":6160,"children":6161},{"style":184},[6162],{"type":36,"value":5434},{"type":27,"tag":87,"props":6164,"children":6165},{"style":359},[6166],{"type":36,"value":1300},{"type":27,"tag":87,"props":6168,"children":6169},{"style":184},[6170],{"type":36,"value":5443},{"type":27,"tag":87,"props":6172,"children":6173},{"class":89,"line":1039},[6174],{"type":27,"tag":87,"props":6175,"children":6176},{"style":184},[6177],{"type":36,"value":5359},{"type":27,"tag":87,"props":6179,"children":6180},{"class":89,"line":1052},[6181],{"type":27,"tag":87,"props":6182,"children":6183},{"style":184},[6184],{"type":36,"value":1805},{"type":27,"tag":32,"props":6186,"children":6187},{},[6188],{"type":27,"tag":2410,"props":6189,"children":6190},{},[6191],{"type":36,"value":5465},{"type":27,"tag":77,"props":6193,"children":6195},{"code":6194},"Hello from Mono!\n",[6196],{"type":27,"tag":15,"props":6197,"children":6198},{"__ignoreMap":8},[6199],{"type":36,"value":6194},{"type":27,"tag":2478,"props":6201,"children":6203},{"id":6202},"example-2-flux-multiple-async-events",[6204],{"type":36,"value":6205},"Example 2: Flux (Multiple Async Events)",{"type":27,"tag":77,"props":6207,"children":6209},{"code":6208,"language":1469,"meta":8,"className":1566,"style":8},"import reactor.core.publisher.Flux;\nimport java.time.Duration;\n\npublic class ReactorFluxExample {\n    public static void main(String[] args) {\n        Flux.interval(Duration.ofMillis(300))\n            .take(5)\n            .map(i -> \"Tick \" + i)\n            .subscribe(System.out::println);\n\n        sleep(2000);\n    }\n\n    static void sleep(long millis) {\n        try { Thread.sleep(millis); } catch (InterruptedException e) { }\n    }\n}\n",[6210],{"type":27,"tag":15,"props":6211,"children":6212},{"__ignoreMap":8},[6213,6225,6236,6243,6263,6302,6336,6360,6394,6417,6424,6444,6451,6458,6489,6524,6531],{"type":27,"tag":87,"props":6214,"children":6215},{"class":89,"line":90},[6216,6220],{"type":27,"tag":87,"props":6217,"children":6218},{"style":178},[6219],{"type":36,"value":192},{"type":27,"tag":87,"props":6221,"children":6222},{"style":184},[6223],{"type":36,"value":6224}," reactor.core.publisher.Flux;\n",{"type":27,"tag":87,"props":6226,"children":6227},{"class":89,"line":200},[6228,6232],{"type":27,"tag":87,"props":6229,"children":6230},{"style":178},[6231],{"type":36,"value":192},{"type":27,"tag":87,"props":6233,"children":6234},{"style":184},[6235],{"type":36,"value":5914},{"type":27,"tag":87,"props":6237,"children":6238},{"class":89,"line":222},[6239],{"type":27,"tag":87,"props":6240,"children":6241},{"emptyLinePlaceholder":261},[6242],{"type":36,"value":264},{"type":27,"tag":87,"props":6244,"children":6245},{"class":89,"line":235},[6246,6250,6254,6259],{"type":27,"tag":87,"props":6247,"children":6248},{"style":178},[6249],{"type":36,"value":4594},{"type":27,"tag":87,"props":6251,"children":6252},{"style":178},[6253],{"type":36,"value":4609},{"type":27,"tag":87,"props":6255,"children":6256},{"style":94},[6257],{"type":36,"value":6258}," ReactorFluxExample",{"type":27,"tag":87,"props":6260,"children":6261},{"style":184},[6262],{"type":36,"value":4683},{"type":27,"tag":87,"props":6264,"children":6265},{"class":89,"line":257},[6266,6270,6274,6278,6282,6286,6290,6294,6298],{"type":27,"tag":87,"props":6267,"children":6268},{"style":178},[6269],{"type":36,"value":5162},{"type":27,"tag":87,"props":6271,"children":6272},{"style":178},[6273],{"type":36,"value":5167},{"type":27,"tag":87,"props":6275,"children":6276},{"style":178},[6277],{"type":36,"value":5172},{"type":27,"tag":87,"props":6279,"children":6280},{"style":94},[6281],{"type":36,"value":5177},{"type":27,"tag":87,"props":6283,"children":6284},{"style":184},[6285],{"type":36,"value":1282},{"type":27,"tag":87,"props":6287,"children":6288},{"style":178},[6289],{"type":36,"value":2839},{"type":27,"tag":87,"props":6291,"children":6292},{"style":184},[6293],{"type":36,"value":5190},{"type":27,"tag":87,"props":6295,"children":6296},{"style":359},[6297],{"type":36,"value":5195},{"type":27,"tag":87,"props":6299,"children":6300},{"style":184},[6301],{"type":36,"value":5200},{"type":27,"tag":87,"props":6303,"children":6304},{"class":89,"line":267},[6305,6310,6315,6319,6323,6327,6332],{"type":27,"tag":87,"props":6306,"children":6307},{"style":184},[6308],{"type":36,"value":6309},"        Flux.",{"type":27,"tag":87,"props":6311,"children":6312},{"style":94},[6313],{"type":36,"value":6314},"interval",{"type":27,"tag":87,"props":6316,"children":6317},{"style":184},[6318],{"type":36,"value":2681},{"type":27,"tag":87,"props":6320,"children":6321},{"style":94},[6322],{"type":36,"value":2686},{"type":27,"tag":87,"props":6324,"children":6325},{"style":184},[6326],{"type":36,"value":1282},{"type":27,"tag":87,"props":6328,"children":6329},{"style":288},[6330],{"type":36,"value":6331},"300",{"type":27,"tag":87,"props":6333,"children":6334},{"style":184},[6335],{"type":36,"value":2700},{"type":27,"tag":87,"props":6337,"children":6338},{"class":89,"line":276},[6339,6343,6348,6352,6356],{"type":27,"tag":87,"props":6340,"children":6341},{"style":184},[6342],{"type":36,"value":6014},{"type":27,"tag":87,"props":6344,"children":6345},{"style":94},[6346],{"type":36,"value":6347},"take",{"type":27,"tag":87,"props":6349,"children":6350},{"style":184},[6351],{"type":36,"value":1282},{"type":27,"tag":87,"props":6353,"children":6354},{"style":288},[6355],{"type":36,"value":2745},{"type":27,"tag":87,"props":6357,"children":6358},{"style":184},[6359],{"type":36,"value":311},{"type":27,"tag":87,"props":6361,"children":6362},{"class":89,"line":284},[6363,6367,6372,6376,6380,6385,6389],{"type":27,"tag":87,"props":6364,"children":6365},{"style":184},[6366],{"type":36,"value":6014},{"type":27,"tag":87,"props":6368,"children":6369},{"style":94},[6370],{"type":36,"value":6371},"map",{"type":27,"tag":87,"props":6373,"children":6374},{"style":184},[6375],{"type":36,"value":4484},{"type":27,"tag":87,"props":6377,"children":6378},{"style":178},[6379],{"type":36,"value":2867},{"type":27,"tag":87,"props":6381,"children":6382},{"style":100},[6383],{"type":36,"value":6384}," \"Tick \"",{"type":27,"tag":87,"props":6386,"children":6387},{"style":178},[6388],{"type":36,"value":2981},{"type":27,"tag":87,"props":6390,"children":6391},{"style":184},[6392],{"type":36,"value":6393}," i)\n",{"type":27,"tag":87,"props":6395,"children":6396},{"class":89,"line":314},[6397,6401,6405,6409,6413],{"type":27,"tag":87,"props":6398,"children":6399},{"style":184},[6400],{"type":36,"value":6014},{"type":27,"tag":87,"props":6402,"children":6403},{"style":94},[6404],{"type":36,"value":6052},{"type":27,"tag":87,"props":6406,"children":6407},{"style":184},[6408],{"type":36,"value":5314},{"type":27,"tag":87,"props":6410,"children":6411},{"style":178},[6412],{"type":36,"value":5319},{"type":27,"tag":87,"props":6414,"children":6415},{"style":184},[6416],{"type":36,"value":5324},{"type":27,"tag":87,"props":6418,"children":6419},{"class":89,"line":341},[6420],{"type":27,"tag":87,"props":6421,"children":6422},{"emptyLinePlaceholder":261},[6423],{"type":36,"value":264},{"type":27,"tag":87,"props":6425,"children":6426},{"class":89,"line":374},[6427,6431,6435,6440],{"type":27,"tag":87,"props":6428,"children":6429},{"style":94},[6430],{"type":36,"value":5332},{"type":27,"tag":87,"props":6432,"children":6433},{"style":184},[6434],{"type":36,"value":1282},{"type":27,"tag":87,"props":6436,"children":6437},{"style":288},[6438],{"type":36,"value":6439},"2000",{"type":27,"tag":87,"props":6441,"children":6442},{"style":184},[6443],{"type":36,"value":1607},{"type":27,"tag":87,"props":6445,"children":6446},{"class":89,"line":699},[6447],{"type":27,"tag":87,"props":6448,"children":6449},{"style":184},[6450],{"type":36,"value":5359},{"type":27,"tag":87,"props":6452,"children":6453},{"class":89,"line":707},[6454],{"type":27,"tag":87,"props":6455,"children":6456},{"emptyLinePlaceholder":261},[6457],{"type":36,"value":264},{"type":27,"tag":87,"props":6459,"children":6460},{"class":89,"line":725},[6461,6465,6469,6473,6477,6481,6485],{"type":27,"tag":87,"props":6462,"children":6463},{"style":178},[6464],{"type":36,"value":5374},{"type":27,"tag":87,"props":6466,"children":6467},{"style":178},[6468],{"type":36,"value":5172},{"type":27,"tag":87,"props":6470,"children":6471},{"style":94},[6472],{"type":36,"value":5383},{"type":27,"tag":87,"props":6474,"children":6475},{"style":184},[6476],{"type":36,"value":1282},{"type":27,"tag":87,"props":6478,"children":6479},{"style":178},[6480],{"type":36,"value":5392},{"type":27,"tag":87,"props":6482,"children":6483},{"style":359},[6484],{"type":36,"value":5397},{"type":27,"tag":87,"props":6486,"children":6487},{"style":184},[6488],{"type":36,"value":5200},{"type":27,"tag":87,"props":6490,"children":6491},{"class":89,"line":1039},[6492,6496,6500,6504,6508,6512,6516,6520],{"type":27,"tag":87,"props":6493,"children":6494},{"style":178},[6495],{"type":36,"value":5409},{"type":27,"tag":87,"props":6497,"children":6498},{"style":184},[6499],{"type":36,"value":5414},{"type":27,"tag":87,"props":6501,"children":6502},{"style":94},[6503],{"type":36,"value":5419},{"type":27,"tag":87,"props":6505,"children":6506},{"style":184},[6507],{"type":36,"value":5424},{"type":27,"tag":87,"props":6509,"children":6510},{"style":178},[6511],{"type":36,"value":5429},{"type":27,"tag":87,"props":6513,"children":6514},{"style":184},[6515],{"type":36,"value":5434},{"type":27,"tag":87,"props":6517,"children":6518},{"style":359},[6519],{"type":36,"value":1300},{"type":27,"tag":87,"props":6521,"children":6522},{"style":184},[6523],{"type":36,"value":5443},{"type":27,"tag":87,"props":6525,"children":6526},{"class":89,"line":1052},[6527],{"type":27,"tag":87,"props":6528,"children":6529},{"style":184},[6530],{"type":36,"value":5359},{"type":27,"tag":87,"props":6532,"children":6533},{"class":89,"line":1060},[6534],{"type":27,"tag":87,"props":6535,"children":6536},{"style":184},[6537],{"type":36,"value":1805},{"type":27,"tag":32,"props":6539,"children":6540},{},[6541],{"type":27,"tag":2410,"props":6542,"children":6543},{},[6544],{"type":36,"value":5465},{"type":27,"tag":77,"props":6546,"children":6548},{"code":6547},"Tick 0\nTick 1\nTick 2\nTick 3\nTick 4\n",[6549],{"type":27,"tag":15,"props":6550,"children":6551},{"__ignoreMap":8},[6552],{"type":36,"value":6547},{"type":27,"tag":2478,"props":6554,"children":6556},{"id":6555},"pros-and-cons-of-reactive-streams",[6557],{"type":36,"value":6558},"Pros and Cons of Reactive Streams",{"type":27,"tag":32,"props":6560,"children":6561},{},[6562],{"type":27,"tag":2410,"props":6563,"children":6564},{},[6565],{"type":36,"value":5790},{"type":27,"tag":46,"props":6567,"children":6568},{},[6569,6574,6579],{"type":27,"tag":50,"props":6570,"children":6571},{},[6572],{"type":36,"value":6573},"Rich operator set for complex flows",{"type":27,"tag":50,"props":6575,"children":6576},{},[6577],{"type":36,"value":6578},"Built-in backpressure handling",{"type":27,"tag":50,"props":6580,"children":6581},{},[6582],{"type":36,"value":6583},"Ideal for data streams and event-driven apps",{"type":27,"tag":32,"props":6585,"children":6586},{},[6587],{"type":27,"tag":2410,"props":6588,"children":6589},{},[6590],{"type":36,"value":5816},{"type":27,"tag":46,"props":6592,"children":6593},{},[6594,6599,6604],{"type":27,"tag":50,"props":6595,"children":6596},{},[6597],{"type":36,"value":6598},"Requires learning new paradigm",{"type":27,"tag":50,"props":6600,"children":6601},{},[6602],{"type":36,"value":6603},"Can be overkill for simple use cases",{"type":27,"tag":50,"props":6605,"children":6606},{},[6607],{"type":36,"value":6608},"More dependencies (Reactor, RxJava)",{"type":27,"tag":5836,"props":6610,"children":6611},{},[],{"type":27,"tag":39,"props":6613,"children":6615},{"id":6614},"_3-when-to-use-each",[6616],{"type":36,"value":6617},"3. When to Use Each?",{"type":27,"tag":6619,"props":6620,"children":6621},"table",{},[6622,6644],{"type":27,"tag":6623,"props":6624,"children":6625},"thead",{},[6626],{"type":27,"tag":6627,"props":6628,"children":6629},"tr",{},[6630,6636,6640],{"type":27,"tag":6631,"props":6632,"children":6633},"th",{},[6634],{"type":36,"value":6635},"Use Case",{"type":27,"tag":6631,"props":6637,"children":6638},{},[6639],{"type":36,"value":5078},{"type":27,"tag":6631,"props":6641,"children":6642},{},[6643],{"type":36,"value":5084},{"type":27,"tag":6645,"props":6646,"children":6647},"tbody",{},[6648,6667,6683,6699,6715,6731],{"type":27,"tag":6627,"props":6649,"children":6650},{},[6651,6657,6662],{"type":27,"tag":6652,"props":6653,"children":6654},"td",{},[6655],{"type":36,"value":6656},"Simple async call",{"type":27,"tag":6652,"props":6658,"children":6659},{},[6660],{"type":36,"value":6661},"✅",{"type":27,"tag":6652,"props":6663,"children":6664},{},[6665],{"type":36,"value":6666},"❌",{"type":27,"tag":6627,"props":6668,"children":6669},{},[6670,6675,6679],{"type":27,"tag":6652,"props":6671,"children":6672},{},[6673],{"type":36,"value":6674},"API call + transform",{"type":27,"tag":6652,"props":6676,"children":6677},{},[6678],{"type":36,"value":6661},{"type":27,"tag":6652,"props":6680,"children":6681},{},[6682],{"type":36,"value":6661},{"type":27,"tag":6627,"props":6684,"children":6685},{},[6686,6691,6695],{"type":27,"tag":6652,"props":6687,"children":6688},{},[6689],{"type":36,"value":6690},"Data pipeline (streaming)",{"type":27,"tag":6652,"props":6692,"children":6693},{},[6694],{"type":36,"value":6666},{"type":27,"tag":6652,"props":6696,"children":6697},{},[6698],{"type":36,"value":6661},{"type":27,"tag":6627,"props":6700,"children":6701},{},[6702,6707,6711],{"type":27,"tag":6652,"props":6703,"children":6704},{},[6705],{"type":36,"value":6706},"Reactive UI/backend",{"type":27,"tag":6652,"props":6708,"children":6709},{},[6710],{"type":36,"value":6666},{"type":27,"tag":6652,"props":6712,"children":6713},{},[6714],{"type":36,"value":6661},{"type":27,"tag":6627,"props":6716,"children":6717},{},[6718,6723,6727],{"type":27,"tag":6652,"props":6719,"children":6720},{},[6721],{"type":36,"value":6722},"Minimal dependencies",{"type":27,"tag":6652,"props":6724,"children":6725},{},[6726],{"type":36,"value":6661},{"type":27,"tag":6652,"props":6728,"children":6729},{},[6730],{"type":36,"value":6666},{"type":27,"tag":6627,"props":6732,"children":6733},{},[6734,6739,6743],{"type":27,"tag":6652,"props":6735,"children":6736},{},[6737],{"type":36,"value":6738},"Advanced composition",{"type":27,"tag":6652,"props":6740,"children":6741},{},[6742],{"type":36,"value":6666},{"type":27,"tag":6652,"props":6744,"children":6745},{},[6746],{"type":36,"value":6661},{"type":27,"tag":5836,"props":6748,"children":6749},{},[],{"type":27,"tag":39,"props":6751,"children":6752},{"id":2304},[6753],{"type":36,"value":2307},{"type":27,"tag":32,"props":6755,"children":6756},{},[6757,6759,6764,6766,6771],{"type":36,"value":6758},"Both ",{"type":27,"tag":15,"props":6760,"children":6762},{"className":6761},[],[6763],{"type":36,"value":5078},{"type":36,"value":6765}," and Reactive Streams serve asynchronous needs, but they excel in different areas. For straightforward async calls, ",{"type":27,"tag":15,"props":6767,"children":6769},{"className":6768},[],[6770],{"type":36,"value":5078},{"type":36,"value":6772}," is often enough. For complex, event-driven, and high-throughput systems, reactive programming shines.",{"type":27,"tag":32,"props":6774,"children":6775},{},[6776],{"type":36,"value":6777},"By mastering both, you’ll be ready to choose the right tool for every concurrency challenge in modern Java applications.",{"type":27,"tag":1397,"props":6779,"children":6780},{"id":2315},[6781],{"type":36,"value":2318},{"type":27,"tag":46,"props":6783,"children":6784},{},[6785,6795,6805],{"type":27,"tag":50,"props":6786,"children":6787},{},[6788],{"type":27,"tag":1410,"props":6789,"children":6792},{"href":6790,"rel":6791},"https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html",[1414],[6793],{"type":36,"value":6794},"CompletableFuture Javadoc",{"type":27,"tag":50,"props":6796,"children":6797},{},[6798],{"type":27,"tag":1410,"props":6799,"children":6802},{"href":6800,"rel":6801},"https://projectreactor.io/docs",[1414],[6803],{"type":36,"value":6804},"Project Reactor Documentation",{"type":27,"tag":50,"props":6806,"children":6807},{},[6808],{"type":27,"tag":1410,"props":6809,"children":6812},{"href":6810,"rel":6811},"https://www.reactivemanifesto.org/",[1414],[6813],{"type":36,"value":6814},"Reactive Manifesto",{"type":27,"tag":1439,"props":6816,"children":6817},{},[6818],{"type":36,"value":1443},{"title":8,"searchDepth":200,"depth":200,"links":6820},[6821,6826,6831,6832],{"id":5089,"depth":200,"text":5092,"children":6822},[6823,6824,6825],{"id":5105,"depth":222,"text":5108},{"id":5476,"depth":222,"text":5479},{"id":5779,"depth":222,"text":5782},{"id":5841,"depth":200,"text":5844,"children":6827},[6828,6829,6830],{"id":5880,"depth":222,"text":5883},{"id":6202,"depth":222,"text":6205},{"id":6555,"depth":222,"text":6558},{"id":6614,"depth":200,"text":6617},{"id":2304,"depth":200,"text":2307},"content:posts:async-java-completable-vs-reactive.md","posts/async-java-completable-vs-reactive.md","posts/async-java-completable-vs-reactive",{"_path":6837,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":6838,"description":6839,"date":6840,"layout":12,"subtitle":6841,"image":6842,"optimized_image":6842,"category":15,"tags":6843,"author":22,"paginate":7,"body":6845,"_type":1455,"_id":8081,"_source":1457,"_file":8082,"_stem":8083,"_extension":1460},"/posts/mastering-concurrency","Mastering Concurrency in Java: Threads, Executors, and Virtual Threads","Exploring Java’s concurrency model with detailed insights into Threads, ExecutorService, and Virtual Threads from Project Loom.","2024-03-15T11:00:00.000Z","A Deep Dive into Java’s Multithreading and Parallel Computing","/assets/img/uploads/java-concurrency.png",[15,1469,5062,6844],"multithreading",{"type":24,"children":6846,"toc":8064},[6847,6855,6861,6866,6919,6932,6938,6966,7203,7209,7242,7247,7253,7273,7279,7284,7575,7581,7628,7634,7652,7658,7663,7669,7702,7707,7971,7977,7995,7999,8004,8009,8013,8055,8060],{"type":27,"tag":28,"props":6848,"children":6849},{},[6850],{"type":27,"tag":32,"props":6851,"children":6852},{},[6853],{"type":36,"value":6854},"Java's concurrency model is a critical component for building scalable and efficient applications. From classic Thread management to modern ExecutorService and the revolutionary Virtual Threads in Project Loom, mastering Java’s concurrency tools is essential for high-performance development.",{"type":27,"tag":39,"props":6856,"children":6858},{"id":6857},"understanding-javas-concurrency-model",[6859],{"type":36,"value":6860},"Understanding Java’s Concurrency Model",{"type":27,"tag":32,"props":6862,"children":6863},{},[6864],{"type":36,"value":6865},"Concurrency in Java enables applications to perform multiple tasks simultaneously, improving throughput and responsiveness. Java provides several concurrency primitives:",{"type":27,"tag":46,"props":6867,"children":6868},{},[6869,6879,6889,6899,6909],{"type":27,"tag":50,"props":6870,"children":6871},{},[6872,6877],{"type":27,"tag":2410,"props":6873,"children":6874},{},[6875],{"type":36,"value":6876},"Threads",{"type":36,"value":6878},": The fundamental unit of execution, allowing tasks to run in parallel.",{"type":27,"tag":50,"props":6880,"children":6881},{},[6882,6887],{"type":27,"tag":2410,"props":6883,"children":6884},{},[6885],{"type":36,"value":6886},"Executors",{"type":36,"value":6888},": High-level abstraction for managing thread pools and task execution.",{"type":27,"tag":50,"props":6890,"children":6891},{},[6892,6897],{"type":27,"tag":2410,"props":6893,"children":6894},{},[6895],{"type":36,"value":6896},"Virtual Threads",{"type":36,"value":6898},": Lightweight, memory-efficient threads introduced in Java 21 for massive scalability.",{"type":27,"tag":50,"props":6900,"children":6901},{},[6902,6907],{"type":27,"tag":2410,"props":6903,"children":6904},{},[6905],{"type":36,"value":6906},"Fork/Join Framework",{"type":36,"value":6908},": Designed for divide-and-conquer algorithms using parallel task execution.",{"type":27,"tag":50,"props":6910,"children":6911},{},[6912,6917],{"type":27,"tag":2410,"props":6913,"children":6914},{},[6915],{"type":36,"value":6916},"Reactive Programming",{"type":36,"value":6918},": Asynchronous, non-blocking programming using event streams.",{"type":27,"tag":32,"props":6920,"children":6921},{},[6922,6924,6930],{"type":36,"value":6923},"Let's now take a deeper look at three major building blocks of concurrent programming in Java: classic threads, the ",{"type":27,"tag":15,"props":6925,"children":6927},{"className":6926},[],[6928],{"type":36,"value":6929},"ExecutorService",{"type":36,"value":6931},", and the new virtual threads.",{"type":27,"tag":39,"props":6933,"children":6935},{"id":6934},"classic-approach-java-threads",[6936],{"type":36,"value":6937},"Classic Approach: Java Threads",{"type":27,"tag":32,"props":6939,"children":6940},{},[6941,6943,6949,6951,6956,6958,6964],{"type":36,"value":6942},"The most basic unit of concurrency in Java is the ",{"type":27,"tag":15,"props":6944,"children":6946},{"className":6945},[],[6947],{"type":36,"value":6948},"Thread",{"type":36,"value":6950},". You can extend the ",{"type":27,"tag":15,"props":6952,"children":6954},{"className":6953},[],[6955],{"type":36,"value":6948},{"type":36,"value":6957}," class or implement the ",{"type":27,"tag":15,"props":6959,"children":6961},{"className":6960},[],[6962],{"type":36,"value":6963},"Runnable",{"type":36,"value":6965}," interface to define concurrent tasks.",{"type":27,"tag":77,"props":6967,"children":6969},{"className":1566,"code":6968,"language":1469,"meta":8,"style":8},"class SimpleThreadExample extends Thread {\n    public void run() {\n        System.out.println(\"Thread running: \" + Thread.currentThread().getName());\n    }\n}\n\npublic class ThreadDemo {\n    public static void main(String[] args) {\n        SimpleThreadExample thread = new SimpleThreadExample();\n        thread.start();\n    }\n}\n",[6970],{"type":27,"tag":15,"props":6971,"children":6972},{"__ignoreMap":8},[6973,6999,7020,7068,7075,7082,7089,7109,7148,7172,7189,7196],{"type":27,"tag":87,"props":6974,"children":6975},{"class":89,"line":90},[6976,6981,6986,6990,6995],{"type":27,"tag":87,"props":6977,"children":6978},{"style":178},[6979],{"type":36,"value":6980},"class",{"type":27,"tag":87,"props":6982,"children":6983},{"style":94},[6984],{"type":36,"value":6985}," SimpleThreadExample",{"type":27,"tag":87,"props":6987,"children":6988},{"style":178},[6989],{"type":36,"value":4673},{"type":27,"tag":87,"props":6991,"children":6992},{"style":94},[6993],{"type":36,"value":6994}," Thread",{"type":27,"tag":87,"props":6996,"children":6997},{"style":184},[6998],{"type":36,"value":4683},{"type":27,"tag":87,"props":7000,"children":7001},{"class":89,"line":200},[7002,7006,7010,7015],{"type":27,"tag":87,"props":7003,"children":7004},{"style":178},[7005],{"type":36,"value":5162},{"type":27,"tag":87,"props":7007,"children":7008},{"style":178},[7009],{"type":36,"value":5172},{"type":27,"tag":87,"props":7011,"children":7012},{"style":94},[7013],{"type":36,"value":7014}," run",{"type":27,"tag":87,"props":7016,"children":7017},{"style":184},[7018],{"type":36,"value":7019},"() {\n",{"type":27,"tag":87,"props":7021,"children":7022},{"class":89,"line":222},[7023,7027,7031,7035,7040,7044,7049,7054,7059,7064],{"type":27,"tag":87,"props":7024,"children":7025},{"style":184},[7026],{"type":36,"value":5729},{"type":27,"tag":87,"props":7028,"children":7029},{"style":94},[7030],{"type":36,"value":2967},{"type":27,"tag":87,"props":7032,"children":7033},{"style":184},[7034],{"type":36,"value":1282},{"type":27,"tag":87,"props":7036,"children":7037},{"style":100},[7038],{"type":36,"value":7039},"\"Thread running: \"",{"type":27,"tag":87,"props":7041,"children":7042},{"style":178},[7043],{"type":36,"value":2981},{"type":27,"tag":87,"props":7045,"children":7046},{"style":184},[7047],{"type":36,"value":7048}," Thread.",{"type":27,"tag":87,"props":7050,"children":7051},{"style":94},[7052],{"type":36,"value":7053},"currentThread",{"type":27,"tag":87,"props":7055,"children":7056},{"style":184},[7057],{"type":36,"value":7058},"().",{"type":27,"tag":87,"props":7060,"children":7061},{"style":94},[7062],{"type":36,"value":7063},"getName",{"type":27,"tag":87,"props":7065,"children":7066},{"style":184},[7067],{"type":36,"value":1765},{"type":27,"tag":87,"props":7069,"children":7070},{"class":89,"line":235},[7071],{"type":27,"tag":87,"props":7072,"children":7073},{"style":184},[7074],{"type":36,"value":5359},{"type":27,"tag":87,"props":7076,"children":7077},{"class":89,"line":257},[7078],{"type":27,"tag":87,"props":7079,"children":7080},{"style":184},[7081],{"type":36,"value":1805},{"type":27,"tag":87,"props":7083,"children":7084},{"class":89,"line":267},[7085],{"type":27,"tag":87,"props":7086,"children":7087},{"emptyLinePlaceholder":261},[7088],{"type":36,"value":264},{"type":27,"tag":87,"props":7090,"children":7091},{"class":89,"line":276},[7092,7096,7100,7105],{"type":27,"tag":87,"props":7093,"children":7094},{"style":178},[7095],{"type":36,"value":4594},{"type":27,"tag":87,"props":7097,"children":7098},{"style":178},[7099],{"type":36,"value":4609},{"type":27,"tag":87,"props":7101,"children":7102},{"style":94},[7103],{"type":36,"value":7104}," ThreadDemo",{"type":27,"tag":87,"props":7106,"children":7107},{"style":184},[7108],{"type":36,"value":4683},{"type":27,"tag":87,"props":7110,"children":7111},{"class":89,"line":284},[7112,7116,7120,7124,7128,7132,7136,7140,7144],{"type":27,"tag":87,"props":7113,"children":7114},{"style":178},[7115],{"type":36,"value":5162},{"type":27,"tag":87,"props":7117,"children":7118},{"style":178},[7119],{"type":36,"value":5167},{"type":27,"tag":87,"props":7121,"children":7122},{"style":178},[7123],{"type":36,"value":5172},{"type":27,"tag":87,"props":7125,"children":7126},{"style":94},[7127],{"type":36,"value":5177},{"type":27,"tag":87,"props":7129,"children":7130},{"style":184},[7131],{"type":36,"value":1282},{"type":27,"tag":87,"props":7133,"children":7134},{"style":178},[7135],{"type":36,"value":2839},{"type":27,"tag":87,"props":7137,"children":7138},{"style":184},[7139],{"type":36,"value":5190},{"type":27,"tag":87,"props":7141,"children":7142},{"style":359},[7143],{"type":36,"value":5195},{"type":27,"tag":87,"props":7145,"children":7146},{"style":184},[7147],{"type":36,"value":5200},{"type":27,"tag":87,"props":7149,"children":7150},{"class":89,"line":314},[7151,7156,7160,7164,7168],{"type":27,"tag":87,"props":7152,"children":7153},{"style":184},[7154],{"type":36,"value":7155},"        SimpleThreadExample thread ",{"type":27,"tag":87,"props":7157,"children":7158},{"style":178},[7159],{"type":36,"value":325},{"type":27,"tag":87,"props":7161,"children":7162},{"style":178},[7163],{"type":36,"value":2052},{"type":27,"tag":87,"props":7165,"children":7166},{"style":94},[7167],{"type":36,"value":6985},{"type":27,"tag":87,"props":7169,"children":7170},{"style":184},[7171],{"type":36,"value":1686},{"type":27,"tag":87,"props":7173,"children":7174},{"class":89,"line":341},[7175,7180,7185],{"type":27,"tag":87,"props":7176,"children":7177},{"style":184},[7178],{"type":36,"value":7179},"        thread.",{"type":27,"tag":87,"props":7181,"children":7182},{"style":94},[7183],{"type":36,"value":7184},"start",{"type":27,"tag":87,"props":7186,"children":7187},{"style":184},[7188],{"type":36,"value":1686},{"type":27,"tag":87,"props":7190,"children":7191},{"class":89,"line":374},[7192],{"type":27,"tag":87,"props":7193,"children":7194},{"style":184},[7195],{"type":36,"value":5359},{"type":27,"tag":87,"props":7197,"children":7198},{"class":89,"line":699},[7199],{"type":27,"tag":87,"props":7200,"children":7201},{"style":184},[7202],{"type":36,"value":1805},{"type":27,"tag":2478,"props":7204,"children":7206},{"id":7205},"limitations-of-raw-threads",[7207],{"type":36,"value":7208},"Limitations of Raw Threads",{"type":27,"tag":46,"props":7210,"children":7211},{},[7212,7222,7232],{"type":27,"tag":50,"props":7213,"children":7214},{},[7215,7220],{"type":27,"tag":2410,"props":7216,"children":7217},{},[7218],{"type":36,"value":7219},"Performance Overhead",{"type":36,"value":7221},": Creating and destroying threads is expensive.",{"type":27,"tag":50,"props":7223,"children":7224},{},[7225,7230],{"type":27,"tag":2410,"props":7226,"children":7227},{},[7228],{"type":36,"value":7229},"No Pooling",{"type":36,"value":7231},": Each thread is a one-off. No built-in reuse.",{"type":27,"tag":50,"props":7233,"children":7234},{},[7235,7240],{"type":27,"tag":2410,"props":7236,"children":7237},{},[7238],{"type":36,"value":7239},"Scalability Issues",{"type":36,"value":7241},": System resources limit the number of threads you can create.",{"type":27,"tag":32,"props":7243,"children":7244},{},[7245],{"type":36,"value":7246},"Using raw threads for large-scale concurrent applications quickly becomes impractical.",{"type":27,"tag":39,"props":7248,"children":7250},{"id":7249},"modern-concurrency-executorservice-and-thread-pooling",[7251],{"type":36,"value":7252},"Modern Concurrency: ExecutorService and Thread Pooling",{"type":27,"tag":32,"props":7254,"children":7255},{},[7256,7258,7263,7265,7271],{"type":36,"value":7257},"To solve the limitations of raw threads, Java introduced the ",{"type":27,"tag":15,"props":7259,"children":7261},{"className":7260},[],[7262],{"type":36,"value":6929},{"type":36,"value":7264}," as part of ",{"type":27,"tag":15,"props":7266,"children":7268},{"className":7267},[],[7269],{"type":36,"value":7270},"java.util.concurrent",{"type":36,"value":7272},". It provides a high-level API to manage and reuse threads through pooling.",{"type":27,"tag":2478,"props":7274,"children":7276},{"id":7275},"how-thread-pooling-works",[7277],{"type":36,"value":7278},"How Thread Pooling Works",{"type":27,"tag":32,"props":7280,"children":7281},{},[7282],{"type":36,"value":7283},"Thread pooling allows you to reuse a fixed number of threads to execute multiple tasks. Instead of creating a new thread for each task, the executor assigns tasks to available worker threads in the pool.",{"type":27,"tag":77,"props":7285,"children":7287},{"className":1566,"code":7286,"language":1469,"meta":8,"style":8},"import java.util.concurrent.ExecutorService;\nimport java.util.concurrent.Executors;\n\npublic class ExecutorExample {\n    public static void main(String[] args) {\n        ExecutorService executor = Executors.newFixedThreadPool(3);\n        for (int i = 0; i \u003C 5; i++) {\n            executor.submit(() -> System.out.println(\"Task executed by: \" + Thread.currentThread().getName()));\n        }\n        executor.shutdown();\n    }\n}\n",[7288],{"type":27,"tag":15,"props":7289,"children":7290},{"__ignoreMap":8},[7291,7303,7315,7322,7342,7381,7416,7474,7536,7544,7561,7568],{"type":27,"tag":87,"props":7292,"children":7293},{"class":89,"line":90},[7294,7298],{"type":27,"tag":87,"props":7295,"children":7296},{"style":178},[7297],{"type":36,"value":192},{"type":27,"tag":87,"props":7299,"children":7300},{"style":184},[7301],{"type":36,"value":7302}," java.util.concurrent.ExecutorService;\n",{"type":27,"tag":87,"props":7304,"children":7305},{"class":89,"line":200},[7306,7310],{"type":27,"tag":87,"props":7307,"children":7308},{"style":178},[7309],{"type":36,"value":192},{"type":27,"tag":87,"props":7311,"children":7312},{"style":184},[7313],{"type":36,"value":7314}," java.util.concurrent.Executors;\n",{"type":27,"tag":87,"props":7316,"children":7317},{"class":89,"line":222},[7318],{"type":27,"tag":87,"props":7319,"children":7320},{"emptyLinePlaceholder":261},[7321],{"type":36,"value":264},{"type":27,"tag":87,"props":7323,"children":7324},{"class":89,"line":235},[7325,7329,7333,7338],{"type":27,"tag":87,"props":7326,"children":7327},{"style":178},[7328],{"type":36,"value":4594},{"type":27,"tag":87,"props":7330,"children":7331},{"style":178},[7332],{"type":36,"value":4609},{"type":27,"tag":87,"props":7334,"children":7335},{"style":94},[7336],{"type":36,"value":7337}," ExecutorExample",{"type":27,"tag":87,"props":7339,"children":7340},{"style":184},[7341],{"type":36,"value":4683},{"type":27,"tag":87,"props":7343,"children":7344},{"class":89,"line":257},[7345,7349,7353,7357,7361,7365,7369,7373,7377],{"type":27,"tag":87,"props":7346,"children":7347},{"style":178},[7348],{"type":36,"value":5162},{"type":27,"tag":87,"props":7350,"children":7351},{"style":178},[7352],{"type":36,"value":5167},{"type":27,"tag":87,"props":7354,"children":7355},{"style":178},[7356],{"type":36,"value":5172},{"type":27,"tag":87,"props":7358,"children":7359},{"style":94},[7360],{"type":36,"value":5177},{"type":27,"tag":87,"props":7362,"children":7363},{"style":184},[7364],{"type":36,"value":1282},{"type":27,"tag":87,"props":7366,"children":7367},{"style":178},[7368],{"type":36,"value":2839},{"type":27,"tag":87,"props":7370,"children":7371},{"style":184},[7372],{"type":36,"value":5190},{"type":27,"tag":87,"props":7374,"children":7375},{"style":359},[7376],{"type":36,"value":5195},{"type":27,"tag":87,"props":7378,"children":7379},{"style":184},[7380],{"type":36,"value":5200},{"type":27,"tag":87,"props":7382,"children":7383},{"class":89,"line":267},[7384,7389,7393,7398,7403,7407,7412],{"type":27,"tag":87,"props":7385,"children":7386},{"style":184},[7387],{"type":36,"value":7388},"        ExecutorService executor ",{"type":27,"tag":87,"props":7390,"children":7391},{"style":178},[7392],{"type":36,"value":325},{"type":27,"tag":87,"props":7394,"children":7395},{"style":184},[7396],{"type":36,"value":7397}," Executors.",{"type":27,"tag":87,"props":7399,"children":7400},{"style":94},[7401],{"type":36,"value":7402},"newFixedThreadPool",{"type":27,"tag":87,"props":7404,"children":7405},{"style":184},[7406],{"type":36,"value":1282},{"type":27,"tag":87,"props":7408,"children":7409},{"style":288},[7410],{"type":36,"value":7411},"3",{"type":27,"tag":87,"props":7413,"children":7414},{"style":184},[7415],{"type":36,"value":1607},{"type":27,"tag":87,"props":7417,"children":7418},{"class":89,"line":276},[7419,7423,7427,7432,7437,7441,7446,7451,7455,7460,7465,7470],{"type":27,"tag":87,"props":7420,"children":7421},{"style":178},[7422],{"type":36,"value":560},{"type":27,"tag":87,"props":7424,"children":7425},{"style":184},[7426],{"type":36,"value":624},{"type":27,"tag":87,"props":7428,"children":7429},{"style":178},[7430],{"type":36,"value":7431},"int",{"type":27,"tag":87,"props":7433,"children":7434},{"style":184},[7435],{"type":36,"value":7436}," i ",{"type":27,"tag":87,"props":7438,"children":7439},{"style":178},[7440],{"type":36,"value":325},{"type":27,"tag":87,"props":7442,"children":7443},{"style":288},[7444],{"type":36,"value":7445}," 0",{"type":27,"tag":87,"props":7447,"children":7448},{"style":184},[7449],{"type":36,"value":7450},"; i ",{"type":27,"tag":87,"props":7452,"children":7453},{"style":178},[7454],{"type":36,"value":2144},{"type":27,"tag":87,"props":7456,"children":7457},{"style":288},[7458],{"type":36,"value":7459}," 5",{"type":27,"tag":87,"props":7461,"children":7462},{"style":184},[7463],{"type":36,"value":7464},"; i",{"type":27,"tag":87,"props":7466,"children":7467},{"style":178},[7468],{"type":36,"value":7469},"++",{"type":27,"tag":87,"props":7471,"children":7472},{"style":184},[7473],{"type":36,"value":5200},{"type":27,"tag":87,"props":7475,"children":7476},{"class":89,"line":284},[7477,7482,7487,7491,7495,7499,7503,7507,7512,7516,7520,7524,7528,7532],{"type":27,"tag":87,"props":7478,"children":7479},{"style":184},[7480],{"type":36,"value":7481},"            executor.",{"type":27,"tag":87,"props":7483,"children":7484},{"style":94},[7485],{"type":36,"value":7486},"submit",{"type":27,"tag":87,"props":7488,"children":7489},{"style":184},[7490],{"type":36,"value":5236},{"type":27,"tag":87,"props":7492,"children":7493},{"style":178},[7494],{"type":36,"value":2867},{"type":27,"tag":87,"props":7496,"children":7497},{"style":184},[7498],{"type":36,"value":2962},{"type":27,"tag":87,"props":7500,"children":7501},{"style":94},[7502],{"type":36,"value":2967},{"type":27,"tag":87,"props":7504,"children":7505},{"style":184},[7506],{"type":36,"value":1282},{"type":27,"tag":87,"props":7508,"children":7509},{"style":100},[7510],{"type":36,"value":7511},"\"Task executed by: \"",{"type":27,"tag":87,"props":7513,"children":7514},{"style":178},[7515],{"type":36,"value":2981},{"type":27,"tag":87,"props":7517,"children":7518},{"style":184},[7519],{"type":36,"value":7048},{"type":27,"tag":87,"props":7521,"children":7522},{"style":94},[7523],{"type":36,"value":7053},{"type":27,"tag":87,"props":7525,"children":7526},{"style":184},[7527],{"type":36,"value":7058},{"type":27,"tag":87,"props":7529,"children":7530},{"style":94},[7531],{"type":36,"value":7063},{"type":27,"tag":87,"props":7533,"children":7534},{"style":184},[7535],{"type":36,"value":3091},{"type":27,"tag":87,"props":7537,"children":7538},{"class":89,"line":314},[7539],{"type":27,"tag":87,"props":7540,"children":7541},{"style":184},[7542],{"type":36,"value":7543},"        }\n",{"type":27,"tag":87,"props":7545,"children":7546},{"class":89,"line":341},[7547,7552,7557],{"type":27,"tag":87,"props":7548,"children":7549},{"style":184},[7550],{"type":36,"value":7551},"        executor.",{"type":27,"tag":87,"props":7553,"children":7554},{"style":94},[7555],{"type":36,"value":7556},"shutdown",{"type":27,"tag":87,"props":7558,"children":7559},{"style":184},[7560],{"type":36,"value":1686},{"type":27,"tag":87,"props":7562,"children":7563},{"class":89,"line":374},[7564],{"type":27,"tag":87,"props":7565,"children":7566},{"style":184},[7567],{"type":36,"value":5359},{"type":27,"tag":87,"props":7569,"children":7570},{"class":89,"line":699},[7571],{"type":27,"tag":87,"props":7572,"children":7573},{"style":184},[7574],{"type":36,"value":1805},{"type":27,"tag":2478,"props":7576,"children":7578},{"id":7577},"common-executor-types",[7579],{"type":36,"value":7580},"Common Executor Types:",{"type":27,"tag":46,"props":7582,"children":7583},{},[7584,7595,7606,7617],{"type":27,"tag":50,"props":7585,"children":7586},{},[7587,7593],{"type":27,"tag":15,"props":7588,"children":7590},{"className":7589},[],[7591],{"type":36,"value":7592},"newFixedThreadPool(n)",{"type":36,"value":7594},": Fixed number of threads.",{"type":27,"tag":50,"props":7596,"children":7597},{},[7598,7604],{"type":27,"tag":15,"props":7599,"children":7601},{"className":7600},[],[7602],{"type":36,"value":7603},"newCachedThreadPool()",{"type":36,"value":7605},": Dynamically creates threads as needed.",{"type":27,"tag":50,"props":7607,"children":7608},{},[7609,7615],{"type":27,"tag":15,"props":7610,"children":7612},{"className":7611},[],[7613],{"type":36,"value":7614},"newSingleThreadExecutor()",{"type":36,"value":7616},": One thread for all tasks.",{"type":27,"tag":50,"props":7618,"children":7619},{},[7620,7626],{"type":27,"tag":15,"props":7621,"children":7623},{"className":7622},[],[7624],{"type":36,"value":7625},"newScheduledThreadPool(n)",{"type":36,"value":7627},": Supports delayed and periodic tasks.",{"type":27,"tag":2478,"props":7629,"children":7631},{"id":7630},"advantages",[7632],{"type":36,"value":7633},"Advantages:",{"type":27,"tag":46,"props":7635,"children":7636},{},[7637,7642,7647],{"type":27,"tag":50,"props":7638,"children":7639},{},[7640],{"type":36,"value":7641},"Efficient resource use through reuse.",{"type":27,"tag":50,"props":7643,"children":7644},{},[7645],{"type":36,"value":7646},"Better scalability and responsiveness.",{"type":27,"tag":50,"props":7648,"children":7649},{},[7650],{"type":36,"value":7651},"Built-in management of task queues and error handling.",{"type":27,"tag":39,"props":7653,"children":7655},{"id":7654},"the-future-virtual-threads-and-project-loom",[7656],{"type":36,"value":7657},"The Future: Virtual Threads and Project Loom",{"type":27,"tag":32,"props":7659,"children":7660},{},[7661],{"type":36,"value":7662},"Java 21 introduces Virtual Threads, a lightweight and scalable alternative to platform threads. A virtual thread is managed by the Java runtime rather than the operating system, allowing millions of threads to coexist.",{"type":27,"tag":2478,"props":7664,"children":7666},{"id":7665},"key-features",[7667],{"type":36,"value":7668},"Key Features:",{"type":27,"tag":46,"props":7670,"children":7671},{},[7672,7682,7692],{"type":27,"tag":50,"props":7673,"children":7674},{},[7675,7680],{"type":27,"tag":2410,"props":7676,"children":7677},{},[7678],{"type":36,"value":7679},"Minimal Memory Footprint",{"type":36,"value":7681},": Much lighter than traditional threads.",{"type":27,"tag":50,"props":7683,"children":7684},{},[7685,7690],{"type":27,"tag":2410,"props":7686,"children":7687},{},[7688],{"type":36,"value":7689},"Unblocked I/O",{"type":36,"value":7691},": I/O operations don’t block the underlying platform thread.",{"type":27,"tag":50,"props":7693,"children":7694},{},[7695,7700],{"type":27,"tag":2410,"props":7696,"children":7697},{},[7698],{"type":36,"value":7699},"Massive Scalability",{"type":36,"value":7701},": Suitable for applications requiring thousands or millions of concurrent tasks (e.g., web servers).",{"type":27,"tag":32,"props":7703,"children":7704},{},[7705],{"type":36,"value":7706},"Example:",{"type":27,"tag":77,"props":7708,"children":7710},{"className":1566,"code":7709,"language":1469,"meta":8,"style":8},"public class VirtualThreadExample {\n    public static void main(String[] args) {\n        try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {\n            for (int i = 0; i \u003C 10; i++) {\n                executor.submit(() -> {\n                    System.out.println(\"Running in: \" + Thread.currentThread().getName());\n                });\n            }\n        }\n    }\n}\n",[7711],{"type":27,"tag":15,"props":7712,"children":7713},{"__ignoreMap":8},[7714,7734,7773,7812,7865,7889,7934,7942,7950,7957,7964],{"type":27,"tag":87,"props":7715,"children":7716},{"class":89,"line":90},[7717,7721,7725,7730],{"type":27,"tag":87,"props":7718,"children":7719},{"style":178},[7720],{"type":36,"value":4594},{"type":27,"tag":87,"props":7722,"children":7723},{"style":178},[7724],{"type":36,"value":4609},{"type":27,"tag":87,"props":7726,"children":7727},{"style":94},[7728],{"type":36,"value":7729}," VirtualThreadExample",{"type":27,"tag":87,"props":7731,"children":7732},{"style":184},[7733],{"type":36,"value":4683},{"type":27,"tag":87,"props":7735,"children":7736},{"class":89,"line":200},[7737,7741,7745,7749,7753,7757,7761,7765,7769],{"type":27,"tag":87,"props":7738,"children":7739},{"style":178},[7740],{"type":36,"value":5162},{"type":27,"tag":87,"props":7742,"children":7743},{"style":178},[7744],{"type":36,"value":5167},{"type":27,"tag":87,"props":7746,"children":7747},{"style":178},[7748],{"type":36,"value":5172},{"type":27,"tag":87,"props":7750,"children":7751},{"style":94},[7752],{"type":36,"value":5177},{"type":27,"tag":87,"props":7754,"children":7755},{"style":184},[7756],{"type":36,"value":1282},{"type":27,"tag":87,"props":7758,"children":7759},{"style":178},[7760],{"type":36,"value":2839},{"type":27,"tag":87,"props":7762,"children":7763},{"style":184},[7764],{"type":36,"value":5190},{"type":27,"tag":87,"props":7766,"children":7767},{"style":359},[7768],{"type":36,"value":5195},{"type":27,"tag":87,"props":7770,"children":7771},{"style":184},[7772],{"type":36,"value":5200},{"type":27,"tag":87,"props":7774,"children":7775},{"class":89,"line":222},[7776,7780,7784,7789,7794,7798,7802,7807],{"type":27,"tag":87,"props":7777,"children":7778},{"style":178},[7779],{"type":36,"value":5409},{"type":27,"tag":87,"props":7781,"children":7782},{"style":184},[7783],{"type":36,"value":624},{"type":27,"tag":87,"props":7785,"children":7786},{"style":178},[7787],{"type":36,"value":7788},"var",{"type":27,"tag":87,"props":7790,"children":7791},{"style":184},[7792],{"type":36,"value":7793}," executor ",{"type":27,"tag":87,"props":7795,"children":7796},{"style":178},[7797],{"type":36,"value":325},{"type":27,"tag":87,"props":7799,"children":7800},{"style":184},[7801],{"type":36,"value":7397},{"type":27,"tag":87,"props":7803,"children":7804},{"style":94},[7805],{"type":36,"value":7806},"newVirtualThreadPerTaskExecutor",{"type":27,"tag":87,"props":7808,"children":7809},{"style":184},[7810],{"type":36,"value":7811},"()) {\n",{"type":27,"tag":87,"props":7813,"children":7814},{"class":89,"line":235},[7815,7820,7824,7828,7832,7836,7840,7844,7848,7853,7857,7861],{"type":27,"tag":87,"props":7816,"children":7817},{"style":178},[7818],{"type":36,"value":7819},"            for",{"type":27,"tag":87,"props":7821,"children":7822},{"style":184},[7823],{"type":36,"value":624},{"type":27,"tag":87,"props":7825,"children":7826},{"style":178},[7827],{"type":36,"value":7431},{"type":27,"tag":87,"props":7829,"children":7830},{"style":184},[7831],{"type":36,"value":7436},{"type":27,"tag":87,"props":7833,"children":7834},{"style":178},[7835],{"type":36,"value":325},{"type":27,"tag":87,"props":7837,"children":7838},{"style":288},[7839],{"type":36,"value":7445},{"type":27,"tag":87,"props":7841,"children":7842},{"style":184},[7843],{"type":36,"value":7450},{"type":27,"tag":87,"props":7845,"children":7846},{"style":178},[7847],{"type":36,"value":2144},{"type":27,"tag":87,"props":7849,"children":7850},{"style":288},[7851],{"type":36,"value":7852}," 10",{"type":27,"tag":87,"props":7854,"children":7855},{"style":184},[7856],{"type":36,"value":7464},{"type":27,"tag":87,"props":7858,"children":7859},{"style":178},[7860],{"type":36,"value":7469},{"type":27,"tag":87,"props":7862,"children":7863},{"style":184},[7864],{"type":36,"value":5200},{"type":27,"tag":87,"props":7866,"children":7867},{"class":89,"line":257},[7868,7873,7877,7881,7885],{"type":27,"tag":87,"props":7869,"children":7870},{"style":184},[7871],{"type":36,"value":7872},"                executor.",{"type":27,"tag":87,"props":7874,"children":7875},{"style":94},[7876],{"type":36,"value":7486},{"type":27,"tag":87,"props":7878,"children":7879},{"style":184},[7880],{"type":36,"value":5236},{"type":27,"tag":87,"props":7882,"children":7883},{"style":178},[7884],{"type":36,"value":2867},{"type":27,"tag":87,"props":7886,"children":7887},{"style":184},[7888],{"type":36,"value":4683},{"type":27,"tag":87,"props":7890,"children":7891},{"class":89,"line":267},[7892,7897,7901,7905,7910,7914,7918,7922,7926,7930],{"type":27,"tag":87,"props":7893,"children":7894},{"style":184},[7895],{"type":36,"value":7896},"                    System.out.",{"type":27,"tag":87,"props":7898,"children":7899},{"style":94},[7900],{"type":36,"value":2967},{"type":27,"tag":87,"props":7902,"children":7903},{"style":184},[7904],{"type":36,"value":1282},{"type":27,"tag":87,"props":7906,"children":7907},{"style":100},[7908],{"type":36,"value":7909},"\"Running in: \"",{"type":27,"tag":87,"props":7911,"children":7912},{"style":178},[7913],{"type":36,"value":2981},{"type":27,"tag":87,"props":7915,"children":7916},{"style":184},[7917],{"type":36,"value":7048},{"type":27,"tag":87,"props":7919,"children":7920},{"style":94},[7921],{"type":36,"value":7053},{"type":27,"tag":87,"props":7923,"children":7924},{"style":184},[7925],{"type":36,"value":7058},{"type":27,"tag":87,"props":7927,"children":7928},{"style":94},[7929],{"type":36,"value":7063},{"type":27,"tag":87,"props":7931,"children":7932},{"style":184},[7933],{"type":36,"value":1765},{"type":27,"tag":87,"props":7935,"children":7936},{"class":89,"line":276},[7937],{"type":27,"tag":87,"props":7938,"children":7939},{"style":184},[7940],{"type":36,"value":7941},"                });\n",{"type":27,"tag":87,"props":7943,"children":7944},{"class":89,"line":284},[7945],{"type":27,"tag":87,"props":7946,"children":7947},{"style":184},[7948],{"type":36,"value":7949},"            }\n",{"type":27,"tag":87,"props":7951,"children":7952},{"class":89,"line":314},[7953],{"type":27,"tag":87,"props":7954,"children":7955},{"style":184},[7956],{"type":36,"value":7543},{"type":27,"tag":87,"props":7958,"children":7959},{"class":89,"line":341},[7960],{"type":27,"tag":87,"props":7961,"children":7962},{"style":184},[7963],{"type":36,"value":5359},{"type":27,"tag":87,"props":7965,"children":7966},{"class":89,"line":374},[7967],{"type":27,"tag":87,"props":7968,"children":7969},{"style":184},[7970],{"type":36,"value":1805},{"type":27,"tag":2478,"props":7972,"children":7974},{"id":7973},"when-to-use-virtual-threads",[7975],{"type":36,"value":7976},"When to Use Virtual Threads:",{"type":27,"tag":46,"props":7978,"children":7979},{},[7980,7985,7990],{"type":27,"tag":50,"props":7981,"children":7982},{},[7983],{"type":36,"value":7984},"I/O-bound applications (e.g., database access, HTTP clients).",{"type":27,"tag":50,"props":7986,"children":7987},{},[7988],{"type":36,"value":7989},"High-concurrency workloads (e.g., messaging systems).",{"type":27,"tag":50,"props":7991,"children":7992},{},[7993],{"type":36,"value":7994},"When simplifying thread management is a priority.",{"type":27,"tag":39,"props":7996,"children":7997},{"id":2304},[7998],{"type":36,"value":2307},{"type":27,"tag":32,"props":8000,"children":8001},{},[8002],{"type":36,"value":8003},"Java offers a flexible and powerful concurrency model. Classic Threads provide a foundational understanding, ExecutorService enables efficient thread reuse and task management, and Virtual Threads open the door to a new era of scalable concurrency with minimal overhead.",{"type":27,"tag":32,"props":8005,"children":8006},{},[8007],{"type":36,"value":8008},"Each model has its place depending on the problem at hand. Mastering them gives you the toolkit needed to build high-performance, concurrent applications.",{"type":27,"tag":39,"props":8010,"children":8011},{"id":2315},[8012],{"type":36,"value":2318},{"type":27,"tag":46,"props":8014,"children":8015},{},[8016,8026,8036,8045],{"type":27,"tag":50,"props":8017,"children":8018},{},[8019],{"type":27,"tag":1410,"props":8020,"children":8023},{"href":8021,"rel":8022},"https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/package-summary.html",[1414],[8024],{"type":36,"value":8025},"Java Concurrency API",{"type":27,"tag":50,"props":8027,"children":8028},{},[8029],{"type":27,"tag":1410,"props":8030,"children":8033},{"href":8031,"rel":8032},"https://openjdk.org/projects/loom/",[1414],[8034],{"type":36,"value":8035},"Project Loom (Virtual Threads)",{"type":27,"tag":50,"props":8037,"children":8038},{},[8039],{"type":27,"tag":1410,"props":8040,"children":8043},{"href":8041,"rel":8042},"https://docs.oracle.com/javase/tutorial/essential/concurrency/forkjoin.html",[1414],[8044],{"type":36,"value":6906},{"type":27,"tag":50,"props":8046,"children":8047},{},[8048],{"type":27,"tag":1410,"props":8049,"children":8052},{"href":8050,"rel":8051},"https://www.oreilly.com/library/view/effective-java-3rd/9780134686097/",[1414],[8053],{"type":36,"value":8054},"Effective Java - Joshua Bloch",{"type":27,"tag":32,"props":8056,"children":8057},{},[8058],{"type":36,"value":8059},"Deep understanding of Java's concurrency tools can significantly improve your system’s performance, scalability, and maintainability.",{"type":27,"tag":1439,"props":8061,"children":8062},{},[8063],{"type":36,"value":1443},{"title":8,"searchDepth":200,"depth":200,"links":8065},[8066,8067,8070,8075,8079,8080],{"id":6857,"depth":200,"text":6860},{"id":6934,"depth":200,"text":6937,"children":8068},[8069],{"id":7205,"depth":222,"text":7208},{"id":7249,"depth":200,"text":7252,"children":8071},[8072,8073,8074],{"id":7275,"depth":222,"text":7278},{"id":7577,"depth":222,"text":7580},{"id":7630,"depth":222,"text":7633},{"id":7654,"depth":200,"text":7657,"children":8076},[8077,8078],{"id":7665,"depth":222,"text":7668},{"id":7973,"depth":222,"text":7976},{"id":2304,"depth":200,"text":2307},{"id":2315,"depth":200,"text":2318},"content:posts:mastering-concurrency.md","posts/mastering-concurrency.md","posts/mastering-concurrency",{"_path":8085,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":8086,"description":8087,"date":8088,"layout":12,"subtitle":8089,"image":8090,"optimized_image":8090,"category":15,"tags":8091,"author":22,"paginate":7,"body":8095,"_type":1455,"_id":8261,"_source":1457,"_file":8262,"_stem":8263,"_extension":1460},"/posts/microservices-mistakes","Common Mistakes When Developing Microservices","A guide on the most frequent mistakes made when developing microservices, with practical examples.","2024-02-15T11:00:00.000Z","Avoid pitfalls and build robust microservices","/assets/img/uploads/microservices.jpg",[15,8092,8093,8094],"microservices","architecture","best practices",{"type":24,"children":8096,"toc":8253},[8097,8105,8111,8116,8126,8132,8137,8146,8152,8157,8166,8172,8177,8186,8192,8197,8206,8210,8215,8248],{"type":27,"tag":28,"props":8098,"children":8099},{},[8100],{"type":27,"tag":32,"props":8101,"children":8102},{},[8103],{"type":36,"value":8104},"Developing microservices can provide significant advantages such as scalability, flexibility, and rapid deployment. However, the journey to a microservice architecture is filled with potential pitfalls. In this post, we'll explore 5 common mistakes to avoid when developing microservices.",{"type":27,"tag":39,"props":8106,"children":8108},{"id":8107},"_1-highly-coupled-services",[8109],{"type":36,"value":8110},"1. Highly Coupled Services",{"type":27,"tag":32,"props":8112,"children":8113},{},[8114],{"type":36,"value":8115},"One common mistake is creating tightly coupled microservices, which undermines independence and complicates deployment and updates.",{"type":27,"tag":32,"props":8117,"children":8118},{},[8119,8124],{"type":27,"tag":2410,"props":8120,"children":8121},{},[8122],{"type":36,"value":8123},"Example",{"type":36,"value":8125},": Using a shared library across multiple microservices might initially seem efficient. However, when the library evolves, every microservice depending on it must be updated and redeployed simultaneously, resulting in complex coordination and loss of service independence.",{"type":27,"tag":39,"props":8127,"children":8129},{"id":8128},"_2-ignoring-error-handling-and-resilience",[8130],{"type":36,"value":8131},"2. Ignoring Error Handling and Resilience",{"type":27,"tag":32,"props":8133,"children":8134},{},[8135],{"type":36,"value":8136},"Failures are inevitable in distributed architectures. A frequent error is neglecting robust error handling, automatic retries, circuit breakers, or fallback patterns. Resilience is crucial to preventing cascading failures.",{"type":27,"tag":32,"props":8138,"children":8139},{},[8140,8144],{"type":27,"tag":2410,"props":8141,"children":8142},{},[8143],{"type":36,"value":8123},{"type":36,"value":8145},": If a critical payment microservice fails without proper resilience measures, it could halt the entire purchasing flow, negatively impacting user experience and causing economic losses.",{"type":27,"tag":39,"props":8147,"children":8149},{"id":8148},"_3-inadequate-monitoring",[8150],{"type":36,"value":8151},"3. Inadequate Monitoring",{"type":27,"tag":32,"props":8153,"children":8154},{},[8155],{"type":36,"value":8156},"Visibility is crucial in distributed systems. Without a clear monitoring and observability strategy (centralized logs, metrics, and distributed tracing), it's difficult to detect problems early or perform effective diagnostics.",{"type":27,"tag":32,"props":8158,"children":8159},{},[8160,8164],{"type":27,"tag":2410,"props":8161,"children":8162},{},[8163],{"type":36,"value":8123},{"type":36,"value":8165},": A performance degradation in one microservice without centralized metrics and tracing could lead to hours wasted trying to pinpoint the specific service causing the bottleneck.",{"type":27,"tag":39,"props":8167,"children":8169},{"id":8168},"_4-deploying-microservices-without-automation",[8170],{"type":36,"value":8171},"4. Deploying Microservices Without Automation",{"type":27,"tag":32,"props":8173,"children":8174},{},[8175],{"type":36,"value":8176},"Rapid and flexible deployment is a significant advantage of microservices, but many teams mistakenly fail to automate these processes early, leading to human errors, inconsistent configurations, and scalability issues. Prioritizing automation with CI/CD is essential.",{"type":27,"tag":32,"props":8178,"children":8179},{},[8180,8184],{"type":27,"tag":2410,"props":8181,"children":8182},{},[8183],{"type":36,"value":8123},{"type":36,"value":8185},": Repeated manual deployments can lead to frequent human errors, such as incorrect configurations that cause hard-to-detect production issues.",{"type":27,"tag":39,"props":8187,"children":8189},{"id":8188},"_5-overly-fragmented-microservices",[8190],{"type":36,"value":8191},"5. Overly Fragmented Microservices",{"type":27,"tag":32,"props":8193,"children":8194},{},[8195],{"type":36,"value":8196},"Excessively splitting an application into very small microservices can create more problems than it solves. Microservices should align clearly with business domains and values, avoiding excessive fragmentation that complicates management and operation.",{"type":27,"tag":32,"props":8198,"children":8199},{},[8200,8204],{"type":27,"tag":2410,"props":8201,"children":8202},{},[8203],{"type":36,"value":8123},{"type":36,"value":8205},": Creating separate microservices for every minor function, such as managing a simple form or validating an input, can result in significant operational overhead with minimal scalability or performance benefits.",{"type":27,"tag":39,"props":8207,"children":8208},{"id":2315},[8209],{"type":36,"value":2318},{"type":27,"tag":32,"props":8211,"children":8212},{},[8213],{"type":36,"value":8214},"To deepen your understanding of microservices, consider exploring the following resources:",{"type":27,"tag":46,"props":8216,"children":8217},{},[8218,8228,8238],{"type":27,"tag":50,"props":8219,"children":8220},{},[8221],{"type":27,"tag":1410,"props":8222,"children":8225},{"href":8223,"rel":8224},"https://microservices.io/book",[1414],[8226],{"type":36,"value":8227},"Building Microservices - Sam Newman",{"type":27,"tag":50,"props":8229,"children":8230},{},[8231],{"type":27,"tag":1410,"props":8232,"children":8235},{"href":8233,"rel":8234},"https://martinfowler.com/microservices/",[1414],[8236],{"type":36,"value":8237},"Microservices Patterns - Chris Richardson",{"type":27,"tag":50,"props":8239,"children":8240},{},[8241],{"type":27,"tag":1410,"props":8242,"children":8245},{"href":8243,"rel":8244},"https://samnewman.io/books/building_microservices/",[1414],[8246],{"type":36,"value":8247},"Martin Fowler - Microservices Resource Guide",{"type":27,"tag":32,"props":8249,"children":8250},{},[8251],{"type":36,"value":8252},"Mastering these concepts will help you design and maintain robust, scalable, and effective microservice architectures.",{"title":8,"searchDepth":200,"depth":200,"links":8254},[8255,8256,8257,8258,8259,8260],{"id":8107,"depth":200,"text":8110},{"id":8128,"depth":200,"text":8131},{"id":8148,"depth":200,"text":8151},{"id":8168,"depth":200,"text":8171},{"id":8188,"depth":200,"text":8191},{"id":2315,"depth":200,"text":2318},"content:posts:microservices-mistakes.md","posts/microservices-mistakes.md","posts/microservices-mistakes",{"_path":8265,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":8266,"description":8267,"date":8268,"layout":12,"subtitle":8269,"image":8270,"optimized_image":8270,"category":15,"tags":8271,"author":22,"paginate":7,"body":8274,"_type":1455,"_id":9280,"_source":1457,"_file":9281,"_stem":9282,"_extension":1460},"/posts/tdd-testing","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","Writing Better Code with Automated Testing","/assets/img/uploads/tdd-java.png",[15,1469,8272,8273],"testing","tdd",{"type":24,"children":8275,"toc":9273},[8276,8284,8290,8295,8313,8318,8324,8332,8337,8342,8523,8531,8536,8541,8808,8814,8819,9030,9035,9208,9213,9217,9222,9226,9231,9264,9269],{"type":27,"tag":28,"props":8277,"children":8278},{},[8279],{"type":27,"tag":32,"props":8280,"children":8281},{},[8282],{"type":36,"value":8283},"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":27,"tag":39,"props":8285,"children":8287},{"id":8286},"what-is-tdd",[8288],{"type":36,"value":8289},"What is TDD?",{"type":27,"tag":32,"props":8291,"children":8292},{},[8293],{"type":36,"value":8294},"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":27,"tag":46,"props":8296,"children":8297},{},[8298,8303,8308],{"type":27,"tag":50,"props":8299,"children":8300},{},[8301],{"type":36,"value":8302},"Red: Write a test that fails (since the functionality is not yet implemented).",{"type":27,"tag":50,"props":8304,"children":8305},{},[8306],{"type":36,"value":8307},"Green: Write the minimal code required to pass the test.",{"type":27,"tag":50,"props":8309,"children":8310},{},[8311],{"type":36,"value":8312},"Refactor: Improve the code while ensuring the test still passes.",{"type":27,"tag":32,"props":8314,"children":8315},{},[8316],{"type":36,"value":8317},"This approach ensures that each piece of code is tested, making maintenance easier and reducing the likelihood of errors.",{"type":27,"tag":39,"props":8319,"children":8321},{"id":8320},"introduction-to-junit-and-mockito",[8322],{"type":36,"value":8323},"Introduction to JUnit and Mockito",{"type":27,"tag":32,"props":8325,"children":8326},{},[8327],{"type":27,"tag":2410,"props":8328,"children":8329},{},[8330],{"type":36,"value":8331},"JUnit",{"type":27,"tag":32,"props":8333,"children":8334},{},[8335],{"type":36,"value":8336},"JUnit is the most widely used unit testing framework in Java. It allows developers to write and execute automated tests efficiently.",{"type":27,"tag":32,"props":8338,"children":8339},{},[8340],{"type":36,"value":8341},"Example of a simple test with JUnit 5:",{"type":27,"tag":77,"props":8343,"children":8345},{"className":1566,"code":8344,"language":1469,"meta":8,"style":8},"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",[8346],{"type":27,"tag":15,"props":8347,"children":8348},{"__ignoreMap":8},[8349,8361,8385,8392,8408,8421,8438,8463,8509,8516],{"type":27,"tag":87,"props":8350,"children":8351},{"class":89,"line":90},[8352,8356],{"type":27,"tag":87,"props":8353,"children":8354},{"style":178},[8355],{"type":36,"value":192},{"type":27,"tag":87,"props":8357,"children":8358},{"style":184},[8359],{"type":36,"value":8360}," org.junit.jupiter.api.Test;\n",{"type":27,"tag":87,"props":8362,"children":8363},{"class":89,"line":200},[8364,8368,8372,8377,8381],{"type":27,"tag":87,"props":8365,"children":8366},{"style":178},[8367],{"type":36,"value":192},{"type":27,"tag":87,"props":8369,"children":8370},{"style":178},[8371],{"type":36,"value":5167},{"type":27,"tag":87,"props":8373,"children":8374},{"style":184},[8375],{"type":36,"value":8376}," org.junit.jupiter.api.Assertions.",{"type":27,"tag":87,"props":8378,"children":8379},{"style":288},[8380],{"type":36,"value":4858},{"type":27,"tag":87,"props":8382,"children":8383},{"style":184},[8384],{"type":36,"value":4288},{"type":27,"tag":87,"props":8386,"children":8387},{"class":89,"line":222},[8388],{"type":27,"tag":87,"props":8389,"children":8390},{"emptyLinePlaceholder":261},[8391],{"type":36,"value":264},{"type":27,"tag":87,"props":8393,"children":8394},{"class":89,"line":235},[8395,8399,8404],{"type":27,"tag":87,"props":8396,"children":8397},{"style":178},[8398],{"type":36,"value":6980},{"type":27,"tag":87,"props":8400,"children":8401},{"style":94},[8402],{"type":36,"value":8403}," CalculatorTest",{"type":27,"tag":87,"props":8405,"children":8406},{"style":184},[8407],{"type":36,"value":4683},{"type":27,"tag":87,"props":8409,"children":8410},{"class":89,"line":257},[8411,8416],{"type":27,"tag":87,"props":8412,"children":8413},{"style":184},[8414],{"type":36,"value":8415},"    @",{"type":27,"tag":87,"props":8417,"children":8418},{"style":178},[8419],{"type":36,"value":8420},"Test\n",{"type":27,"tag":87,"props":8422,"children":8423},{"class":89,"line":267},[8424,8429,8434],{"type":27,"tag":87,"props":8425,"children":8426},{"style":178},[8427],{"type":36,"value":8428},"    void",{"type":27,"tag":87,"props":8430,"children":8431},{"style":94},[8432],{"type":36,"value":8433}," testSum",{"type":27,"tag":87,"props":8435,"children":8436},{"style":184},[8437],{"type":36,"value":7019},{"type":27,"tag":87,"props":8439,"children":8440},{"class":89,"line":276},[8441,8446,8450,8454,8459],{"type":27,"tag":87,"props":8442,"children":8443},{"style":184},[8444],{"type":36,"value":8445},"        Calculator calc ",{"type":27,"tag":87,"props":8447,"children":8448},{"style":178},[8449],{"type":36,"value":325},{"type":27,"tag":87,"props":8451,"children":8452},{"style":178},[8453],{"type":36,"value":2052},{"type":27,"tag":87,"props":8455,"children":8456},{"style":94},[8457],{"type":36,"value":8458}," Calculator",{"type":27,"tag":87,"props":8460,"children":8461},{"style":184},[8462],{"type":36,"value":1686},{"type":27,"tag":87,"props":8464,"children":8465},{"class":89,"line":284},[8466,8471,8475,8479,8484,8489,8493,8497,8501,8505],{"type":27,"tag":87,"props":8467,"children":8468},{"style":94},[8469],{"type":36,"value":8470},"        assertEquals",{"type":27,"tag":87,"props":8472,"children":8473},{"style":184},[8474],{"type":36,"value":1282},{"type":27,"tag":87,"props":8476,"children":8477},{"style":288},[8478],{"type":36,"value":2745},{"type":27,"tag":87,"props":8480,"children":8481},{"style":184},[8482],{"type":36,"value":8483},", calc.",{"type":27,"tag":87,"props":8485,"children":8486},{"style":94},[8487],{"type":36,"value":8488},"add",{"type":27,"tag":87,"props":8490,"children":8491},{"style":184},[8492],{"type":36,"value":1282},{"type":27,"tag":87,"props":8494,"children":8495},{"style":288},[8496],{"type":36,"value":1654},{"type":27,"tag":87,"props":8498,"children":8499},{"style":184},[8500],{"type":36,"value":917},{"type":27,"tag":87,"props":8502,"children":8503},{"style":288},[8504],{"type":36,"value":7411},{"type":27,"tag":87,"props":8506,"children":8507},{"style":184},[8508],{"type":36,"value":2085},{"type":27,"tag":87,"props":8510,"children":8511},{"class":89,"line":314},[8512],{"type":27,"tag":87,"props":8513,"children":8514},{"style":184},[8515],{"type":36,"value":5359},{"type":27,"tag":87,"props":8517,"children":8518},{"class":89,"line":341},[8519],{"type":27,"tag":87,"props":8520,"children":8521},{"style":184},[8522],{"type":36,"value":1805},{"type":27,"tag":32,"props":8524,"children":8525},{},[8526],{"type":27,"tag":2410,"props":8527,"children":8528},{},[8529],{"type":36,"value":8530},"Mockito",{"type":27,"tag":32,"props":8532,"children":8533},{},[8534],{"type":36,"value":8535},"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":27,"tag":32,"props":8537,"children":8538},{},[8539],{"type":36,"value":8540},"Example using Mockito:",{"type":27,"tag":77,"props":8542,"children":8544},{"className":1566,"code":8543,"language":1469,"meta":8,"style":8},"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",[8545],{"type":27,"tag":15,"props":8546,"children":8547},{"__ignoreMap":8},[8548,8559,8571,8595,8618,8625,8641,8652,8668,8690,8731,8739,8765,8794,8801],{"type":27,"tag":87,"props":8549,"children":8550},{"class":89,"line":90},[8551,8555],{"type":27,"tag":87,"props":8552,"children":8553},{"style":178},[8554],{"type":36,"value":192},{"type":27,"tag":87,"props":8556,"children":8557},{"style":184},[8558],{"type":36,"value":8360},{"type":27,"tag":87,"props":8560,"children":8561},{"class":89,"line":200},[8562,8566],{"type":27,"tag":87,"props":8563,"children":8564},{"style":178},[8565],{"type":36,"value":192},{"type":27,"tag":87,"props":8567,"children":8568},{"style":184},[8569],{"type":36,"value":8570}," org.mockito.Mockito;\n",{"type":27,"tag":87,"props":8572,"children":8573},{"class":89,"line":222},[8574,8578,8582,8587,8591],{"type":27,"tag":87,"props":8575,"children":8576},{"style":178},[8577],{"type":36,"value":192},{"type":27,"tag":87,"props":8579,"children":8580},{"style":178},[8581],{"type":36,"value":5167},{"type":27,"tag":87,"props":8583,"children":8584},{"style":184},[8585],{"type":36,"value":8586}," org.mockito.Mockito.",{"type":27,"tag":87,"props":8588,"children":8589},{"style":288},[8590],{"type":36,"value":4858},{"type":27,"tag":87,"props":8592,"children":8593},{"style":184},[8594],{"type":36,"value":4288},{"type":27,"tag":87,"props":8596,"children":8597},{"class":89,"line":235},[8598,8602,8606,8610,8614],{"type":27,"tag":87,"props":8599,"children":8600},{"style":178},[8601],{"type":36,"value":192},{"type":27,"tag":87,"props":8603,"children":8604},{"style":178},[8605],{"type":36,"value":5167},{"type":27,"tag":87,"props":8607,"children":8608},{"style":184},[8609],{"type":36,"value":8376},{"type":27,"tag":87,"props":8611,"children":8612},{"style":288},[8613],{"type":36,"value":4858},{"type":27,"tag":87,"props":8615,"children":8616},{"style":184},[8617],{"type":36,"value":4288},{"type":27,"tag":87,"props":8619,"children":8620},{"class":89,"line":257},[8621],{"type":27,"tag":87,"props":8622,"children":8623},{"emptyLinePlaceholder":261},[8624],{"type":36,"value":264},{"type":27,"tag":87,"props":8626,"children":8627},{"class":89,"line":267},[8628,8632,8637],{"type":27,"tag":87,"props":8629,"children":8630},{"style":178},[8631],{"type":36,"value":6980},{"type":27,"tag":87,"props":8633,"children":8634},{"style":94},[8635],{"type":36,"value":8636}," ServiceTest",{"type":27,"tag":87,"props":8638,"children":8639},{"style":184},[8640],{"type":36,"value":4683},{"type":27,"tag":87,"props":8642,"children":8643},{"class":89,"line":276},[8644,8648],{"type":27,"tag":87,"props":8645,"children":8646},{"style":184},[8647],{"type":36,"value":8415},{"type":27,"tag":87,"props":8649,"children":8650},{"style":178},[8651],{"type":36,"value":8420},{"type":27,"tag":87,"props":8653,"children":8654},{"class":89,"line":284},[8655,8659,8664],{"type":27,"tag":87,"props":8656,"children":8657},{"style":178},[8658],{"type":36,"value":8428},{"type":27,"tag":87,"props":8660,"children":8661},{"style":94},[8662],{"type":36,"value":8663}," testService",{"type":27,"tag":87,"props":8665,"children":8666},{"style":184},[8667],{"type":36,"value":7019},{"type":27,"tag":87,"props":8669,"children":8670},{"class":89,"line":314},[8671,8676,8680,8685],{"type":27,"tag":87,"props":8672,"children":8673},{"style":184},[8674],{"type":36,"value":8675},"        ExternalService serviceMock ",{"type":27,"tag":87,"props":8677,"children":8678},{"style":178},[8679],{"type":36,"value":325},{"type":27,"tag":87,"props":8681,"children":8682},{"style":94},[8683],{"type":36,"value":8684}," mock",{"type":27,"tag":87,"props":8686,"children":8687},{"style":184},[8688],{"type":36,"value":8689},"(ExternalService.class);\n",{"type":27,"tag":87,"props":8691,"children":8692},{"class":89,"line":341},[8693,8698,8703,8708,8713,8718,8722,8727],{"type":27,"tag":87,"props":8694,"children":8695},{"style":94},[8696],{"type":36,"value":8697},"        when",{"type":27,"tag":87,"props":8699,"children":8700},{"style":184},[8701],{"type":36,"value":8702},"(serviceMock.",{"type":27,"tag":87,"props":8704,"children":8705},{"style":94},[8706],{"type":36,"value":8707},"getData",{"type":27,"tag":87,"props":8709,"children":8710},{"style":184},[8711],{"type":36,"value":8712},"()).",{"type":27,"tag":87,"props":8714,"children":8715},{"style":94},[8716],{"type":36,"value":8717},"thenReturn",{"type":27,"tag":87,"props":8719,"children":8720},{"style":184},[8721],{"type":36,"value":1282},{"type":27,"tag":87,"props":8723,"children":8724},{"style":100},[8725],{"type":36,"value":8726},"\"Mocked data\"",{"type":27,"tag":87,"props":8728,"children":8729},{"style":184},[8730],{"type":36,"value":1607},{"type":27,"tag":87,"props":8732,"children":8733},{"class":89,"line":374},[8734],{"type":27,"tag":87,"props":8735,"children":8736},{"style":184},[8737],{"type":36,"value":8738},"        \n",{"type":27,"tag":87,"props":8740,"children":8741},{"class":89,"line":699},[8742,8747,8751,8755,8760],{"type":27,"tag":87,"props":8743,"children":8744},{"style":184},[8745],{"type":36,"value":8746},"        Client client ",{"type":27,"tag":87,"props":8748,"children":8749},{"style":178},[8750],{"type":36,"value":325},{"type":27,"tag":87,"props":8752,"children":8753},{"style":178},[8754],{"type":36,"value":2052},{"type":27,"tag":87,"props":8756,"children":8757},{"style":94},[8758],{"type":36,"value":8759}," Client",{"type":27,"tag":87,"props":8761,"children":8762},{"style":184},[8763],{"type":36,"value":8764},"(serviceMock);\n",{"type":27,"tag":87,"props":8766,"children":8767},{"class":89,"line":707},[8768,8772,8776,8780,8785,8790],{"type":27,"tag":87,"props":8769,"children":8770},{"style":94},[8771],{"type":36,"value":8470},{"type":27,"tag":87,"props":8773,"children":8774},{"style":184},[8775],{"type":36,"value":1282},{"type":27,"tag":87,"props":8777,"children":8778},{"style":100},[8779],{"type":36,"value":8726},{"type":27,"tag":87,"props":8781,"children":8782},{"style":184},[8783],{"type":36,"value":8784},", client.",{"type":27,"tag":87,"props":8786,"children":8787},{"style":94},[8788],{"type":36,"value":8789},"getInformation",{"type":27,"tag":87,"props":8791,"children":8792},{"style":184},[8793],{"type":36,"value":1765},{"type":27,"tag":87,"props":8795,"children":8796},{"class":89,"line":725},[8797],{"type":27,"tag":87,"props":8798,"children":8799},{"style":184},[8800],{"type":36,"value":5359},{"type":27,"tag":87,"props":8802,"children":8803},{"class":89,"line":1039},[8804],{"type":27,"tag":87,"props":8805,"children":8806},{"style":184},[8807],{"type":36,"value":1805},{"type":27,"tag":39,"props":8809,"children":8811},{"id":8810},"tdd-in-action-a-practical-example",[8812],{"type":36,"value":8813},"TDD in Action: A Practical Example",{"type":27,"tag":32,"props":8815,"children":8816},{},[8817],{"type":36,"value":8818},"Let's say we need to develop a user management service. First, we write a failing test:",{"type":27,"tag":77,"props":8820,"children":8822},{"className":1566,"code":8821,"language":1469,"meta":8,"style":8},"@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",[8823],{"type":27,"tag":15,"props":8824,"children":8825},{"__ignoreMap":8},[8826,8838,8855,8876,8902,8910,8953,8993,9000,9023],{"type":27,"tag":87,"props":8827,"children":8828},{"class":89,"line":90},[8829,8834],{"type":27,"tag":87,"props":8830,"children":8831},{"style":184},[8832],{"type":36,"value":8833},"@",{"type":27,"tag":87,"props":8835,"children":8836},{"style":178},[8837],{"type":36,"value":8420},{"type":27,"tag":87,"props":8839,"children":8840},{"class":89,"line":200},[8841,8846,8851],{"type":27,"tag":87,"props":8842,"children":8843},{"style":178},[8844],{"type":36,"value":8845},"void",{"type":27,"tag":87,"props":8847,"children":8848},{"style":94},[8849],{"type":36,"value":8850}," testAddUser",{"type":27,"tag":87,"props":8852,"children":8853},{"style":184},[8854],{"type":36,"value":7019},{"type":27,"tag":87,"props":8856,"children":8857},{"class":89,"line":222},[8858,8863,8867,8871],{"type":27,"tag":87,"props":8859,"children":8860},{"style":184},[8861],{"type":36,"value":8862},"    UserRepository repoMock ",{"type":27,"tag":87,"props":8864,"children":8865},{"style":178},[8866],{"type":36,"value":325},{"type":27,"tag":87,"props":8868,"children":8869},{"style":94},[8870],{"type":36,"value":8684},{"type":27,"tag":87,"props":8872,"children":8873},{"style":184},[8874],{"type":36,"value":8875},"(UserRepository.class);\n",{"type":27,"tag":87,"props":8877,"children":8878},{"class":89,"line":235},[8879,8884,8888,8892,8897],{"type":27,"tag":87,"props":8880,"children":8881},{"style":184},[8882],{"type":36,"value":8883},"    UserService service ",{"type":27,"tag":87,"props":8885,"children":8886},{"style":178},[8887],{"type":36,"value":325},{"type":27,"tag":87,"props":8889,"children":8890},{"style":178},[8891],{"type":36,"value":2052},{"type":27,"tag":87,"props":8893,"children":8894},{"style":94},[8895],{"type":36,"value":8896}," UserService",{"type":27,"tag":87,"props":8898,"children":8899},{"style":184},[8900],{"type":36,"value":8901},"(repoMock);\n",{"type":27,"tag":87,"props":8903,"children":8904},{"class":89,"line":257},[8905],{"type":27,"tag":87,"props":8906,"children":8907},{"style":184},[8908],{"type":36,"value":8909},"    \n",{"type":27,"tag":87,"props":8911,"children":8912},{"class":89,"line":267},[8913,8918,8922,8926,8931,8935,8940,8944,8949],{"type":27,"tag":87,"props":8914,"children":8915},{"style":184},[8916],{"type":36,"value":8917},"    User user ",{"type":27,"tag":87,"props":8919,"children":8920},{"style":178},[8921],{"type":36,"value":325},{"type":27,"tag":87,"props":8923,"children":8924},{"style":178},[8925],{"type":36,"value":2052},{"type":27,"tag":87,"props":8927,"children":8928},{"style":94},[8929],{"type":36,"value":8930}," User",{"type":27,"tag":87,"props":8932,"children":8933},{"style":184},[8934],{"type":36,"value":1282},{"type":27,"tag":87,"props":8936,"children":8937},{"style":100},[8938],{"type":36,"value":8939},"\"John\"",{"type":27,"tag":87,"props":8941,"children":8942},{"style":184},[8943],{"type":36,"value":917},{"type":27,"tag":87,"props":8945,"children":8946},{"style":100},[8947],{"type":36,"value":8948},"\"john@example.com\"",{"type":27,"tag":87,"props":8950,"children":8951},{"style":184},[8952],{"type":36,"value":1607},{"type":27,"tag":87,"props":8954,"children":8955},{"class":89,"line":276},[8956,8961,8966,8971,8976,8980,8984,8989],{"type":27,"tag":87,"props":8957,"children":8958},{"style":94},[8959],{"type":36,"value":8960},"    when",{"type":27,"tag":87,"props":8962,"children":8963},{"style":184},[8964],{"type":36,"value":8965},"(repoMock.",{"type":27,"tag":87,"props":8967,"children":8968},{"style":94},[8969],{"type":36,"value":8970},"save",{"type":27,"tag":87,"props":8972,"children":8973},{"style":184},[8974],{"type":36,"value":8975},"(user)).",{"type":27,"tag":87,"props":8977,"children":8978},{"style":94},[8979],{"type":36,"value":8717},{"type":27,"tag":87,"props":8981,"children":8982},{"style":184},[8983],{"type":36,"value":1282},{"type":27,"tag":87,"props":8985,"children":8986},{"style":288},[8987],{"type":36,"value":8988},"true",{"type":27,"tag":87,"props":8990,"children":8991},{"style":184},[8992],{"type":36,"value":1607},{"type":27,"tag":87,"props":8994,"children":8995},{"class":89,"line":284},[8996],{"type":27,"tag":87,"props":8997,"children":8998},{"style":184},[8999],{"type":36,"value":8909},{"type":27,"tag":87,"props":9001,"children":9002},{"class":89,"line":314},[9003,9008,9013,9018],{"type":27,"tag":87,"props":9004,"children":9005},{"style":94},[9006],{"type":36,"value":9007},"    assertTrue",{"type":27,"tag":87,"props":9009,"children":9010},{"style":184},[9011],{"type":36,"value":9012},"(service.",{"type":27,"tag":87,"props":9014,"children":9015},{"style":94},[9016],{"type":36,"value":9017},"registerUser",{"type":27,"tag":87,"props":9019,"children":9020},{"style":184},[9021],{"type":36,"value":9022},"(user));\n",{"type":27,"tag":87,"props":9024,"children":9025},{"class":89,"line":341},[9026],{"type":27,"tag":87,"props":9027,"children":9028},{"style":184},[9029],{"type":36,"value":1805},{"type":27,"tag":32,"props":9031,"children":9032},{},[9033],{"type":36,"value":9034},"Next, we implement the minimal functionality required for the test to pass:",{"type":27,"tag":77,"props":9036,"children":9038},{"className":1566,"code":9037,"language":1469,"meta":8,"style":8},"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",[9039],{"type":27,"tag":15,"props":9040,"children":9041},{"__ignoreMap":8},[9042,9057,9074,9081,9106,9128,9135,9142,9173,9194,9201],{"type":27,"tag":87,"props":9043,"children":9044},{"class":89,"line":90},[9045,9049,9053],{"type":27,"tag":87,"props":9046,"children":9047},{"style":178},[9048],{"type":36,"value":6980},{"type":27,"tag":87,"props":9050,"children":9051},{"style":94},[9052],{"type":36,"value":8896},{"type":27,"tag":87,"props":9054,"children":9055},{"style":184},[9056],{"type":36,"value":4683},{"type":27,"tag":87,"props":9058,"children":9059},{"class":89,"line":200},[9060,9065,9069],{"type":27,"tag":87,"props":9061,"children":9062},{"style":178},[9063],{"type":36,"value":9064},"private",{"type":27,"tag":87,"props":9066,"children":9067},{"style":178},[9068],{"type":36,"value":4660},{"type":27,"tag":87,"props":9070,"children":9071},{"style":184},[9072],{"type":36,"value":9073}," UserRepository repository;\n",{"type":27,"tag":87,"props":9075,"children":9076},{"class":89,"line":222},[9077],{"type":27,"tag":87,"props":9078,"children":9079},{"style":184},[9080],{"type":36,"value":8909},{"type":27,"tag":87,"props":9082,"children":9083},{"class":89,"line":235},[9084,9088,9092,9097,9102],{"type":27,"tag":87,"props":9085,"children":9086},{"style":178},[9087],{"type":36,"value":5162},{"type":27,"tag":87,"props":9089,"children":9090},{"style":94},[9091],{"type":36,"value":8896},{"type":27,"tag":87,"props":9093,"children":9094},{"style":184},[9095],{"type":36,"value":9096},"(UserRepository ",{"type":27,"tag":87,"props":9098,"children":9099},{"style":359},[9100],{"type":36,"value":9101},"repository",{"type":27,"tag":87,"props":9103,"children":9104},{"style":184},[9105],{"type":36,"value":5200},{"type":27,"tag":87,"props":9107,"children":9108},{"class":89,"line":257},[9109,9114,9119,9123],{"type":27,"tag":87,"props":9110,"children":9111},{"style":288},[9112],{"type":36,"value":9113},"        this",{"type":27,"tag":87,"props":9115,"children":9116},{"style":184},[9117],{"type":36,"value":9118},".repository ",{"type":27,"tag":87,"props":9120,"children":9121},{"style":178},[9122],{"type":36,"value":325},{"type":27,"tag":87,"props":9124,"children":9125},{"style":184},[9126],{"type":36,"value":9127}," repository;\n",{"type":27,"tag":87,"props":9129,"children":9130},{"class":89,"line":267},[9131],{"type":27,"tag":87,"props":9132,"children":9133},{"style":184},[9134],{"type":36,"value":5359},{"type":27,"tag":87,"props":9136,"children":9137},{"class":89,"line":276},[9138],{"type":27,"tag":87,"props":9139,"children":9140},{"style":184},[9141],{"type":36,"value":8909},{"type":27,"tag":87,"props":9143,"children":9144},{"class":89,"line":284},[9145,9149,9154,9159,9164,9169],{"type":27,"tag":87,"props":9146,"children":9147},{"style":178},[9148],{"type":36,"value":5162},{"type":27,"tag":87,"props":9150,"children":9151},{"style":178},[9152],{"type":36,"value":9153}," boolean",{"type":27,"tag":87,"props":9155,"children":9156},{"style":94},[9157],{"type":36,"value":9158}," registerUser",{"type":27,"tag":87,"props":9160,"children":9161},{"style":184},[9162],{"type":36,"value":9163},"(User ",{"type":27,"tag":87,"props":9165,"children":9166},{"style":359},[9167],{"type":36,"value":9168},"user",{"type":27,"tag":87,"props":9170,"children":9171},{"style":184},[9172],{"type":36,"value":5200},{"type":27,"tag":87,"props":9174,"children":9175},{"class":89,"line":314},[9176,9180,9185,9189],{"type":27,"tag":87,"props":9177,"children":9178},{"style":178},[9179],{"type":36,"value":1241},{"type":27,"tag":87,"props":9181,"children":9182},{"style":184},[9183],{"type":36,"value":9184}," repository.",{"type":27,"tag":87,"props":9186,"children":9187},{"style":94},[9188],{"type":36,"value":8970},{"type":27,"tag":87,"props":9190,"children":9191},{"style":184},[9192],{"type":36,"value":9193},"(user);\n",{"type":27,"tag":87,"props":9195,"children":9196},{"class":89,"line":341},[9197],{"type":27,"tag":87,"props":9198,"children":9199},{"style":184},[9200],{"type":36,"value":5359},{"type":27,"tag":87,"props":9202,"children":9203},{"class":89,"line":374},[9204],{"type":27,"tag":87,"props":9205,"children":9206},{"style":184},[9207],{"type":36,"value":1805},{"type":27,"tag":32,"props":9209,"children":9210},{},[9211],{"type":36,"value":9212},"Finally, we refactor the code if necessary while ensuring all tests continue to pass.",{"type":27,"tag":39,"props":9214,"children":9215},{"id":2304},[9216],{"type":36,"value":2307},{"type":27,"tag":32,"props":9218,"children":9219},{},[9220],{"type":36,"value":9221},"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":27,"tag":39,"props":9223,"children":9224},{"id":2315},[9225],{"type":36,"value":2318},{"type":27,"tag":32,"props":9227,"children":9228},{},[9229],{"type":36,"value":9230},"To deepen your understanding of TDD, JUnit, and Mockito, consider exploring the following resources:",{"type":27,"tag":46,"props":9232,"children":9233},{},[9234,9244,9254],{"type":27,"tag":50,"props":9235,"children":9236},{},[9237],{"type":27,"tag":1410,"props":9238,"children":9241},{"href":9239,"rel":9240},"https://junit.org/junit5/docs/current/user-guide/",[1414],[9242],{"type":36,"value":9243},"JUnit 5 User Guide",{"type":27,"tag":50,"props":9245,"children":9246},{},[9247],{"type":27,"tag":1410,"props":9248,"children":9251},{"href":9249,"rel":9250},"https://site.mockito.org/",[1414],[9252],{"type":36,"value":9253},"Mockito Documentation",{"type":27,"tag":50,"props":9255,"children":9256},{},[9257],{"type":27,"tag":1410,"props":9258,"children":9261},{"href":9259,"rel":9260},"https://www.oreilly.com/library/view/test-driven-development/0321146530/",[1414],[9262],{"type":36,"value":9263},"Test-Driven Development by Example - Kent Beck",{"type":27,"tag":32,"props":9265,"children":9266},{},[9267],{"type":36,"value":9268},"Mastering TDD will not only improve your coding skills but also help you build more reliable and maintainable software systems.",{"type":27,"tag":1439,"props":9270,"children":9271},{},[9272],{"type":36,"value":1443},{"title":8,"searchDepth":200,"depth":200,"links":9274},[9275,9276,9277,9278,9279],{"id":8286,"depth":200,"text":8289},{"id":8320,"depth":200,"text":8323},{"id":8810,"depth":200,"text":8813},{"id":2304,"depth":200,"text":2307},{"id":2315,"depth":200,"text":2318},"content:posts:tdd-testing.md","posts/tdd-testing.md","posts/tdd-testing",{"_path":9284,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":9285,"description":9286,"date":9287,"layout":12,"subtitle":9288,"image":9289,"optimized_image":9289,"category":15,"tags":9290,"author":22,"paginate":7,"body":9293,"_type":1455,"_id":9670,"_source":1457,"_file":9671,"_stem":9672,"_extension":1460},"/posts/single-table-design","Single Table Design","Exploring Java 17's New Features with examples","2023-12-27T11:00:00.000Z","A Practical Approach to Database Modeling with dynamoDb","/assets/img/uploads/cloud-computing.jpg",[15,9291,9292],"database","aws",{"type":24,"children":9294,"toc":9662},[9295,9310,9316,9321,9327,9360,9366,9399,9405,9410,9418,9427,9472,9479,9515,9536,9544,9565,9606,9610,9615,9619,9624,9657],{"type":27,"tag":28,"props":9296,"children":9297},{},[9298],{"type":27,"tag":32,"props":9299,"children":9300},{},[9301,9303,9308],{"type":36,"value":9302},"In the realm of software development and database design, the ",{"type":27,"tag":2410,"props":9304,"children":9305},{},[9306],{"type":36,"value":9307},"Single Table Design (STD)",{"type":36,"value":9309}," has emerged as a compelling model for structuring data. This approach challenges traditional database normalization techniques by advocating for a simplified, denormalized structure contained within a single table. In this article, we will delve into the essence of Single Table Design, exploring its advantages and drawbacks, and provide a practical example to illustrate its application.",{"type":27,"tag":39,"props":9311,"children":9313},{"id":9312},"what-is-single-table-design",[9314],{"type":36,"value":9315},"What is Single Table Design?",{"type":27,"tag":32,"props":9317,"children":9318},{},[9319],{"type":36,"value":9320},"Single Table Design is a database modeling strategy that involves consolidating multiple entities and relationships into a single table. Unlike the conventional normalization process, which divides data into separate tables to minimize redundancy and maintain referential integrity, STD embraces a more denormalized structure. This means that a single table contains all the necessary fields and relationships to represent various entities within the system.",{"type":27,"tag":2478,"props":9322,"children":9324},{"id":9323},"advantages-of-single-table-design",[9325],{"type":36,"value":9326},"Advantages of Single Table Design",{"type":27,"tag":46,"props":9328,"children":9329},{},[9330,9340,9350],{"type":27,"tag":50,"props":9331,"children":9332},{},[9333,9338],{"type":27,"tag":2410,"props":9334,"children":9335},{},[9336],{"type":36,"value":9337},"Simplified Schema:",{"type":36,"value":9339}," STD simplifies the database schema by eliminating the need for multiple tables and complex relationships. This can lead to easier maintenance and a more straightforward understanding of the data structure.",{"type":27,"tag":50,"props":9341,"children":9342},{},[9343,9348],{"type":27,"tag":2410,"props":9344,"children":9345},{},[9346],{"type":36,"value":9347},"Improved Query Performance:",{"type":36,"value":9349}," Retrieving data from a single table can often be more efficient than joining multiple tables, especially for read-heavy operations. This can result in better query performance and reduced latency.",{"type":27,"tag":50,"props":9351,"children":9352},{},[9353,9358],{"type":27,"tag":2410,"props":9354,"children":9355},{},[9356],{"type":36,"value":9357},"Flexibility in Schema Evolution:",{"type":36,"value":9359}," With a denormalized structure, it becomes easier to adapt the database schema to evolving requirements without the need for complex migrations. Adding or modifying fields becomes a less cumbersome task.",{"type":27,"tag":2478,"props":9361,"children":9363},{"id":9362},"disadvantages-of-single-table-design",[9364],{"type":36,"value":9365},"Disadvantages of Single Table Design",{"type":27,"tag":46,"props":9367,"children":9368},{},[9369,9379,9389],{"type":27,"tag":50,"props":9370,"children":9371},{},[9372,9377],{"type":27,"tag":2410,"props":9373,"children":9374},{},[9375],{"type":36,"value":9376},"Data Redundancy:",{"type":36,"value":9378}," Since data is denormalized, there may be redundancy in the storage of information. This can lead to increased storage requirements and potential inconsistencies if updates are not managed properly.",{"type":27,"tag":50,"props":9380,"children":9381},{},[9382,9387],{"type":27,"tag":2410,"props":9383,"children":9384},{},[9385],{"type":36,"value":9386},"Limited Support for Complex Relationships:",{"type":36,"value":9388}," STD might not be suitable for systems with complex relationships between entities. Maintaining intricate connections between data points could become challenging in a denormalized structure.",{"type":27,"tag":50,"props":9390,"children":9391},{},[9392,9397],{"type":27,"tag":2410,"props":9393,"children":9394},{},[9395],{"type":36,"value":9396},"Normalization Benefits Sacrificed:",{"type":36,"value":9398}," By consolidating data into a single table, the benefits of normalization, such as minimizing data redundancy and ensuring consistency, are sacrificed to some extent.",{"type":27,"tag":39,"props":9400,"children":9402},{"id":9401},"example-of-single-table-design",[9403],{"type":36,"value":9404},"Example of Single Table Design",{"type":27,"tag":32,"props":9406,"children":9407},{},[9408],{"type":36,"value":9409},"Let's consider a simplified example of a blog application where we have Users, Posts, and Comments as entities. In a traditional normalized database, we might have separate tables for each entity. However, in a Single Table Design approach, we would merge these entities into a single table:",{"type":27,"tag":77,"props":9411,"children":9413},{"code":9412},"| PK           | SK            | GSI1PK   | GSI1SK     | Attribute1    | Attribute2      | ... |\n|--------------|---------------|----------|------------|---------------|-----------------|-----|\n| USER#1       | PROFILE#1     |          |            | Alice         | alice@email.com | ... |\n| ORDER#1      | INFO#1        | USER#1   | PROFILE#1  |               |                 | ... |\n| PRODUCT#123  | DETAILS#123   |          |            | Laptop        | Electronics     | ... |\n| COMMENT#101  | TEXT#101      | USER#1   | ORDER#1    | Great post!   |                 | ... |\n",[9414],{"type":27,"tag":15,"props":9415,"children":9416},{"__ignoreMap":8},[9417],{"type":36,"value":9412},{"type":27,"tag":32,"props":9419,"children":9420},{},[9421],{"type":27,"tag":9422,"props":9423,"children":9424},"em",{},[9425],{"type":36,"value":9426},"Explanation:",{"type":27,"tag":46,"props":9428,"children":9429},{},[9430,9451],{"type":27,"tag":50,"props":9431,"children":9432},{},[9433,9438],{"type":27,"tag":2410,"props":9434,"children":9435},{},[9436],{"type":36,"value":9437},"PK (Partition Key) and SK (Sort Key):",{"type":27,"tag":46,"props":9439,"children":9440},{},[9441,9446],{"type":27,"tag":50,"props":9442,"children":9443},{},[9444],{"type":36,"value":9445},"USER#1, ORDER#1, PRODUCT#123, and COMMENT#101 serve as the PK, representing distinct entities (User, Order, Product, Comment).",{"type":27,"tag":50,"props":9447,"children":9448},{},[9449],{"type":36,"value":9450},"PROFILE#1, INFO#1, DETAILS#123, and TEXT#101 act as SK, helping to distinguish and organize items within the same PK.",{"type":27,"tag":50,"props":9452,"children":9453},{},[9454,9459],{"type":27,"tag":2410,"props":9455,"children":9456},{},[9457],{"type":36,"value":9458},"GSI1PK and GSI1SK (Global Secondary Index):",{"type":27,"tag":46,"props":9460,"children":9461},{},[9462,9467],{"type":27,"tag":50,"props":9463,"children":9464},{},[9465],{"type":36,"value":9466},"GSI1PK and GSI1SK are additional indices that facilitate different access patterns.",{"type":27,"tag":50,"props":9468,"children":9469},{},[9470],{"type":36,"value":9471},"For example, GSI1PK USER#1 and GSI1SK PROFILE#1 enable efficient querying for user profiles.",{"type":27,"tag":9473,"props":9474,"children":9476},"h4",{"id":9475},"query-examples",[9477],{"type":36,"value":9478},"Query Examples:",{"type":27,"tag":1495,"props":9480,"children":9481},{},[9482,9510],{"type":27,"tag":50,"props":9483,"children":9484},{},[9485,9487],{"type":36,"value":9486},"Retrieve User Profile:\n",{"type":27,"tag":46,"props":9488,"children":9489},{},[9490],{"type":27,"tag":50,"props":9491,"children":9492},{},[9493,9495,9501,9503,9509],{"type":36,"value":9494},"Query using PK ",{"type":27,"tag":15,"props":9496,"children":9498},{"className":9497},[],[9499],{"type":36,"value":9500},"USER#1",{"type":36,"value":9502}," and SK ",{"type":27,"tag":15,"props":9504,"children":9506},{"className":9505},[],[9507],{"type":36,"value":9508},"PROFILE#1",{"type":36,"value":3225},{"type":27,"tag":50,"props":9511,"children":9512},{},[9513],{"type":36,"value":9514},"Fetch Orders for a User:",{"type":27,"tag":46,"props":9516,"children":9517},{},[9518],{"type":27,"tag":50,"props":9519,"children":9520},{},[9521,9522,9527,9529,9535],{"type":36,"value":9494},{"type":27,"tag":15,"props":9523,"children":9525},{"className":9524},[],[9526],{"type":36,"value":9500},{"type":36,"value":9528}," and SK range ",{"type":27,"tag":15,"props":9530,"children":9532},{"className":9531},[],[9533],{"type":36,"value":9534},"INFO#",{"type":36,"value":3225},{"type":27,"tag":1495,"props":9537,"children":9538},{"start":222},[9539],{"type":27,"tag":50,"props":9540,"children":9541},{},[9542],{"type":36,"value":9543},"Get Comments for an Order:",{"type":27,"tag":46,"props":9545,"children":9546},{},[9547],{"type":27,"tag":50,"props":9548,"children":9549},{},[9550,9551,9557,9558,9564],{"type":36,"value":9494},{"type":27,"tag":15,"props":9552,"children":9554},{"className":9553},[],[9555],{"type":36,"value":9556},"ORDER#1",{"type":36,"value":9528},{"type":27,"tag":15,"props":9559,"children":9561},{"className":9560},[],[9562],{"type":36,"value":9563},"TEXT#",{"type":36,"value":3225},{"type":27,"tag":32,"props":9566,"children":9567},{},[9568,9570,9574,9576,9581,9583,9589,9590,9596,9598,9604],{"type":36,"value":9569},"This example demonstrates how ",{"type":27,"tag":2410,"props":9571,"children":9572},{},[9573],{"type":36,"value":9285},{"type":36,"value":9575}," in ",{"type":27,"tag":2410,"props":9577,"children":9578},{},[9579],{"type":36,"value":9580},"DynamoDB",{"type":36,"value":9582},", utilizing ",{"type":27,"tag":15,"props":9584,"children":9586},{"className":9585},[],[9587],{"type":36,"value":9588},"PK",{"type":36,"value":917},{"type":27,"tag":15,"props":9591,"children":9593},{"className":9592},[],[9594],{"type":36,"value":9595},"SK",{"type":36,"value":9597},", and ",{"type":27,"tag":15,"props":9599,"children":9601},{"className":9600},[],[9602],{"type":36,"value":9603},"GSI",{"type":36,"value":9605},", can efficiently handle diverse queries within a unified structure. It optimizes data retrieval while adhering to the principles of denormalization and simplicity.",{"type":27,"tag":39,"props":9607,"children":9608},{"id":2304},[9609],{"type":36,"value":2307},{"type":27,"tag":32,"props":9611,"children":9612},{},[9613],{"type":36,"value":9614},"Single Table Design offers a practical alternative to traditional database normalization, emphasizing simplicity and performance. While it may not be suitable for every use case, especially those with complex relationships, STD can be a powerful tool in scenarios where a denormalized structure aligns with the application's requirements. Consider the specific needs of your project and evaluate whether Single Table Design is a suitable fit for your database modeling approach.",{"type":27,"tag":1397,"props":9616,"children":9617},{"id":2315},[9618],{"type":36,"value":2318},{"type":27,"tag":32,"props":9620,"children":9621},{},[9622],{"type":36,"value":9623},"To deepen your understanding of Single Table Design in Amazon DynamoDB and database modeling best practices, consider exploring the following official AWS documentation:",{"type":27,"tag":46,"props":9625,"children":9626},{},[9627,9637,9647],{"type":27,"tag":50,"props":9628,"children":9629},{},[9630],{"type":27,"tag":1410,"props":9631,"children":9634},{"href":9632,"rel":9633},"https://aws.amazon.com/es/pm/dynamodb/",[1414],[9635],{"type":36,"value":9636},"DynamoDB Overview",{"type":27,"tag":50,"props":9638,"children":9639},{},[9640],{"type":27,"tag":1410,"props":9641,"children":9644},{"href":9642,"rel":9643},"https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/best-practices.html",[1414],[9645],{"type":36,"value":9646},"Best practices for designing and architecting with DynamoDB",{"type":27,"tag":50,"props":9648,"children":9649},{},[9650],{"type":27,"tag":1410,"props":9651,"children":9654},{"href":9652,"rel":9653},"https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/examples-dynamodb.html",[1414],[9655],{"type":36,"value":9656},"DynamoDB Examples Using the AWS SDK for Java",{"type":27,"tag":32,"props":9658,"children":9659},{},[9660],{"type":36,"value":9661},"These resources provide comprehensive insights into the principles, features, and best practices related to DynamoDB, including Single Table Design. Referencing the official documentation will empower you with the knowledge needed to effectively design, implement, and optimize your database models on the AWS platform.",{"title":8,"searchDepth":200,"depth":200,"links":9663},[9664,9668,9669],{"id":9312,"depth":200,"text":9315,"children":9665},[9666,9667],{"id":9323,"depth":222,"text":9326},{"id":9362,"depth":222,"text":9365},{"id":9401,"depth":200,"text":9404},{"id":2304,"depth":200,"text":2307},"content:posts:single-table-design.md","posts/single-table-design.md","posts/single-table-design",{"_path":9674,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":9675,"description":9286,"date":9676,"layout":12,"subtitle":9677,"image":9678,"optimized_image":9678,"category":15,"tags":9679,"author":22,"paginate":7,"body":9680,"_type":1455,"_id":10063,"_source":1457,"_file":10064,"_stem":10065,"_extension":1460},"/posts/java-17","Exploring Java 17's New Features","2023-10-08T11:00:00.000Z","with examples","/assets/img/uploads/java-source-code.png",[15,1469],{"type":24,"children":9681,"toc":10055},[9682,9687,9692,9698,9703,9771,9775,9780,9851,9857,9862,10015,10021,10026,10032,10037,10041,10046,10051],{"type":27,"tag":32,"props":9683,"children":9684},{},[9685],{"type":36,"value":9686},"Java 17 is here, and it brings along a host of exciting features that enhance the language's capabilities. In this post, we'll dive into some of the key additions and provide practical code examples to help you get started.",{"type":27,"tag":32,"props":9688,"children":9689},{},[9690],{"type":36,"value":9691},"Java 17, a long-term support (LTS) release, introduces several noteworthy features that simplify coding and improve performance. Let's explore these features one by one.",{"type":27,"tag":2478,"props":9693,"children":9695},{"id":9694},"pattern-matching-for-instanceof-operator",[9696],{"type":36,"value":9697},"Pattern Matching for instanceof operator",{"type":27,"tag":32,"props":9699,"children":9700},{},[9701],{"type":36,"value":9702},"Pattern Matching is a game-changer in Java 17. It allows you to combine type checking and type casting in a single line, making your code more concise and readable. Here's an example:",{"type":27,"tag":77,"props":9704,"children":9706},{"className":1566,"code":9705,"language":1469,"meta":8,"style":8},"if (object instanceof String str) {\n    // 'str' is now of type String within this block\n    System.out.println(str.length());\n}\n",[9707],{"type":27,"tag":15,"props":9708,"children":9709},{"__ignoreMap":8},[9710,9731,9739,9764],{"type":27,"tag":87,"props":9711,"children":9712},{"class":89,"line":90},[9713,9717,9722,9726],{"type":27,"tag":87,"props":9714,"children":9715},{"style":178},[9716],{"type":36,"value":1773},{"type":27,"tag":87,"props":9718,"children":9719},{"style":184},[9720],{"type":36,"value":9721}," (object ",{"type":27,"tag":87,"props":9723,"children":9724},{"style":178},[9725],{"type":36,"value":4312},{"type":27,"tag":87,"props":9727,"children":9728},{"style":184},[9729],{"type":36,"value":9730}," String str) {\n",{"type":27,"tag":87,"props":9732,"children":9733},{"class":89,"line":200},[9734],{"type":27,"tag":87,"props":9735,"children":9736},{"style":1794},[9737],{"type":36,"value":9738},"    // 'str' is now of type String within this block\n",{"type":27,"tag":87,"props":9740,"children":9741},{"class":89,"line":222},[9742,9746,9750,9755,9760],{"type":27,"tag":87,"props":9743,"children":9744},{"style":184},[9745],{"type":36,"value":4342},{"type":27,"tag":87,"props":9747,"children":9748},{"style":94},[9749],{"type":36,"value":2967},{"type":27,"tag":87,"props":9751,"children":9752},{"style":184},[9753],{"type":36,"value":9754},"(str.",{"type":27,"tag":87,"props":9756,"children":9757},{"style":94},[9758],{"type":36,"value":9759},"length",{"type":27,"tag":87,"props":9761,"children":9762},{"style":184},[9763],{"type":36,"value":1765},{"type":27,"tag":87,"props":9765,"children":9766},{"class":89,"line":235},[9767],{"type":27,"tag":87,"props":9768,"children":9769},{"style":184},[9770],{"type":36,"value":1805},{"type":27,"tag":2478,"props":9772,"children":9773},{"id":4210},[9774],{"type":36,"value":4568},{"type":27,"tag":32,"props":9776,"children":9777},{},[9778],{"type":36,"value":9779},"Sealed classes enable you to restrict which classes can be subclasses. This promotes better control over your code's architecture. Here's how you can define a sealed class:",{"type":27,"tag":77,"props":9781,"children":9783},{"className":1566,"code":9782,"language":1469,"meta":8,"style":8},"public sealed class Shape permits Circle, Rectangle, Triangle {\n// Class definition here\n}\n",[9784],{"type":27,"tag":15,"props":9785,"children":9786},{"__ignoreMap":8},[9787,9836,9844],{"type":27,"tag":87,"props":9788,"children":9789},{"class":89,"line":90},[9790,9794,9798,9802,9806,9811,9815,9819,9823,9827,9832],{"type":27,"tag":87,"props":9791,"children":9792},{"style":178},[9793],{"type":36,"value":4594},{"type":27,"tag":87,"props":9795,"children":9796},{"style":178},[9797],{"type":36,"value":4599},{"type":27,"tag":87,"props":9799,"children":9800},{"style":178},[9801],{"type":36,"value":4609},{"type":27,"tag":87,"props":9803,"children":9804},{"style":94},[9805],{"type":36,"value":4678},{"type":27,"tag":87,"props":9807,"children":9808},{"style":178},[9809],{"type":36,"value":9810}," permits",{"type":27,"tag":87,"props":9812,"children":9813},{"style":94},[9814],{"type":36,"value":4627},{"type":27,"tag":87,"props":9816,"children":9817},{"style":184},[9818],{"type":36,"value":917},{"type":27,"tag":87,"props":9820,"children":9821},{"style":94},[9822],{"type":36,"value":4636},{"type":27,"tag":87,"props":9824,"children":9825},{"style":184},[9826],{"type":36,"value":917},{"type":27,"tag":87,"props":9828,"children":9829},{"style":94},[9830],{"type":36,"value":9831},"Triangle",{"type":27,"tag":87,"props":9833,"children":9834},{"style":184},[9835],{"type":36,"value":4683},{"type":27,"tag":87,"props":9837,"children":9838},{"class":89,"line":200},[9839],{"type":27,"tag":87,"props":9840,"children":9841},{"style":1794},[9842],{"type":36,"value":9843},"// Class definition here\n",{"type":27,"tag":87,"props":9845,"children":9846},{"class":89,"line":222},[9847],{"type":27,"tag":87,"props":9848,"children":9849},{"style":184},[9850],{"type":36,"value":1805},{"type":27,"tag":2478,"props":9852,"children":9854},{"id":9853},"new-switch-expressions",[9855],{"type":36,"value":9856},"New Switch Expressions",{"type":27,"tag":32,"props":9858,"children":9859},{},[9860],{"type":36,"value":9861},"Java 17 enhances switch expressions by allowing you to simplify repetitive code. Now, you can use \"case ->\" syntax to create more concise switch expressions:",{"type":27,"tag":77,"props":9863,"children":9865},{"className":1566,"code":9864,"language":1469,"meta":8,"style":8},"int day = 3;\nString dayName = switch (day) {\n    case 1 -> \"Monday\";\n    case 2 -> \"Tuesday\";\n    case 3 -> \"Wednesday\";\n    default -> \"Unknown\";\n};\n",[9866],{"type":27,"tag":15,"props":9867,"children":9868},{"__ignoreMap":8},[9869,9894,9915,9939,9964,9988,10008],{"type":27,"tag":87,"props":9870,"children":9871},{"class":89,"line":90},[9872,9876,9881,9885,9890],{"type":27,"tag":87,"props":9873,"children":9874},{"style":178},[9875],{"type":36,"value":7431},{"type":27,"tag":87,"props":9877,"children":9878},{"style":184},[9879],{"type":36,"value":9880}," day ",{"type":27,"tag":87,"props":9882,"children":9883},{"style":178},[9884],{"type":36,"value":325},{"type":27,"tag":87,"props":9886,"children":9887},{"style":288},[9888],{"type":36,"value":9889}," 3",{"type":27,"tag":87,"props":9891,"children":9892},{"style":184},[9893],{"type":36,"value":4288},{"type":27,"tag":87,"props":9895,"children":9896},{"class":89,"line":200},[9897,9902,9906,9910],{"type":27,"tag":87,"props":9898,"children":9899},{"style":184},[9900],{"type":36,"value":9901},"String dayName ",{"type":27,"tag":87,"props":9903,"children":9904},{"style":178},[9905],{"type":36,"value":325},{"type":27,"tag":87,"props":9907,"children":9908},{"style":178},[9909],{"type":36,"value":4827},{"type":27,"tag":87,"props":9911,"children":9912},{"style":184},[9913],{"type":36,"value":9914}," (day) {\n",{"type":27,"tag":87,"props":9916,"children":9917},{"class":89,"line":222},[9918,9922,9926,9930,9935],{"type":27,"tag":87,"props":9919,"children":9920},{"style":178},[9921],{"type":36,"value":4426},{"type":27,"tag":87,"props":9923,"children":9924},{"style":288},[9925],{"type":36,"value":4494},{"type":27,"tag":87,"props":9927,"children":9928},{"style":178},[9929],{"type":36,"value":4511},{"type":27,"tag":87,"props":9931,"children":9932},{"style":100},[9933],{"type":36,"value":9934}," \"Monday\"",{"type":27,"tag":87,"props":9936,"children":9937},{"style":184},[9938],{"type":36,"value":4288},{"type":27,"tag":87,"props":9940,"children":9941},{"class":89,"line":235},[9942,9946,9951,9955,9960],{"type":27,"tag":87,"props":9943,"children":9944},{"style":178},[9945],{"type":36,"value":4426},{"type":27,"tag":87,"props":9947,"children":9948},{"style":288},[9949],{"type":36,"value":9950}," 2",{"type":27,"tag":87,"props":9952,"children":9953},{"style":178},[9954],{"type":36,"value":4511},{"type":27,"tag":87,"props":9956,"children":9957},{"style":100},[9958],{"type":36,"value":9959}," \"Tuesday\"",{"type":27,"tag":87,"props":9961,"children":9962},{"style":184},[9963],{"type":36,"value":4288},{"type":27,"tag":87,"props":9965,"children":9966},{"class":89,"line":257},[9967,9971,9975,9979,9984],{"type":27,"tag":87,"props":9968,"children":9969},{"style":178},[9970],{"type":36,"value":4426},{"type":27,"tag":87,"props":9972,"children":9973},{"style":288},[9974],{"type":36,"value":9889},{"type":27,"tag":87,"props":9976,"children":9977},{"style":178},[9978],{"type":36,"value":4511},{"type":27,"tag":87,"props":9980,"children":9981},{"style":100},[9982],{"type":36,"value":9983}," \"Wednesday\"",{"type":27,"tag":87,"props":9985,"children":9986},{"style":184},[9987],{"type":36,"value":4288},{"type":27,"tag":87,"props":9989,"children":9990},{"class":89,"line":267},[9991,9995,9999,10004],{"type":27,"tag":87,"props":9992,"children":9993},{"style":178},[9994],{"type":36,"value":4506},{"type":27,"tag":87,"props":9996,"children":9997},{"style":178},[9998],{"type":36,"value":4511},{"type":27,"tag":87,"props":10000,"children":10001},{"style":100},[10002],{"type":36,"value":10003}," \"Unknown\"",{"type":27,"tag":87,"props":10005,"children":10006},{"style":184},[10007],{"type":36,"value":4288},{"type":27,"tag":87,"props":10009,"children":10010},{"class":89,"line":276},[10011],{"type":27,"tag":87,"props":10012,"children":10013},{"style":184},[10014],{"type":36,"value":4910},{"type":27,"tag":2478,"props":10016,"children":10018},{"id":10017},"strong-encapsulation-of-jdk-internals",[10019],{"type":36,"value":10020},"Strong Encapsulation of JDK Internals",{"type":27,"tag":32,"props":10022,"children":10023},{},[10024],{"type":36,"value":10025},"With strong encapsulation, Java 17 further restricts access to JDK internals, promoting better security and stability of your applications.",{"type":27,"tag":2478,"props":10027,"children":10029},{"id":10028},"foreign-function-memory-api",[10030],{"type":36,"value":10031},"Foreign Function & Memory API",{"type":27,"tag":32,"props":10033,"children":10034},{},[10035],{"type":36,"value":10036},"Java 17 introduces a Foreign Function & Memory API that facilitates interaction with native code and memory management. This is especially valuable for low-level operations.",{"type":27,"tag":2478,"props":10038,"children":10039},{"id":2304},[10040],{"type":36,"value":2307},{"type":27,"tag":32,"props":10042,"children":10043},{},[10044],{"type":36,"value":10045},"Java 17 brings a wealth of new features that make coding in Java more efficient and secure. Pattern matching, sealed classes, improved switch expressions, and stronger encapsulation are just a few of the highlights. These additions not only simplify your code but also enhance its performance and maintainability.",{"type":27,"tag":32,"props":10047,"children":10048},{},[10049],{"type":36,"value":10050},"Start exploring these features today and take your Java development skills to the next level!",{"type":27,"tag":1439,"props":10052,"children":10053},{},[10054],{"type":36,"value":1443},{"title":8,"searchDepth":200,"depth":200,"links":10056},[10057,10058,10059,10060,10061,10062],{"id":9694,"depth":222,"text":9697},{"id":4210,"depth":222,"text":4568},{"id":9853,"depth":222,"text":9856},{"id":10017,"depth":222,"text":10020},{"id":10028,"depth":222,"text":10031},{"id":2304,"depth":222,"text":2307},"content:posts:java-17.md","posts/java-17.md","posts/java-17",{"_path":10067,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":10068,"description":10068,"date":10069,"layout":12,"subtitle":10070,"image":10071,"optimized_image":10071,"category":15,"tags":10072,"author":22,"paginate":7,"body":10073,"_type":1455,"_id":10695,"_source":1457,"_file":10696,"_stem":10697,"_extension":1460},"/posts/hexagonal-architecture","Introduction to Hexagonal Architecture","2023-10-02 18:00:00","A brief introduction","/assets/img/uploads/hexagonal-architecture.jpeg",[15,1469,8093],{"type":24,"children":10074,"toc":10685},[10075,10080,10086,10105,10110,10133,10138,10149,10164,10170,10175,10228,10234,10239,10245,10250,10273,10278,10284,10289,10312,10317,10323,10328,10553,10558,10629,10634,10638,10643,10676,10681],{"type":27,"tag":32,"props":10076,"children":10077},{},[10078],{"type":36,"value":10079},"In the world of software development, architectural patterns play a pivotal role in creating robust, maintainable, and flexible systems. One such architectural pattern that has gained popularity in recent years is Hexagonal Architecture. In this article, we will delve into the fundamentals of Hexagonal Architecture, explore its advantages, and illustrate how to structure packages in a Java project following this architectural style.",{"type":27,"tag":39,"props":10081,"children":10083},{"id":10082},"what-is-hexagonal-architecture",[10084],{"type":36,"value":10085},"What is Hexagonal Architecture?",{"type":27,"tag":32,"props":10087,"children":10088},{},[10089,10091,10096,10098,10103],{"type":36,"value":10090},"Hexagonal Architecture, also known as ",{"type":27,"tag":2410,"props":10092,"children":10093},{},[10094],{"type":36,"value":10095},"Ports and Adapters",{"type":36,"value":10097}," or the ",{"type":27,"tag":2410,"props":10099,"children":10100},{},[10101],{"type":36,"value":10102},"Onion Architecture",{"type":36,"value":10104},", is a design pattern that promotes the separation of concerns and modularization in software systems. It was first introduced by Alistair Cockburn in 2005. At its core, Hexagonal Architecture revolves around the idea of isolating the core business logic from external dependencies and infrastructure concerns.",{"type":27,"tag":32,"props":10106,"children":10107},{},[10108],{"type":36,"value":10109},"The central concept of Hexagonal Architecture is the division of an application into two main parts:",{"type":27,"tag":1495,"props":10111,"children":10112},{},[10113,10123],{"type":27,"tag":50,"props":10114,"children":10115},{},[10116,10121],{"type":27,"tag":2410,"props":10117,"children":10118},{},[10119],{"type":36,"value":10120},"Core Business Logic",{"type":36,"value":10122},": This is the heart of the application where the domain-specific rules and functionality reside. It should be completely isolated from any external factors like databases, user interfaces, or third-party services.",{"type":27,"tag":50,"props":10124,"children":10125},{},[10126,10131],{"type":27,"tag":2410,"props":10127,"children":10128},{},[10129],{"type":36,"value":10130},"External Interfaces",{"type":36,"value":10132},": These are the entry points and exit points to the application. They include adapters that communicate with the external world, such as REST APIs, databases, UI frameworks, and messaging systems.",{"type":27,"tag":32,"props":10134,"children":10135},{},[10136],{"type":36,"value":10137},"The goal of Hexagonal Architecture is to ensure that changes in the external interfaces (adapters) do not impact the core business logic, and vice versa. This separation enables better testability, maintainability, and scalability of your software.",{"type":27,"tag":32,"props":10139,"children":10140},{},[10141,10146],{"type":27,"tag":10142,"props":10143,"children":10145},"img",{"alt":8,"src":10144},"https://miro.medium.com/v2/resize:fit:1400/format:webp/1*ebUHgG6JwawEifXlARgfzg.png",[],{"type":27,"tag":9422,"props":10147,"children":10148},{},[],{"type":27,"tag":10150,"props":10151,"children":10152},"center",{},[10153],{"type":27,"tag":9422,"props":10154,"children":10155},{},[10156,10158],{"type":36,"value":10157},"source: ",{"type":27,"tag":1410,"props":10159,"children":10161},{"href":10160},"https://blog.devgenius.io/flask-blog-tutorial-with-hexagonal-architecture-part-1-6446e7e9aaaa",[10162],{"type":36,"value":10163}," medium.com",{"type":27,"tag":39,"props":10165,"children":10167},{"id":10166},"advantages-of-hexagonal-architecture",[10168],{"type":36,"value":10169},"Advantages of Hexagonal Architecture",{"type":27,"tag":32,"props":10171,"children":10172},{},[10173],{"type":36,"value":10174},"Utilizing Hexagonal Architecture offers several advantages:",{"type":27,"tag":1495,"props":10176,"children":10177},{},[10178,10188,10198,10208,10218],{"type":27,"tag":50,"props":10179,"children":10180},{},[10181,10186],{"type":27,"tag":2410,"props":10182,"children":10183},{},[10184],{"type":36,"value":10185},"Modularity",{"type":36,"value":10187},": The separation of concerns into core business logic and external interfaces makes it easier to maintain and extend your application. Changes in one part of the system have minimal impact on the other.",{"type":27,"tag":50,"props":10189,"children":10190},{},[10191,10196],{"type":27,"tag":2410,"props":10192,"children":10193},{},[10194],{"type":36,"value":10195},"Testability",{"type":36,"value":10197},": Isolating the core logic allows for comprehensive unit testing without the need for complex mocking of external dependencies.",{"type":27,"tag":50,"props":10199,"children":10200},{},[10201,10206],{"type":27,"tag":2410,"props":10202,"children":10203},{},[10204],{"type":36,"value":10205},"Flexibility",{"type":36,"value":10207},": You can switch out external components (e.g., databases, UI frameworks) without affecting the core business logic. This adaptability is particularly beneficial when upgrading or changing technology stacks.",{"type":27,"tag":50,"props":10209,"children":10210},{},[10211,10216],{"type":27,"tag":2410,"props":10212,"children":10213},{},[10214],{"type":36,"value":10215},"Clean Code",{"type":36,"value":10217},": Hexagonal Architecture encourages clean and organized code. It promotes the use of interfaces and clear boundaries between components, making the codebase more understandable.",{"type":27,"tag":50,"props":10219,"children":10220},{},[10221,10226],{"type":27,"tag":2410,"props":10222,"children":10223},{},[10224],{"type":36,"value":10225},"Business Focus",{"type":36,"value":10227},": Developers can focus on implementing business requirements without being distracted by technical details, resulting in a more business-centric codebase.",{"type":27,"tag":39,"props":10229,"children":10231},{"id":10230},"ports-and-adapters-in-hexagonal-architecture",[10232],{"type":36,"value":10233},"Ports and Adapters in Hexagonal Architecture",{"type":27,"tag":32,"props":10235,"children":10236},{},[10237],{"type":36,"value":10238},"In Hexagonal Architecture, the concepts of \"Ports\" and \"Adapters\" play a central role in achieving its architectural goals. Let's take a closer look at what these terms mean:",{"type":27,"tag":2478,"props":10240,"children":10242},{"id":10241},"ports",[10243],{"type":36,"value":10244},"Ports",{"type":27,"tag":32,"props":10246,"children":10247},{},[10248],{"type":36,"value":10249},"Ports are interfaces or contracts that define the interactions between the core business logic of your application and the external world. They represent the entry points and exit points for data and functionality. In simpler terms, ports are the \"what\" your application needs from the outside world.",{"type":27,"tag":46,"props":10251,"children":10252},{},[10253,10263],{"type":27,"tag":50,"props":10254,"children":10255},{},[10256,10261],{"type":27,"tag":2410,"props":10257,"children":10258},{},[10259],{"type":36,"value":10260},"Primary Ports (Inbound)",{"type":36,"value":10262},": These are entry points for external interactions with your application. Examples include REST API endpoints, command handlers, or event listeners.",{"type":27,"tag":50,"props":10264,"children":10265},{},[10266,10271],{"type":27,"tag":2410,"props":10267,"children":10268},{},[10269],{"type":36,"value":10270},"Secondary Ports (Outbound)",{"type":36,"value":10272},": These are exit points through which your application interacts with external resources, such as databases, external services, or message queues. They define what your application provides to the external world.",{"type":27,"tag":32,"props":10274,"children":10275},{},[10276],{"type":36,"value":10277},"Ports are defined as Java interfaces, for example, in the context of Spring Boot, they can be defined as Spring beans, ensuring that the core business logic interacts with the external world through these well-defined interfaces.",{"type":27,"tag":2478,"props":10279,"children":10281},{"id":10280},"adapters",[10282],{"type":36,"value":10283},"Adapters",{"type":27,"tag":32,"props":10285,"children":10286},{},[10287],{"type":36,"value":10288},"Adapters, on the other hand, are responsible for implementing the ports and enabling communication between the core business logic and external resources. Adapters bridge the gap between the application's internal interfaces (ports) and the external technologies and systems.",{"type":27,"tag":46,"props":10290,"children":10291},{},[10292,10302],{"type":27,"tag":50,"props":10293,"children":10294},{},[10295,10300],{"type":27,"tag":2410,"props":10296,"children":10297},{},[10298],{"type":36,"value":10299},"Primary Adapters (Inbound)",{"type":36,"value":10301},": These are implementations of the primary ports, allowing external systems to communicate with your application. For example, a REST controller that handles HTTP requests and routes them to the application's use cases.",{"type":27,"tag":50,"props":10303,"children":10304},{},[10305,10310],{"type":27,"tag":2410,"props":10306,"children":10307},{},[10308],{"type":36,"value":10309},"Secondary Adapters (Outbound)",{"type":36,"value":10311},": These are implementations of the secondary ports, facilitating communication between your application and external resources. This could include database repositories, external API clients, or message queue consumers.",{"type":27,"tag":32,"props":10313,"children":10314},{},[10315],{"type":36,"value":10316},"Adapters are responsible for translating external input into a format understandable by the core business logic and vice versa. They ensure that the application remains isolated from the specifics of the external technologies it interacts with.",{"type":27,"tag":39,"props":10318,"children":10320},{"id":10319},"structuring-a-spring-boot-project-with-hexagonal-architecture",[10321],{"type":36,"value":10322},"Structuring a Spring Boot Project with Hexagonal Architecture",{"type":27,"tag":32,"props":10324,"children":10325},{},[10326],{"type":36,"value":10327},"Now, let's explore how you can structure a Java (Spring Boot) project using Hexagonal Architecture. Here's an example structure:",{"type":27,"tag":77,"props":10329,"children":10333},{"className":10330,"code":10331,"language":10332,"meta":8,"style":8},"language-css shiki shiki-themes github-dark github-light","myapp/\n├── src/\n│   ├── main/\n│   │   ├── java/\n│   │   │   ├── com/\n│   │   │   │   ├── myapp/\n│   │   │   │   │   ├── application/\n│   │   │   │   │   │   ├── MyApplication.java\n│   │   │   │   │   │   └── ...\n│   │   │   │   │   ├── domain/\n│   │   │   │   │   │   ├── MyEntity.java\n│   │   │   │   │   │   └── ...\n│   │   │   │   │   ├── ports/\n│   │   │   │   │   │   ├── MyRepository.java\n│   │   │   │   │   │   └── ...\n│   │   │   │   │   └── ...\n│   │   │   │   ├── infrastructure/\n│   │   │   │   │   ├── adapter/\n│   │   │   │   │   │   ├── MyRepositoryImpl.java\n│   │   │   │   │   │   └── ...\n│   │   │   │   │   ├── web/\n│   │   │   │   │   │   ├── MyController.java\n│   │   │   │   │   │   └── ...\n│   │   │   │   │   └── ...\n│   ├── resources/\n│   └── ...\n└── ...\n","css",[10334],{"type":27,"tag":15,"props":10335,"children":10336},{"__ignoreMap":8},[10337,10345,10353,10361,10369,10377,10385,10393,10401,10409,10417,10425,10432,10440,10448,10455,10463,10471,10479,10487,10494,10502,10510,10518,10526,10535,10544],{"type":27,"tag":87,"props":10338,"children":10339},{"class":89,"line":90},[10340],{"type":27,"tag":87,"props":10341,"children":10342},{},[10343],{"type":36,"value":10344},"myapp/\n",{"type":27,"tag":87,"props":10346,"children":10347},{"class":89,"line":200},[10348],{"type":27,"tag":87,"props":10349,"children":10350},{},[10351],{"type":36,"value":10352},"├── src/\n",{"type":27,"tag":87,"props":10354,"children":10355},{"class":89,"line":222},[10356],{"type":27,"tag":87,"props":10357,"children":10358},{},[10359],{"type":36,"value":10360},"│   ├── main/\n",{"type":27,"tag":87,"props":10362,"children":10363},{"class":89,"line":235},[10364],{"type":27,"tag":87,"props":10365,"children":10366},{},[10367],{"type":36,"value":10368},"│   │   ├── java/\n",{"type":27,"tag":87,"props":10370,"children":10371},{"class":89,"line":257},[10372],{"type":27,"tag":87,"props":10373,"children":10374},{},[10375],{"type":36,"value":10376},"│   │   │   ├── com/\n",{"type":27,"tag":87,"props":10378,"children":10379},{"class":89,"line":267},[10380],{"type":27,"tag":87,"props":10381,"children":10382},{},[10383],{"type":36,"value":10384},"│   │   │   │   ├── myapp/\n",{"type":27,"tag":87,"props":10386,"children":10387},{"class":89,"line":276},[10388],{"type":27,"tag":87,"props":10389,"children":10390},{},[10391],{"type":36,"value":10392},"│   │   │   │   │   ├── application/\n",{"type":27,"tag":87,"props":10394,"children":10395},{"class":89,"line":284},[10396],{"type":27,"tag":87,"props":10397,"children":10398},{},[10399],{"type":36,"value":10400},"│   │   │   │   │   │   ├── MyApplication.java\n",{"type":27,"tag":87,"props":10402,"children":10403},{"class":89,"line":314},[10404],{"type":27,"tag":87,"props":10405,"children":10406},{},[10407],{"type":36,"value":10408},"│   │   │   │   │   │   └── ...\n",{"type":27,"tag":87,"props":10410,"children":10411},{"class":89,"line":341},[10412],{"type":27,"tag":87,"props":10413,"children":10414},{},[10415],{"type":36,"value":10416},"│   │   │   │   │   ├── domain/\n",{"type":27,"tag":87,"props":10418,"children":10419},{"class":89,"line":374},[10420],{"type":27,"tag":87,"props":10421,"children":10422},{},[10423],{"type":36,"value":10424},"│   │   │   │   │   │   ├── MyEntity.java\n",{"type":27,"tag":87,"props":10426,"children":10427},{"class":89,"line":699},[10428],{"type":27,"tag":87,"props":10429,"children":10430},{},[10431],{"type":36,"value":10408},{"type":27,"tag":87,"props":10433,"children":10434},{"class":89,"line":707},[10435],{"type":27,"tag":87,"props":10436,"children":10437},{},[10438],{"type":36,"value":10439},"│   │   │   │   │   ├── ports/\n",{"type":27,"tag":87,"props":10441,"children":10442},{"class":89,"line":725},[10443],{"type":27,"tag":87,"props":10444,"children":10445},{},[10446],{"type":36,"value":10447},"│   │   │   │   │   │   ├── MyRepository.java\n",{"type":27,"tag":87,"props":10449,"children":10450},{"class":89,"line":1039},[10451],{"type":27,"tag":87,"props":10452,"children":10453},{},[10454],{"type":36,"value":10408},{"type":27,"tag":87,"props":10456,"children":10457},{"class":89,"line":1052},[10458],{"type":27,"tag":87,"props":10459,"children":10460},{},[10461],{"type":36,"value":10462},"│   │   │   │   │   └── ...\n",{"type":27,"tag":87,"props":10464,"children":10465},{"class":89,"line":1060},[10466],{"type":27,"tag":87,"props":10467,"children":10468},{},[10469],{"type":36,"value":10470},"│   │   │   │   ├── infrastructure/\n",{"type":27,"tag":87,"props":10472,"children":10473},{"class":89,"line":1088},[10474],{"type":27,"tag":87,"props":10475,"children":10476},{},[10477],{"type":36,"value":10478},"│   │   │   │   │   ├── adapter/\n",{"type":27,"tag":87,"props":10480,"children":10481},{"class":89,"line":3553},[10482],{"type":27,"tag":87,"props":10483,"children":10484},{},[10485],{"type":36,"value":10486},"│   │   │   │   │   │   ├── MyRepositoryImpl.java\n",{"type":27,"tag":87,"props":10488,"children":10489},{"class":89,"line":3571},[10490],{"type":27,"tag":87,"props":10491,"children":10492},{},[10493],{"type":36,"value":10408},{"type":27,"tag":87,"props":10495,"children":10496},{"class":89,"line":3579},[10497],{"type":27,"tag":87,"props":10498,"children":10499},{},[10500],{"type":36,"value":10501},"│   │   │   │   │   ├── web/\n",{"type":27,"tag":87,"props":10503,"children":10504},{"class":89,"line":3600},[10505],{"type":27,"tag":87,"props":10506,"children":10507},{},[10508],{"type":36,"value":10509},"│   │   │   │   │   │   ├── MyController.java\n",{"type":27,"tag":87,"props":10511,"children":10513},{"class":89,"line":10512},23,[10514],{"type":27,"tag":87,"props":10515,"children":10516},{},[10517],{"type":36,"value":10408},{"type":27,"tag":87,"props":10519,"children":10521},{"class":89,"line":10520},24,[10522],{"type":27,"tag":87,"props":10523,"children":10524},{},[10525],{"type":36,"value":10462},{"type":27,"tag":87,"props":10527,"children":10529},{"class":89,"line":10528},25,[10530],{"type":27,"tag":87,"props":10531,"children":10532},{},[10533],{"type":36,"value":10534},"│   ├── resources/\n",{"type":27,"tag":87,"props":10536,"children":10538},{"class":89,"line":10537},26,[10539],{"type":27,"tag":87,"props":10540,"children":10541},{},[10542],{"type":36,"value":10543},"│   └── ...\n",{"type":27,"tag":87,"props":10545,"children":10547},{"class":89,"line":10546},27,[10548],{"type":27,"tag":87,"props":10549,"children":10550},{},[10551],{"type":36,"value":10552},"└── ...\n",{"type":27,"tag":32,"props":10554,"children":10555},{},[10556],{"type":36,"value":10557},"In this structure:",{"type":27,"tag":46,"props":10559,"children":10560},{},[10561,10572,10583,10593],{"type":27,"tag":50,"props":10562,"children":10563},{},[10564,10570],{"type":27,"tag":15,"props":10565,"children":10567},{"className":10566},[],[10568],{"type":36,"value":10569},"application",{"type":36,"value":10571},": Contains use cases and application services that orchestrate the core business logic.",{"type":27,"tag":50,"props":10573,"children":10574},{},[10575,10581],{"type":27,"tag":15,"props":10576,"children":10578},{"className":10577},[],[10579],{"type":36,"value":10580},"domain",{"type":36,"value":10582},": Holds the domain model, including entities, value objects, and domain-specific logic.",{"type":27,"tag":50,"props":10584,"children":10585},{},[10586,10591],{"type":27,"tag":15,"props":10587,"children":10589},{"className":10588},[],[10590],{"type":36,"value":10241},{"type":36,"value":10592},": Defines interfaces (ports) that the core business logic requires from external dependencies. Implementations of these interfaces are provided in the infrastructure package.",{"type":27,"tag":50,"props":10594,"children":10595},{},[10596,10602,10604],{"type":27,"tag":15,"props":10597,"children":10599},{"className":10598},[],[10600],{"type":36,"value":10601},"infrastructure",{"type":36,"value":10603},": Contains external adapters and implementations.",{"type":27,"tag":46,"props":10605,"children":10606},{},[10607,10618],{"type":27,"tag":50,"props":10608,"children":10609},{},[10610,10616],{"type":27,"tag":15,"props":10611,"children":10613},{"className":10612},[],[10614],{"type":36,"value":10615},"adapter",{"type":36,"value":10617},": Houses adapters that connect the application to external resources such as databases or message queues. For example, MyRepositoryImpl implements the MyRepository interface.",{"type":27,"tag":50,"props":10619,"children":10620},{},[10621,10627],{"type":27,"tag":15,"props":10622,"children":10624},{"className":10623},[],[10625],{"type":36,"value":10626},"web",{"type":36,"value":10628},": This is where you define your REST API controllers. MyController represents a RESTful API controller.",{"type":27,"tag":32,"props":10630,"children":10631},{},[10632],{"type":36,"value":10633},"With this structure, you maintain a clear separation between the core business logic (inside the application and domain packages) and the external interfaces (inside the infrastructure and web packages). This promotes testability, maintainability, and scalability while allowing you to leverage the Spring Boot framework for building RESTful APIs.",{"type":27,"tag":39,"props":10635,"children":10636},{"id":2315},[10637],{"type":36,"value":2318},{"type":27,"tag":32,"props":10639,"children":10640},{},[10641],{"type":36,"value":10642},"If you're interested in diving deeper into Hexagonal Architecture and its application in Spring Boot projects, here are some valuable resources to explore:",{"type":27,"tag":46,"props":10644,"children":10645},{},[10646,10661],{"type":27,"tag":50,"props":10647,"children":10648},{},[10649,10659],{"type":27,"tag":2410,"props":10650,"children":10651},{},[10652],{"type":27,"tag":1410,"props":10653,"children":10656},{"href":10654,"rel":10655},"https://alistair.cockburn.us/hexagonal-architecture/",[1414],[10657],{"type":36,"value":10658},"Hexagonal Architecture by Alistair Cockburn",{"type":36,"value":10660},": The original article by Alistair Cockburn, the creator of Hexagonal Architecture, provides an in-depth explanation of the concept.",{"type":27,"tag":50,"props":10662,"children":10663},{},[10664,10674],{"type":27,"tag":2410,"props":10665,"children":10666},{},[10667],{"type":27,"tag":1410,"props":10668,"children":10671},{"href":10669,"rel":10670},"https://www.oreilly.com/library/view/clean-architecture-a/9780134494272/",[1414],[10672],{"type":36,"value":10673},"Clean Architecture by Robert C. Martin",{"type":36,"value":10675},": Although not strictly Hexagonal Architecture, Clean Architecture shares similar principles and is worth exploring for a broader perspective on architectural patterns.",{"type":27,"tag":32,"props":10677,"children":10678},{},[10679],{"type":36,"value":10680},"These resources will provide you with a solid foundation and practical insights into Hexagonal Architecture, helping you design and build well-structured and maintainable software applications.",{"type":27,"tag":1439,"props":10682,"children":10683},{},[10684],{"type":36,"value":1443},{"title":8,"searchDepth":200,"depth":200,"links":10686},[10687,10688,10689,10693,10694],{"id":10082,"depth":200,"text":10085},{"id":10166,"depth":200,"text":10169},{"id":10230,"depth":200,"text":10233,"children":10690},[10691,10692],{"id":10241,"depth":222,"text":10244},{"id":10280,"depth":222,"text":10283},{"id":10319,"depth":200,"text":10322},{"id":2315,"depth":200,"text":2318},"content:posts:hexagonal-architecture.md","posts/hexagonal-architecture.md","posts/hexagonal-architecture",{"_path":10699,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":10700,"description":10701,"date":10702,"layout":12,"subtitle":10703,"image":10704,"optimized_image":10704,"category":15,"tags":10705,"author":22,"paginate":7,"body":10708,"_type":1455,"_id":11279,"_source":1457,"_file":11280,"_stem":11281,"_extension":1460},"/posts/terraform","Unleashing the Power of Infrastructure as Code (IaC)","Unleashing the Power of Infrastructure as Code (IaC) with Terraform","2023-09-24 18:00:00","with Terraform","/assets/img/uploads/infrastructure.jpg",[10706,10707],"sre","IaC",{"type":24,"children":10709,"toc":11273},[10710,10715,10721,10726,10732,10737,10961,10966,10972,10977,10990,11137,11142,11147,11189,11194,11199,11204,11208,11213,11264,11269],{"type":27,"tag":32,"props":10711,"children":10712},{},[10713],{"type":36,"value":10714},"In the rapidly evolving landscape of software development, Infrastructure as Code (IaC) has emerged as a pivotal paradigm. It revolutionizes the way we manage and provision infrastructure, and at the forefront of this revolution stands Terraform. In this post, we will embark on a practical journey to demystify IaC, understand Terraform's role, and explore essential Terraform concepts, culminating in a hands-on example of provisioning an S3 bucket using this powerful tool.",{"type":27,"tag":2478,"props":10716,"children":10718},{"id":10717},"what-is-infrastructure-as-code-iac",[10719],{"type":36,"value":10720},"What is Infrastructure as Code (IaC)?",{"type":27,"tag":32,"props":10722,"children":10723},{},[10724],{"type":36,"value":10725},"Infrastructure as Code (IaC) is a methodology that treats infrastructure provisioning and management as software development. Instead of manually configuring servers, networks, and other resources, IaC allows you to define infrastructure components in code. This code is version-controlled, tested, and deployed like any other software. The benefits are numerous: consistency, repeatability, scalability, and improved collaboration among development and operations teams.",{"type":27,"tag":2478,"props":10727,"children":10729},{"id":10728},"understanding-terraform-concepts",[10730],{"type":36,"value":10731},"Understanding Terraform Concepts",{"type":27,"tag":32,"props":10733,"children":10734},{},[10735],{"type":36,"value":10736},"Terraform operates on several fundamental concepts that are essential to grasp as you start working with this Infrastructure as Code (IaC) tool. Let's break them down with brief explanations:",{"type":27,"tag":46,"props":10738,"children":10739},{},[10740,10773,10804,10835,10866,10897,10930],{"type":27,"tag":50,"props":10741,"children":10742},{},[10743,10749,10750],{"type":27,"tag":15,"props":10744,"children":10746},{"className":10745},[],[10747],{"type":36,"value":10748},"Providers",{"type":36,"value":136},{"type":27,"tag":46,"props":10751,"children":10752},{},[10753,10763],{"type":27,"tag":50,"props":10754,"children":10755},{},[10756,10761],{"type":27,"tag":2410,"props":10757,"children":10758},{},[10759],{"type":36,"value":10760},"What Are They?:",{"type":36,"value":10762},"  Providers are responsible for bridging the gap between Terraform and various infrastructure platforms, such as cloud providers (AWS, Azure, GCP), on-premises environments, or third-party services.",{"type":27,"tag":50,"props":10764,"children":10765},{},[10766,10771],{"type":27,"tag":2410,"props":10767,"children":10768},{},[10769],{"type":36,"value":10770},"How They Work:",{"type":36,"value":10772}," Each provider has a set of configuration settings to authenticate and interact with a specific platform. Terraform uses these settings to establish connections and manage resources on the chosen platform.",{"type":27,"tag":50,"props":10774,"children":10775},{},[10776,10782,10783],{"type":27,"tag":15,"props":10777,"children":10779},{"className":10778},[],[10780],{"type":36,"value":10781},"Resources",{"type":36,"value":136},{"type":27,"tag":46,"props":10784,"children":10785},{},[10786,10795],{"type":27,"tag":50,"props":10787,"children":10788},{},[10789,10793],{"type":27,"tag":2410,"props":10790,"children":10791},{},[10792],{"type":36,"value":10760},{"type":36,"value":10794},"  Resources are individual infrastructure components that you want to create, manage, or delete using Terraform. They can represent anything from virtual machines and databases to networking elements and security groups.",{"type":27,"tag":50,"props":10796,"children":10797},{},[10798,10802],{"type":27,"tag":2410,"props":10799,"children":10800},{},[10801],{"type":36,"value":10770},{"type":36,"value":10803}," Resources are defined within provider blocks in your Terraform configuration. You specify the resource type, a unique name, and configuration settings to define the desired state of the resource.",{"type":27,"tag":50,"props":10805,"children":10806},{},[10807,10813,10814],{"type":27,"tag":15,"props":10808,"children":10810},{"className":10809},[],[10811],{"type":36,"value":10812},"Variables",{"type":36,"value":136},{"type":27,"tag":46,"props":10815,"children":10816},{},[10817,10826],{"type":27,"tag":50,"props":10818,"children":10819},{},[10820,10824],{"type":27,"tag":2410,"props":10821,"children":10822},{},[10823],{"type":36,"value":10760},{"type":36,"value":10825},"  Variables allow you to parameterize your Terraform configurations. They provide a way to input values that might change depending on the environment or use case.",{"type":27,"tag":50,"props":10827,"children":10828},{},[10829,10833],{"type":27,"tag":2410,"props":10830,"children":10831},{},[10832],{"type":36,"value":10770},{"type":36,"value":10834}," You define variables in your configuration, and they can be used throughout your Terraform code. Variables can be assigned default values or provided by external input files.",{"type":27,"tag":50,"props":10836,"children":10837},{},[10838,10844,10845],{"type":27,"tag":15,"props":10839,"children":10841},{"className":10840},[],[10842],{"type":36,"value":10843},"Data Sources",{"type":36,"value":136},{"type":27,"tag":46,"props":10846,"children":10847},{},[10848,10857],{"type":27,"tag":50,"props":10849,"children":10850},{},[10851,10855],{"type":27,"tag":2410,"props":10852,"children":10853},{},[10854],{"type":36,"value":10760},{"type":36,"value":10856},"  Data sources allow you to retrieve information from external sources and use it in your Terraform configurations. This could include data from AWS EC2 instances, DNS records, or even remote databases.",{"type":27,"tag":50,"props":10858,"children":10859},{},[10860,10864],{"type":27,"tag":2410,"props":10861,"children":10862},{},[10863],{"type":36,"value":10770},{"type":36,"value":10865}," You declare a data source in your configuration, specify its type and configuration settings, and then reference the data source's attributes in other parts of your code.",{"type":27,"tag":50,"props":10867,"children":10868},{},[10869,10875,10876],{"type":27,"tag":15,"props":10870,"children":10872},{"className":10871},[],[10873],{"type":36,"value":10874},"Outputs",{"type":36,"value":136},{"type":27,"tag":46,"props":10877,"children":10878},{},[10879,10888],{"type":27,"tag":50,"props":10880,"children":10881},{},[10882,10886],{"type":27,"tag":2410,"props":10883,"children":10884},{},[10885],{"type":36,"value":10760},{"type":36,"value":10887},"  Outputs allow you to expose specific values or attributes of resources or data sources for easy access after provisioning infrastructure. They are useful for sharing information with other parts of your system.",{"type":27,"tag":50,"props":10889,"children":10890},{},[10891,10895],{"type":27,"tag":2410,"props":10892,"children":10893},{},[10894],{"type":36,"value":10770},{"type":36,"value":10896}," You define output blocks in your Terraform configuration, specifying what values you want to expose. After applying the configuration, you can retrieve these values using terraform output.",{"type":27,"tag":50,"props":10898,"children":10899},{},[10900,10906,10907],{"type":27,"tag":15,"props":10901,"children":10903},{"className":10902},[],[10904],{"type":36,"value":10905},"State",{"type":36,"value":136},{"type":27,"tag":46,"props":10908,"children":10909},{},[10910,10920],{"type":27,"tag":50,"props":10911,"children":10912},{},[10913,10918],{"type":27,"tag":2410,"props":10914,"children":10915},{},[10916],{"type":36,"value":10917},"What Is It?:",{"type":36,"value":10919}," Terraform maintains a state file that records the current state of your managed infrastructure. This state file is crucial for tracking changes, enabling Terraform to understand what changes are necessary to achieve the desired state.",{"type":27,"tag":50,"props":10921,"children":10922},{},[10923,10928],{"type":27,"tag":2410,"props":10924,"children":10925},{},[10926],{"type":36,"value":10927},"How It Works:",{"type":36,"value":10929}," Terraform creates and manages the state file, which includes resource mappings and dependencies. It's stored locally by default but can be managed remotely for team collaboration.",{"type":27,"tag":50,"props":10931,"children":10932},{},[10933,10939,10940],{"type":27,"tag":15,"props":10934,"children":10936},{"className":10935},[],[10937],{"type":36,"value":10938},"Modules",{"type":36,"value":136},{"type":27,"tag":46,"props":10941,"children":10942},{},[10943,10952],{"type":27,"tag":50,"props":10944,"children":10945},{},[10946,10950],{"type":27,"tag":2410,"props":10947,"children":10948},{},[10949],{"type":36,"value":10760},{"type":36,"value":10951},"  Modules enable you to encapsulate and reuse parts of your Terraform configurations. They are like building blocks that help you structure and modularize your infrastructure code.",{"type":27,"tag":50,"props":10953,"children":10954},{},[10955,10959],{"type":27,"tag":2410,"props":10956,"children":10957},{},[10958],{"type":36,"value":10770},{"type":36,"value":10960}," You create modules by defining a set of resources, variables, and outputs within a directory. You can then reuse these modules across different projects, promoting code reuse and maintainability.",{"type":27,"tag":32,"props":10962,"children":10963},{},[10964],{"type":36,"value":10965},"These core Terraform concepts form the foundation of your Infrastructure as Code journey. Understanding how to use and manipulate them effectively will enable you to manage infrastructure efficiently and consistently, regardless of its complexity or scale.",{"type":27,"tag":2478,"props":10967,"children":10969},{"id":10968},"example-provisioning-an-s3-bucket-with-terraform",[10970],{"type":36,"value":10971},"Example: Provisioning an S3 Bucket with Terraform",{"type":27,"tag":32,"props":10973,"children":10974},{},[10975],{"type":36,"value":10976},"Now, let's get our hands dirty by provisioning an S3 bucket using Terraform. First, ensure you have Terraform installed on your machine.",{"type":27,"tag":32,"props":10978,"children":10979},{},[10980,10982,10988],{"type":36,"value":10981},"Create a Terraform configuration file, e.g., ",{"type":27,"tag":15,"props":10983,"children":10985},{"className":10984},[],[10986],{"type":36,"value":10987},"main.tf",{"type":36,"value":10989},", and add the following code:",{"type":27,"tag":77,"props":10991,"children":10995},{"className":10992,"code":10993,"language":10994,"meta":8,"style":8},"language-hcl shiki shiki-themes github-dark github-light","# Specify the AWS provider\nprovider \"aws\" {\n  region = \"us-east-1\"  # Choose your desired region\n}\n\n# Define an S3 bucket resource\nresource \"aws_s3_bucket\" \"example_bucket\" {\n  bucket = \"my-unique-bucket-name\"\n  acl    = \"private\"  # You can adjust access control here\n}\n","hcl",[10996],{"type":27,"tag":15,"props":10997,"children":10998},{"__ignoreMap":8},[10999,11007,11024,11046,11053,11060,11068,11090,11107,11130],{"type":27,"tag":87,"props":11000,"children":11001},{"class":89,"line":90},[11002],{"type":27,"tag":87,"props":11003,"children":11004},{"style":1794},[11005],{"type":36,"value":11006},"# Specify the AWS provider\n",{"type":27,"tag":87,"props":11008,"children":11009},{"class":89,"line":200},[11010,11015,11020],{"type":27,"tag":87,"props":11011,"children":11012},{"style":94},[11013],{"type":36,"value":11014},"provider",{"type":27,"tag":87,"props":11016,"children":11017},{"style":288},[11018],{"type":36,"value":11019}," \"aws\"",{"type":27,"tag":87,"props":11021,"children":11022},{"style":184},[11023],{"type":36,"value":4683},{"type":27,"tag":87,"props":11025,"children":11026},{"class":89,"line":222},[11027,11032,11036,11041],{"type":27,"tag":87,"props":11028,"children":11029},{"style":184},[11030],{"type":36,"value":11031},"  region",{"type":27,"tag":87,"props":11033,"children":11034},{"style":178},[11035],{"type":36,"value":296},{"type":27,"tag":87,"props":11037,"children":11038},{"style":100},[11039],{"type":36,"value":11040}," \"us-east-1\"",{"type":27,"tag":87,"props":11042,"children":11043},{"style":1794},[11044],{"type":36,"value":11045},"  # Choose your desired region\n",{"type":27,"tag":87,"props":11047,"children":11048},{"class":89,"line":235},[11049],{"type":27,"tag":87,"props":11050,"children":11051},{"style":184},[11052],{"type":36,"value":1805},{"type":27,"tag":87,"props":11054,"children":11055},{"class":89,"line":257},[11056],{"type":27,"tag":87,"props":11057,"children":11058},{"emptyLinePlaceholder":261},[11059],{"type":36,"value":264},{"type":27,"tag":87,"props":11061,"children":11062},{"class":89,"line":267},[11063],{"type":27,"tag":87,"props":11064,"children":11065},{"style":1794},[11066],{"type":36,"value":11067},"# Define an S3 bucket resource\n",{"type":27,"tag":87,"props":11069,"children":11070},{"class":89,"line":276},[11071,11076,11081,11086],{"type":27,"tag":87,"props":11072,"children":11073},{"style":94},[11074],{"type":36,"value":11075},"resource",{"type":27,"tag":87,"props":11077,"children":11078},{"style":288},[11079],{"type":36,"value":11080}," \"aws_s3_bucket\"",{"type":27,"tag":87,"props":11082,"children":11083},{"style":288},[11084],{"type":36,"value":11085}," \"example_bucket\"",{"type":27,"tag":87,"props":11087,"children":11088},{"style":184},[11089],{"type":36,"value":4683},{"type":27,"tag":87,"props":11091,"children":11092},{"class":89,"line":284},[11093,11098,11102],{"type":27,"tag":87,"props":11094,"children":11095},{"style":184},[11096],{"type":36,"value":11097},"  bucket",{"type":27,"tag":87,"props":11099,"children":11100},{"style":178},[11101],{"type":36,"value":296},{"type":27,"tag":87,"props":11103,"children":11104},{"style":100},[11105],{"type":36,"value":11106}," \"my-unique-bucket-name\"\n",{"type":27,"tag":87,"props":11108,"children":11109},{"class":89,"line":314},[11110,11115,11120,11125],{"type":27,"tag":87,"props":11111,"children":11112},{"style":184},[11113],{"type":36,"value":11114},"  acl",{"type":27,"tag":87,"props":11116,"children":11117},{"style":178},[11118],{"type":36,"value":11119},"    =",{"type":27,"tag":87,"props":11121,"children":11122},{"style":100},[11123],{"type":36,"value":11124}," \"private\"",{"type":27,"tag":87,"props":11126,"children":11127},{"style":1794},[11128],{"type":36,"value":11129},"  # You can adjust access control here\n",{"type":27,"tag":87,"props":11131,"children":11132},{"class":89,"line":341},[11133],{"type":27,"tag":87,"props":11134,"children":11135},{"style":184},[11136],{"type":36,"value":1805},{"type":27,"tag":32,"props":11138,"children":11139},{},[11140],{"type":36,"value":11141},"This Terraform configuration specifies an AWS provider and creates an S3 bucket resource with a unique name. Replace \"my-unique-bucket-name\" with your preferred bucket name.",{"type":27,"tag":32,"props":11143,"children":11144},{},[11145],{"type":36,"value":11146},"To apply this configuration, navigate to the directory containing main.tf and run the following commands:",{"type":27,"tag":77,"props":11148,"children":11150},{"className":79,"code":11149,"language":81,"meta":8,"style":8},"terraform init  # Initialize the Terraform working directory\nterraform apply # Create the S3 bucket\n",[11151],{"type":27,"tag":15,"props":11152,"children":11153},{"__ignoreMap":8},[11154,11172],{"type":27,"tag":87,"props":11155,"children":11156},{"class":89,"line":90},[11157,11162,11167],{"type":27,"tag":87,"props":11158,"children":11159},{"style":94},[11160],{"type":36,"value":11161},"terraform",{"type":27,"tag":87,"props":11163,"children":11164},{"style":100},[11165],{"type":36,"value":11166}," init",{"type":27,"tag":87,"props":11168,"children":11169},{"style":1794},[11170],{"type":36,"value":11171},"  # Initialize the Terraform working directory\n",{"type":27,"tag":87,"props":11173,"children":11174},{"class":89,"line":200},[11175,11179,11184],{"type":27,"tag":87,"props":11176,"children":11177},{"style":94},[11178],{"type":36,"value":11161},{"type":27,"tag":87,"props":11180,"children":11181},{"style":100},[11182],{"type":36,"value":11183}," apply",{"type":27,"tag":87,"props":11185,"children":11186},{"style":1794},[11187],{"type":36,"value":11188}," # Create the S3 bucket\n",{"type":27,"tag":32,"props":11190,"children":11191},{},[11192],{"type":36,"value":11193},"Terraform will prompt you to confirm the resource creation. Type \"yes\" and press Enter. Terraform will provision the S3 bucket according to your configuration.",{"type":27,"tag":32,"props":11195,"children":11196},{},[11197],{"type":36,"value":11198},"Congratulations! You've just provisioned an S3 bucket using Terraform. You can now manage your infrastructure as code, track changes, and apply updates with ease.",{"type":27,"tag":32,"props":11200,"children":11201},{},[11202],{"type":36,"value":11203},"In this post, we've only scratched the surface of Terraform's capabilities. Explore its extensive documentation and dive deeper into its features to harness the full potential of Infrastructure as Code with Terraform.",{"type":27,"tag":2478,"props":11205,"children":11206},{"id":2315},[11207],{"type":36,"value":2318},{"type":27,"tag":32,"props":11209,"children":11210},{},[11211],{"type":36,"value":11212},"To deepen your understanding of Terraform and explore its capabilities in more detail, here are some valuable resources from official documentation and provider-specific documentation:",{"type":27,"tag":46,"props":11214,"children":11215},{},[11216,11228,11240,11252],{"type":27,"tag":50,"props":11217,"children":11218},{},[11219,11226],{"type":27,"tag":1410,"props":11220,"children":11223},{"href":11221,"rel":11222},"https://www.terraform.io/docs/index.html",[1414],[11224],{"type":36,"value":11225},"Terraform Official Documentation (HashiCorp)",{"type":36,"value":11227}," The official Terraform documentation is an excellent starting point for learning the tool, understanding its features, and accessing in-depth guides and reference materials.",{"type":27,"tag":50,"props":11229,"children":11230},{},[11231,11238],{"type":27,"tag":1410,"props":11232,"children":11235},{"href":11233,"rel":11234},"https://registry.terraform.io/providers/hashicorp/aws/latest/docs",[1414],[11236],{"type":36,"value":11237},"AWS Provider Documentation",{"type":36,"value":11239},": If you plan to use Terraform with AWS, the official AWS Provider documentation provides comprehensive information on configuring and managing AWS resources using Terraform.",{"type":27,"tag":50,"props":11241,"children":11242},{},[11243,11250],{"type":27,"tag":1410,"props":11244,"children":11247},{"href":11245,"rel":11246},"https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs",[1414],[11248],{"type":36,"value":11249},"Azure Provider Documentation",{"type":36,"value":11251},": For Azure users, the official Azure Provider documentation offers detailed guidance on working with Azure resources through Terraform.",{"type":27,"tag":50,"props":11253,"children":11254},{},[11255,11262],{"type":27,"tag":1410,"props":11256,"children":11259},{"href":11257,"rel":11258},"https://registry.terraform.io/providers/hashicorp/google/latest/docs",[1414],[11260],{"type":36,"value":11261},"Google Cloud Provider Documentation",{"type":36,"value":11263},": If Google Cloud is your chosen platform, the official Google Cloud Provider documentation provides valuable insights into Terraform's integration with Google Cloud resources.",{"type":27,"tag":32,"props":11265,"children":11266},{},[11267],{"type":36,"value":11268},"These resources serve as essential references as you explore Terraform and its integration with various cloud providers. Whether you're just getting started or looking to dive deeper into specific topics, these official documents will be invaluable in your Terraform journey.",{"type":27,"tag":1439,"props":11270,"children":11271},{},[11272],{"type":36,"value":1443},{"title":8,"searchDepth":200,"depth":200,"links":11274},[11275,11276,11277,11278],{"id":10717,"depth":222,"text":10720},{"id":10728,"depth":222,"text":10731},{"id":10968,"depth":222,"text":10971},{"id":2315,"depth":222,"text":2318},"content:posts:terraform.md","posts/terraform.md","posts/terraform",{"_path":11283,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":11284,"description":11285,"date":11286,"layout":12,"subtitle":11287,"image":11288,"optimized_image":11288,"category":15,"tags":11289,"author":22,"paginate":7,"body":11290,"_type":1455,"_id":11566,"_source":1457,"_file":11567,"_stem":11568,"_extension":1460},"/posts/python-virtual-environments","Python Virtual Environments (venv)","A Comprehensive Guide to Python Virtual Environments (venv)","2023-09-17 22:00:00","A Comprehensive Guide","/assets/img/uploads/python-image.jpg",[168,15],{"type":24,"children":11291,"toc":11561},[11292,11297,11303,11308,11326,11332,11337,11342,11484,11490,11495,11523,11528,11533,11552,11557],{"type":27,"tag":32,"props":11293,"children":11294},{},[11295],{"type":36,"value":11296},"In the world of Python development, managing dependencies can be a challenging task. You might encounter situations where different projects require different versions of the same library, or you simply want to isolate your project's environment to ensure consistency. That's where Python's venv comes into play. In this tutorial, we'll explore the advantages of using venv in your Python projects, guide you through its installation using pip, and provide an example of how to install dependencies and execute a Python script within your virtual environment.",{"type":27,"tag":39,"props":11298,"children":11300},{"id":11299},"advantages-of-using-venv",[11301],{"type":36,"value":11302},"Advantages of Using venv",{"type":27,"tag":32,"props":11304,"children":11305},{},[11306],{"type":36,"value":11307},"Python's venv module, introduced in Python 3.3, allows you to create isolated Python environments for your projects. Here are some of the key advantages:",{"type":27,"tag":46,"props":11309,"children":11310},{},[11311,11316,11321],{"type":27,"tag":50,"props":11312,"children":11313},{},[11314],{"type":36,"value":11315},"Dependency Isolation: venv allows you to create a self-contained environment for each project. This means you can have different versions of Python and project-specific libraries without conflicts.",{"type":27,"tag":50,"props":11317,"children":11318},{},[11319],{"type":36,"value":11320},"Version Control Integration: Including your virtual environment in version control (e.g., Git) ensures that others can recreate your development environment precisely, making collaboration smoother.",{"type":27,"tag":50,"props":11322,"children":11323},{},[11324],{"type":36,"value":11325},"Easy Cleanup: Virtual environments are easy to create and delete, so you can keep your system clean by removing unused environments when you're done with a project.",{"type":27,"tag":39,"props":11327,"children":11329},{"id":11328},"installing-venv-with-pip",[11330],{"type":36,"value":11331},"Installing venv with pip",{"type":27,"tag":32,"props":11333,"children":11334},{},[11335],{"type":36,"value":11336},"Before you can create virtual environments with venv, make sure you have Python 3.3 or higher installed on your system. Most modern Python installations come with venv included, so you don't need to install it separately.",{"type":27,"tag":32,"props":11338,"children":11339},{},[11340],{"type":36,"value":11341},"To create a new virtual environment, follow these steps:",{"type":27,"tag":1495,"props":11343,"children":11344},{},[11345,11350,11355,11394],{"type":27,"tag":50,"props":11346,"children":11347},{},[11348],{"type":36,"value":11349},"Open your terminal or command prompt.",{"type":27,"tag":50,"props":11351,"children":11352},{},[11353],{"type":36,"value":11354},"Navigate to the directory where you want to create the virtual environment.",{"type":27,"tag":50,"props":11356,"children":11357},{},[11358,11360],{"type":36,"value":11359},"Run the following command to create a new virtual environment named \"myenv\" (you can replace \"myenv\" with your preferred name):",{"type":27,"tag":77,"props":11361,"children":11363},{"className":79,"code":11362,"language":81,"meta":8,"style":8},"$ python -m venv myenv\n",[11364],{"type":27,"tag":15,"props":11365,"children":11366},{"__ignoreMap":8},[11367],{"type":27,"tag":87,"props":11368,"children":11369},{"class":89,"line":90},[11370,11375,11380,11384,11389],{"type":27,"tag":87,"props":11371,"children":11372},{"style":94},[11373],{"type":36,"value":11374},"$",{"type":27,"tag":87,"props":11376,"children":11377},{"style":100},[11378],{"type":36,"value":11379}," python",{"type":27,"tag":87,"props":11381,"children":11382},{"style":288},[11383],{"type":36,"value":3999},{"type":27,"tag":87,"props":11385,"children":11386},{"style":100},[11387],{"type":36,"value":11388}," venv",{"type":27,"tag":87,"props":11390,"children":11391},{"style":100},[11392],{"type":36,"value":11393}," myenv\n",{"type":27,"tag":50,"props":11395,"children":11396},{},[11397,11399,11407,11446,11454,11478,11482],{"type":36,"value":11398},"To activate the virtual environment, use the appropriate command for your operating system:",{"type":27,"tag":46,"props":11400,"children":11401},{},[11402],{"type":27,"tag":50,"props":11403,"children":11404},{},[11405],{"type":36,"value":11406},"On Windows:",{"type":27,"tag":77,"props":11408,"children":11410},{"className":79,"code":11409,"language":81,"meta":8,"style":8},"$ myenv\\Scripts\\activate\n",[11411],{"type":27,"tag":15,"props":11412,"children":11413},{"__ignoreMap":8},[11414],{"type":27,"tag":87,"props":11415,"children":11416},{"class":89,"line":90},[11417,11421,11426,11431,11436,11441],{"type":27,"tag":87,"props":11418,"children":11419},{"style":94},[11420],{"type":36,"value":11374},{"type":27,"tag":87,"props":11422,"children":11423},{"style":100},[11424],{"type":36,"value":11425}," myenv",{"type":27,"tag":87,"props":11427,"children":11428},{"style":288},[11429],{"type":36,"value":11430},"\\S",{"type":27,"tag":87,"props":11432,"children":11433},{"style":100},[11434],{"type":36,"value":11435},"cripts",{"type":27,"tag":87,"props":11437,"children":11438},{"style":288},[11439],{"type":36,"value":11440},"\\a",{"type":27,"tag":87,"props":11442,"children":11443},{"style":100},[11444],{"type":36,"value":11445},"ctivate\n",{"type":27,"tag":46,"props":11447,"children":11448},{},[11449],{"type":27,"tag":50,"props":11450,"children":11451},{},[11452],{"type":36,"value":11453},"On macOS and Linux:",{"type":27,"tag":77,"props":11455,"children":11457},{"className":79,"code":11456,"language":81,"meta":8,"style":8},"$ source myenv/bin/activate\n",[11458],{"type":27,"tag":15,"props":11459,"children":11460},{"__ignoreMap":8},[11461],{"type":27,"tag":87,"props":11462,"children":11463},{"class":89,"line":90},[11464,11468,11473],{"type":27,"tag":87,"props":11465,"children":11466},{"style":94},[11467],{"type":36,"value":11374},{"type":27,"tag":87,"props":11469,"children":11470},{"style":100},[11471],{"type":36,"value":11472}," source",{"type":27,"tag":87,"props":11474,"children":11475},{"style":100},[11476],{"type":36,"value":11477}," myenv/bin/activate\n",{"type":27,"tag":11479,"props":11480,"children":11481},"br",{},[],{"type":36,"value":11483},"Once activated, your terminal prompt will change, indicating that you are now working within the virtual environment.",{"type":27,"tag":39,"props":11485,"children":11487},{"id":11486},"installing-dependencies-and-running-a-python-script",[11488],{"type":36,"value":11489},"Installing Dependencies and Running a Python Script",{"type":27,"tag":32,"props":11491,"children":11492},{},[11493],{"type":36,"value":11494},"Now that you're inside your virtual environment, you can install project-specific dependencies using pip. For example, let's install the popular library requests:",{"type":27,"tag":77,"props":11496,"children":11498},{"className":79,"code":11497,"language":81,"meta":8,"style":8},"$ pip install requests\n",[11499],{"type":27,"tag":15,"props":11500,"children":11501},{"__ignoreMap":8},[11502],{"type":27,"tag":87,"props":11503,"children":11504},{"class":89,"line":90},[11505,11509,11514,11518],{"type":27,"tag":87,"props":11506,"children":11507},{"style":94},[11508],{"type":36,"value":11374},{"type":27,"tag":87,"props":11510,"children":11511},{"style":100},[11512],{"type":36,"value":11513}," pip",{"type":27,"tag":87,"props":11515,"children":11516},{"style":100},[11517],{"type":36,"value":103},{"type":27,"tag":87,"props":11519,"children":11520},{"style":100},[11521],{"type":36,"value":11522}," requests\n",{"type":27,"tag":32,"props":11524,"children":11525},{},[11526],{"type":36,"value":11527},"With your dependencies installed, you can create a Python script or use an existing one within the virtual environment. To run your script, simply execute it as you normally would. All the installed packages will be available for your script to use without affecting the global Python environment.",{"type":27,"tag":32,"props":11529,"children":11530},{},[11531],{"type":36,"value":11532},"When you're done working on your project, you can deactivate the virtual environment with the following command:",{"type":27,"tag":77,"props":11534,"children":11536},{"className":79,"code":11535,"language":81,"meta":8,"style":8},"$ deactivate\n",[11537],{"type":27,"tag":15,"props":11538,"children":11539},{"__ignoreMap":8},[11540],{"type":27,"tag":87,"props":11541,"children":11542},{"class":89,"line":90},[11543,11547],{"type":27,"tag":87,"props":11544,"children":11545},{"style":94},[11546],{"type":36,"value":11374},{"type":27,"tag":87,"props":11548,"children":11549},{"style":100},[11550],{"type":36,"value":11551}," deactivate\n",{"type":27,"tag":32,"props":11553,"children":11554},{},[11555],{"type":36,"value":11556},"And that's it! You've successfully set up and used a virtual environment with venv in Python. This tool is invaluable for managing dependencies and keeping your projects organized. Incorporate venv into your Python development workflow to take full advantage of its benefits.",{"type":27,"tag":1439,"props":11558,"children":11559},{},[11560],{"type":36,"value":1443},{"title":8,"searchDepth":200,"depth":200,"links":11562},[11563,11564,11565],{"id":11299,"depth":200,"text":11302},{"id":11328,"depth":200,"text":11331},{"id":11486,"depth":200,"text":11489},"content:posts:python-virtual-environments.md","posts/python-virtual-environments.md","posts/python-virtual-environments",{"_path":11570,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":11571,"description":11572,"date":11573,"layout":12,"subtitle":11574,"image":11575,"optimized_image":11575,"category":15,"tags":11576,"author":22,"paginate":7,"body":11579,"_type":1455,"_id":12255,"_source":1457,"_file":12256,"_stem":12257,"_extension":1460},"/posts/api-first-principles","API First principles","API First principles explained with examples","2023-09-01 22:15:18","Exploring OpenAPI with YAML","/assets/img/uploads/connection-train.jpg",[11577,11578],"api-first","openapi",{"type":24,"children":11580,"toc":12250},[11581,11586,11592,11597,11603,11608,11613,11618,12227,12232,12236,12241,12246],{"type":27,"tag":32,"props":11582,"children":11583},{},[11584],{"type":36,"value":11585},"In the ever-evolving world of software development, embracing the \"API First\" philosophy has become a pivotal strategy. This approach prioritizes the design and development of Application Programming Interfaces (APIs) at the forefront of any software project. It not only streamlines development processes but also fosters collaboration and innovation. In this post, we'll delve into the concept of API-First and explore OpenAPI, a powerful tool for defining, documenting, and managing APIs.",{"type":27,"tag":39,"props":11587,"children":11589},{"id":11588},"understanding-api-first",[11590],{"type":36,"value":11591},"Understanding API First",{"type":27,"tag":32,"props":11593,"children":11594},{},[11595],{"type":36,"value":11596},"The API-First approach is a mindset that centers around designing APIs before any other aspect of a software project. It shifts the focus from coding to defining clear, standardized interfaces that different parts of the software can communicate through. This methodology promotes a structured and modular architecture, making it easier to adapt and scale applications over time.",{"type":27,"tag":39,"props":11598,"children":11600},{"id":11599},"introducing-openapi",[11601],{"type":36,"value":11602},"Introducing OpenAPI",{"type":27,"tag":32,"props":11604,"children":11605},{},[11606],{"type":36,"value":11607},"OpenAPI, formerly known as Swagger, is a specification for building and documenting RESTful APIs. It offers a standardized way to define API endpoints, request/response formats, and authentication methods. OpenAPI enables teams to create clear, machine-readable API contracts, making it a fundamental part of the API-First philosophy.",{"type":27,"tag":32,"props":11609,"children":11610},{},[11611],{"type":36,"value":11612},"Example: YAML-based API Contract",{"type":27,"tag":32,"props":11614,"children":11615},{},[11616],{"type":36,"value":11617},"Let's dive into a practical example of an API contract using YAML. Below is a simplified representation of an e-commerce API for managing products:",{"type":27,"tag":77,"props":11619,"children":11623},{"className":11620,"code":11621,"language":11622,"meta":8,"style":8},"language-yaml shiki shiki-themes github-dark github-light","openapi: 3.0.0\ninfo:\n  title: E-Commerce API\n  version: 1.0.0\npaths:\n  /products:\n    get:\n      summary: Get a list of products\n      responses:\n        '200':\n          description: Successful response\n          content:\n            application/json:\n              schema:\n                type: array\n                items:\n                  $ref: '#/components/schemas/Product'\n    post:\n      summary: Create a new product\n      requestBody:\n        required: true\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/Product'\n      responses:\n        '201':\n          description: Product created successfully\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/Product'\ncomponents:\n  schemas:\n    Product:\n      type: object\n      properties:\n        id:\n          type: integer\n        name:\n          type: string\n        price:\n          type: number\n","yaml",[11624],{"type":27,"tag":15,"props":11625,"children":11626},{"__ignoreMap":8},[11627,11643,11655,11672,11689,11701,11713,11725,11742,11754,11766,11783,11795,11807,11819,11836,11848,11865,11877,11893,11905,11921,11933,11945,11957,11973,11984,11996,12013,12025,12037,12049,12066,12079,12092,12105,12123,12136,12149,12167,12180,12197,12210],{"type":27,"tag":87,"props":11628,"children":11629},{"class":89,"line":90},[11630,11634,11638],{"type":27,"tag":87,"props":11631,"children":11632},{"style":2147},[11633],{"type":36,"value":11578},{"type":27,"tag":87,"props":11635,"children":11636},{"style":184},[11637],{"type":36,"value":907},{"type":27,"tag":87,"props":11639,"children":11640},{"style":288},[11641],{"type":36,"value":11642},"3.0.0\n",{"type":27,"tag":87,"props":11644,"children":11645},{"class":89,"line":200},[11646,11651],{"type":27,"tag":87,"props":11647,"children":11648},{"style":2147},[11649],{"type":36,"value":11650},"info",{"type":27,"tag":87,"props":11652,"children":11653},{"style":184},[11654],{"type":36,"value":1216},{"type":27,"tag":87,"props":11656,"children":11657},{"class":89,"line":222},[11658,11663,11667],{"type":27,"tag":87,"props":11659,"children":11660},{"style":2147},[11661],{"type":36,"value":11662},"  title",{"type":27,"tag":87,"props":11664,"children":11665},{"style":184},[11666],{"type":36,"value":907},{"type":27,"tag":87,"props":11668,"children":11669},{"style":100},[11670],{"type":36,"value":11671},"E-Commerce API\n",{"type":27,"tag":87,"props":11673,"children":11674},{"class":89,"line":235},[11675,11680,11684],{"type":27,"tag":87,"props":11676,"children":11677},{"style":2147},[11678],{"type":36,"value":11679},"  version",{"type":27,"tag":87,"props":11681,"children":11682},{"style":184},[11683],{"type":36,"value":907},{"type":27,"tag":87,"props":11685,"children":11686},{"style":288},[11687],{"type":36,"value":11688},"1.0.0\n",{"type":27,"tag":87,"props":11690,"children":11691},{"class":89,"line":257},[11692,11697],{"type":27,"tag":87,"props":11693,"children":11694},{"style":2147},[11695],{"type":36,"value":11696},"paths",{"type":27,"tag":87,"props":11698,"children":11699},{"style":184},[11700],{"type":36,"value":1216},{"type":27,"tag":87,"props":11702,"children":11703},{"class":89,"line":267},[11704,11709],{"type":27,"tag":87,"props":11705,"children":11706},{"style":2147},[11707],{"type":36,"value":11708},"  /products",{"type":27,"tag":87,"props":11710,"children":11711},{"style":184},[11712],{"type":36,"value":1216},{"type":27,"tag":87,"props":11714,"children":11715},{"class":89,"line":276},[11716,11721],{"type":27,"tag":87,"props":11717,"children":11718},{"style":2147},[11719],{"type":36,"value":11720},"    get",{"type":27,"tag":87,"props":11722,"children":11723},{"style":184},[11724],{"type":36,"value":1216},{"type":27,"tag":87,"props":11726,"children":11727},{"class":89,"line":284},[11728,11733,11737],{"type":27,"tag":87,"props":11729,"children":11730},{"style":2147},[11731],{"type":36,"value":11732},"      summary",{"type":27,"tag":87,"props":11734,"children":11735},{"style":184},[11736],{"type":36,"value":907},{"type":27,"tag":87,"props":11738,"children":11739},{"style":100},[11740],{"type":36,"value":11741},"Get a list of products\n",{"type":27,"tag":87,"props":11743,"children":11744},{"class":89,"line":314},[11745,11750],{"type":27,"tag":87,"props":11746,"children":11747},{"style":2147},[11748],{"type":36,"value":11749},"      responses",{"type":27,"tag":87,"props":11751,"children":11752},{"style":184},[11753],{"type":36,"value":1216},{"type":27,"tag":87,"props":11755,"children":11756},{"class":89,"line":341},[11757,11762],{"type":27,"tag":87,"props":11758,"children":11759},{"style":100},[11760],{"type":36,"value":11761},"        '200'",{"type":27,"tag":87,"props":11763,"children":11764},{"style":184},[11765],{"type":36,"value":1216},{"type":27,"tag":87,"props":11767,"children":11768},{"class":89,"line":374},[11769,11774,11778],{"type":27,"tag":87,"props":11770,"children":11771},{"style":2147},[11772],{"type":36,"value":11773},"          description",{"type":27,"tag":87,"props":11775,"children":11776},{"style":184},[11777],{"type":36,"value":907},{"type":27,"tag":87,"props":11779,"children":11780},{"style":100},[11781],{"type":36,"value":11782},"Successful response\n",{"type":27,"tag":87,"props":11784,"children":11785},{"class":89,"line":699},[11786,11791],{"type":27,"tag":87,"props":11787,"children":11788},{"style":2147},[11789],{"type":36,"value":11790},"          content",{"type":27,"tag":87,"props":11792,"children":11793},{"style":184},[11794],{"type":36,"value":1216},{"type":27,"tag":87,"props":11796,"children":11797},{"class":89,"line":707},[11798,11803],{"type":27,"tag":87,"props":11799,"children":11800},{"style":2147},[11801],{"type":36,"value":11802},"            application/json",{"type":27,"tag":87,"props":11804,"children":11805},{"style":184},[11806],{"type":36,"value":1216},{"type":27,"tag":87,"props":11808,"children":11809},{"class":89,"line":725},[11810,11815],{"type":27,"tag":87,"props":11811,"children":11812},{"style":2147},[11813],{"type":36,"value":11814},"              schema",{"type":27,"tag":87,"props":11816,"children":11817},{"style":184},[11818],{"type":36,"value":1216},{"type":27,"tag":87,"props":11820,"children":11821},{"class":89,"line":1039},[11822,11827,11831],{"type":27,"tag":87,"props":11823,"children":11824},{"style":2147},[11825],{"type":36,"value":11826},"                type",{"type":27,"tag":87,"props":11828,"children":11829},{"style":184},[11830],{"type":36,"value":907},{"type":27,"tag":87,"props":11832,"children":11833},{"style":100},[11834],{"type":36,"value":11835},"array\n",{"type":27,"tag":87,"props":11837,"children":11838},{"class":89,"line":1052},[11839,11844],{"type":27,"tag":87,"props":11840,"children":11841},{"style":2147},[11842],{"type":36,"value":11843},"                items",{"type":27,"tag":87,"props":11845,"children":11846},{"style":184},[11847],{"type":36,"value":1216},{"type":27,"tag":87,"props":11849,"children":11850},{"class":89,"line":1060},[11851,11856,11860],{"type":27,"tag":87,"props":11852,"children":11853},{"style":2147},[11854],{"type":36,"value":11855},"                  $ref",{"type":27,"tag":87,"props":11857,"children":11858},{"style":184},[11859],{"type":36,"value":907},{"type":27,"tag":87,"props":11861,"children":11862},{"style":100},[11863],{"type":36,"value":11864},"'#/components/schemas/Product'\n",{"type":27,"tag":87,"props":11866,"children":11867},{"class":89,"line":1088},[11868,11873],{"type":27,"tag":87,"props":11869,"children":11870},{"style":2147},[11871],{"type":36,"value":11872},"    post",{"type":27,"tag":87,"props":11874,"children":11875},{"style":184},[11876],{"type":36,"value":1216},{"type":27,"tag":87,"props":11878,"children":11879},{"class":89,"line":3553},[11880,11884,11888],{"type":27,"tag":87,"props":11881,"children":11882},{"style":2147},[11883],{"type":36,"value":11732},{"type":27,"tag":87,"props":11885,"children":11886},{"style":184},[11887],{"type":36,"value":907},{"type":27,"tag":87,"props":11889,"children":11890},{"style":100},[11891],{"type":36,"value":11892},"Create a new product\n",{"type":27,"tag":87,"props":11894,"children":11895},{"class":89,"line":3571},[11896,11901],{"type":27,"tag":87,"props":11897,"children":11898},{"style":2147},[11899],{"type":36,"value":11900},"      requestBody",{"type":27,"tag":87,"props":11902,"children":11903},{"style":184},[11904],{"type":36,"value":1216},{"type":27,"tag":87,"props":11906,"children":11907},{"class":89,"line":3579},[11908,11913,11917],{"type":27,"tag":87,"props":11909,"children":11910},{"style":2147},[11911],{"type":36,"value":11912},"        required",{"type":27,"tag":87,"props":11914,"children":11915},{"style":184},[11916],{"type":36,"value":907},{"type":27,"tag":87,"props":11918,"children":11919},{"style":288},[11920],{"type":36,"value":3761},{"type":27,"tag":87,"props":11922,"children":11923},{"class":89,"line":3600},[11924,11929],{"type":27,"tag":87,"props":11925,"children":11926},{"style":2147},[11927],{"type":36,"value":11928},"        content",{"type":27,"tag":87,"props":11930,"children":11931},{"style":184},[11932],{"type":36,"value":1216},{"type":27,"tag":87,"props":11934,"children":11935},{"class":89,"line":10512},[11936,11941],{"type":27,"tag":87,"props":11937,"children":11938},{"style":2147},[11939],{"type":36,"value":11940},"          application/json",{"type":27,"tag":87,"props":11942,"children":11943},{"style":184},[11944],{"type":36,"value":1216},{"type":27,"tag":87,"props":11946,"children":11947},{"class":89,"line":10520},[11948,11953],{"type":27,"tag":87,"props":11949,"children":11950},{"style":2147},[11951],{"type":36,"value":11952},"            schema",{"type":27,"tag":87,"props":11954,"children":11955},{"style":184},[11956],{"type":36,"value":1216},{"type":27,"tag":87,"props":11958,"children":11959},{"class":89,"line":10528},[11960,11965,11969],{"type":27,"tag":87,"props":11961,"children":11962},{"style":2147},[11963],{"type":36,"value":11964},"              $ref",{"type":27,"tag":87,"props":11966,"children":11967},{"style":184},[11968],{"type":36,"value":907},{"type":27,"tag":87,"props":11970,"children":11971},{"style":100},[11972],{"type":36,"value":11864},{"type":27,"tag":87,"props":11974,"children":11975},{"class":89,"line":10537},[11976,11980],{"type":27,"tag":87,"props":11977,"children":11978},{"style":2147},[11979],{"type":36,"value":11749},{"type":27,"tag":87,"props":11981,"children":11982},{"style":184},[11983],{"type":36,"value":1216},{"type":27,"tag":87,"props":11985,"children":11986},{"class":89,"line":10546},[11987,11992],{"type":27,"tag":87,"props":11988,"children":11989},{"style":100},[11990],{"type":36,"value":11991},"        '201'",{"type":27,"tag":87,"props":11993,"children":11994},{"style":184},[11995],{"type":36,"value":1216},{"type":27,"tag":87,"props":11997,"children":11999},{"class":89,"line":11998},28,[12000,12004,12008],{"type":27,"tag":87,"props":12001,"children":12002},{"style":2147},[12003],{"type":36,"value":11773},{"type":27,"tag":87,"props":12005,"children":12006},{"style":184},[12007],{"type":36,"value":907},{"type":27,"tag":87,"props":12009,"children":12010},{"style":100},[12011],{"type":36,"value":12012},"Product created successfully\n",{"type":27,"tag":87,"props":12014,"children":12016},{"class":89,"line":12015},29,[12017,12021],{"type":27,"tag":87,"props":12018,"children":12019},{"style":2147},[12020],{"type":36,"value":11790},{"type":27,"tag":87,"props":12022,"children":12023},{"style":184},[12024],{"type":36,"value":1216},{"type":27,"tag":87,"props":12026,"children":12028},{"class":89,"line":12027},30,[12029,12033],{"type":27,"tag":87,"props":12030,"children":12031},{"style":2147},[12032],{"type":36,"value":11802},{"type":27,"tag":87,"props":12034,"children":12035},{"style":184},[12036],{"type":36,"value":1216},{"type":27,"tag":87,"props":12038,"children":12040},{"class":89,"line":12039},31,[12041,12045],{"type":27,"tag":87,"props":12042,"children":12043},{"style":2147},[12044],{"type":36,"value":11814},{"type":27,"tag":87,"props":12046,"children":12047},{"style":184},[12048],{"type":36,"value":1216},{"type":27,"tag":87,"props":12050,"children":12052},{"class":89,"line":12051},32,[12053,12058,12062],{"type":27,"tag":87,"props":12054,"children":12055},{"style":2147},[12056],{"type":36,"value":12057},"                $ref",{"type":27,"tag":87,"props":12059,"children":12060},{"style":184},[12061],{"type":36,"value":907},{"type":27,"tag":87,"props":12063,"children":12064},{"style":100},[12065],{"type":36,"value":11864},{"type":27,"tag":87,"props":12067,"children":12069},{"class":89,"line":12068},33,[12070,12075],{"type":27,"tag":87,"props":12071,"children":12072},{"style":2147},[12073],{"type":36,"value":12074},"components",{"type":27,"tag":87,"props":12076,"children":12077},{"style":184},[12078],{"type":36,"value":1216},{"type":27,"tag":87,"props":12080,"children":12082},{"class":89,"line":12081},34,[12083,12088],{"type":27,"tag":87,"props":12084,"children":12085},{"style":2147},[12086],{"type":36,"value":12087},"  schemas",{"type":27,"tag":87,"props":12089,"children":12090},{"style":184},[12091],{"type":36,"value":1216},{"type":27,"tag":87,"props":12093,"children":12095},{"class":89,"line":12094},35,[12096,12101],{"type":27,"tag":87,"props":12097,"children":12098},{"style":2147},[12099],{"type":36,"value":12100},"    Product",{"type":27,"tag":87,"props":12102,"children":12103},{"style":184},[12104],{"type":36,"value":1216},{"type":27,"tag":87,"props":12106,"children":12108},{"class":89,"line":12107},36,[12109,12114,12118],{"type":27,"tag":87,"props":12110,"children":12111},{"style":2147},[12112],{"type":36,"value":12113},"      type",{"type":27,"tag":87,"props":12115,"children":12116},{"style":184},[12117],{"type":36,"value":907},{"type":27,"tag":87,"props":12119,"children":12120},{"style":100},[12121],{"type":36,"value":12122},"object\n",{"type":27,"tag":87,"props":12124,"children":12126},{"class":89,"line":12125},37,[12127,12132],{"type":27,"tag":87,"props":12128,"children":12129},{"style":2147},[12130],{"type":36,"value":12131},"      properties",{"type":27,"tag":87,"props":12133,"children":12134},{"style":184},[12135],{"type":36,"value":1216},{"type":27,"tag":87,"props":12137,"children":12139},{"class":89,"line":12138},38,[12140,12145],{"type":27,"tag":87,"props":12141,"children":12142},{"style":2147},[12143],{"type":36,"value":12144},"        id",{"type":27,"tag":87,"props":12146,"children":12147},{"style":184},[12148],{"type":36,"value":1216},{"type":27,"tag":87,"props":12150,"children":12152},{"class":89,"line":12151},39,[12153,12158,12162],{"type":27,"tag":87,"props":12154,"children":12155},{"style":2147},[12156],{"type":36,"value":12157},"          type",{"type":27,"tag":87,"props":12159,"children":12160},{"style":184},[12161],{"type":36,"value":907},{"type":27,"tag":87,"props":12163,"children":12164},{"style":100},[12165],{"type":36,"value":12166},"integer\n",{"type":27,"tag":87,"props":12168,"children":12170},{"class":89,"line":12169},40,[12171,12176],{"type":27,"tag":87,"props":12172,"children":12173},{"style":2147},[12174],{"type":36,"value":12175},"        name",{"type":27,"tag":87,"props":12177,"children":12178},{"style":184},[12179],{"type":36,"value":1216},{"type":27,"tag":87,"props":12181,"children":12183},{"class":89,"line":12182},41,[12184,12188,12192],{"type":27,"tag":87,"props":12185,"children":12186},{"style":2147},[12187],{"type":36,"value":12157},{"type":27,"tag":87,"props":12189,"children":12190},{"style":184},[12191],{"type":36,"value":907},{"type":27,"tag":87,"props":12193,"children":12194},{"style":100},[12195],{"type":36,"value":12196},"string\n",{"type":27,"tag":87,"props":12198,"children":12200},{"class":89,"line":12199},42,[12201,12206],{"type":27,"tag":87,"props":12202,"children":12203},{"style":2147},[12204],{"type":36,"value":12205},"        price",{"type":27,"tag":87,"props":12207,"children":12208},{"style":184},[12209],{"type":36,"value":1216},{"type":27,"tag":87,"props":12211,"children":12213},{"class":89,"line":12212},43,[12214,12218,12222],{"type":27,"tag":87,"props":12215,"children":12216},{"style":2147},[12217],{"type":36,"value":12157},{"type":27,"tag":87,"props":12219,"children":12220},{"style":184},[12221],{"type":36,"value":907},{"type":27,"tag":87,"props":12223,"children":12224},{"style":100},[12225],{"type":36,"value":12226},"number\n",{"type":27,"tag":32,"props":12228,"children":12229},{},[12230],{"type":36,"value":12231},"This YAML file defines the API endpoints, request/response structures, and data schemas for an e-commerce platform. It serves as a contract that developers, testers, and documentation teams can refer to, ensuring consistent implementation and clear communication.",{"type":27,"tag":39,"props":12233,"children":12234},{"id":2304},[12235],{"type":36,"value":2307},{"type":27,"tag":32,"props":12237,"children":12238},{},[12239],{"type":36,"value":12240},"Adopting the API-First philosophy and utilizing tools like OpenAPI with YAML-based contracts can greatly enhance your software development projects. It fosters collaboration, reduces development time, and ultimately results in more robust and scalable APIs. As the software landscape continues to evolve, embracing API-First practices becomes not just an option but a necessity for success.",{"type":27,"tag":32,"props":12242,"children":12243},{},[12244],{"type":36,"value":12245},"Start your journey towards API excellence today by making API-First development a core principle of your projects.",{"type":27,"tag":1439,"props":12247,"children":12248},{},[12249],{"type":36,"value":1443},{"title":8,"searchDepth":200,"depth":200,"links":12251},[12252,12253,12254],{"id":11588,"depth":200,"text":11591},{"id":11599,"depth":200,"text":11602},{"id":2304,"depth":200,"text":2307},"content:posts:api-first-principles.md","posts/api-first-principles.md","posts/api-first-principles",{"_path":12259,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":12260,"description":12261,"date":12262,"layout":12,"subtitle":12263,"image":12264,"optimized_image":12264,"category":15,"tags":12265,"author":22,"paginate":7,"body":12267,"_type":1455,"_id":12716,"_source":1457,"_file":12717,"_stem":12718,"_extension":1460},"/posts/playing-with-ocr-libraries","Playing with OCR libraries","How to recognize text from images with pytesseract library. From image to python string","2020-11-22T11:00:00.000Z","How to recognize text from images with pytesseract library","/assets/img/uploads/ocr.jpg",[12266,168],"ocr",{"type":24,"children":12268,"toc":12711},[12269,12282,12288,12309,12335,12340,12401,12406,12447,12453,12677,12689,12695,12707],{"type":27,"tag":32,"props":12270,"children":12271},{},[12272,12274,12280],{"type":36,"value":12273},"A Few days ago I found a cool library for text recognition in images, ",{"type":27,"tag":1410,"props":12275,"children":12277},{"href":12276},"https://pypi.org/project/pytesseract/",[12278],{"type":36,"value":12279},"pytesseract",{"type":36,"value":12281},".\nWith this library and just a few lines of code you can implement OCR features.",{"type":27,"tag":39,"props":12283,"children":12285},{"id":12284},"get-started",[12286],{"type":36,"value":12287},"Get started",{"type":27,"tag":32,"props":12289,"children":12290},{},[12291,12293,12299,12301,12308],{"type":36,"value":12292},"Install ",{"type":27,"tag":15,"props":12294,"children":12296},{"className":12295},[],[12297],{"type":36,"value":12298},"teseract",{"type":36,"value":12300}," in MacOs (",{"type":27,"tag":1410,"props":12302,"children":12305},{"href":12303,"rel":12304},"https://tesseract-ocr.github.io/tessdoc/Home.html",[1414],[12306],{"type":36,"value":12307},"for other platforms",{"type":36,"value":650},{"type":27,"tag":77,"props":12310,"children":12314},{"className":12311,"code":12312,"language":12313,"meta":8,"style":8},"language-sh shiki shiki-themes github-dark github-light","brew install tesseract\n","sh",[12315],{"type":27,"tag":15,"props":12316,"children":12317},{"__ignoreMap":8},[12318],{"type":27,"tag":87,"props":12319,"children":12320},{"class":89,"line":90},[12321,12326,12330],{"type":27,"tag":87,"props":12322,"children":12323},{"style":94},[12324],{"type":36,"value":12325},"brew",{"type":27,"tag":87,"props":12327,"children":12328},{"style":100},[12329],{"type":36,"value":103},{"type":27,"tag":87,"props":12331,"children":12332},{"style":100},[12333],{"type":36,"value":12334}," tesseract\n",{"type":27,"tag":32,"props":12336,"children":12337},{},[12338],{"type":36,"value":12339},"Create a new python environment & install requirements",{"type":27,"tag":77,"props":12341,"children":12343},{"className":79,"code":12342,"language":81,"meta":8,"style":8},"python -m venv en\nsource env/bin/activate\npip install -r requirements.txt\n",[12344],{"type":27,"tag":15,"props":12345,"children":12346},{"__ignoreMap":8},[12347,12367,12380],{"type":27,"tag":87,"props":12348,"children":12349},{"class":89,"line":90},[12350,12354,12358,12362],{"type":27,"tag":87,"props":12351,"children":12352},{"style":94},[12353],{"type":36,"value":168},{"type":27,"tag":87,"props":12355,"children":12356},{"style":288},[12357],{"type":36,"value":3999},{"type":27,"tag":87,"props":12359,"children":12360},{"style":100},[12361],{"type":36,"value":11388},{"type":27,"tag":87,"props":12363,"children":12364},{"style":100},[12365],{"type":36,"value":12366}," en\n",{"type":27,"tag":87,"props":12368,"children":12369},{"class":89,"line":200},[12370,12375],{"type":27,"tag":87,"props":12371,"children":12372},{"style":288},[12373],{"type":36,"value":12374},"source",{"type":27,"tag":87,"props":12376,"children":12377},{"style":100},[12378],{"type":36,"value":12379}," env/bin/activate\n",{"type":27,"tag":87,"props":12381,"children":12382},{"class":89,"line":222},[12383,12387,12391,12396],{"type":27,"tag":87,"props":12384,"children":12385},{"style":94},[12386],{"type":36,"value":97},{"type":27,"tag":87,"props":12388,"children":12389},{"style":100},[12390],{"type":36,"value":103},{"type":27,"tag":87,"props":12392,"children":12393},{"style":288},[12394],{"type":36,"value":12395}," -r",{"type":27,"tag":87,"props":12397,"children":12398},{"style":100},[12399],{"type":36,"value":12400}," requirements.txt\n",{"type":27,"tag":32,"props":12402,"children":12403},{},[12404],{"type":36,"value":12405},"requirements.txt file",{"type":27,"tag":77,"props":12407,"children":12411},{"className":12408,"code":12409,"language":12410,"meta":8,"style":8},"language-txt shiki shiki-themes github-dark github-light","numpy==1.19.4\nopencv-python==4.4.0.46\nPillow==8.0.1\npytesseract==0.3.6\n","txt",[12412],{"type":27,"tag":15,"props":12413,"children":12414},{"__ignoreMap":8},[12415,12423,12431,12439],{"type":27,"tag":87,"props":12416,"children":12417},{"class":89,"line":90},[12418],{"type":27,"tag":87,"props":12419,"children":12420},{},[12421],{"type":36,"value":12422},"numpy==1.19.4\n",{"type":27,"tag":87,"props":12424,"children":12425},{"class":89,"line":200},[12426],{"type":27,"tag":87,"props":12427,"children":12428},{},[12429],{"type":36,"value":12430},"opencv-python==4.4.0.46\n",{"type":27,"tag":87,"props":12432,"children":12433},{"class":89,"line":222},[12434],{"type":27,"tag":87,"props":12435,"children":12436},{},[12437],{"type":36,"value":12438},"Pillow==8.0.1\n",{"type":27,"tag":87,"props":12440,"children":12441},{"class":89,"line":235},[12442],{"type":27,"tag":87,"props":12443,"children":12444},{},[12445],{"type":36,"value":12446},"pytesseract==0.3.6\n",{"type":27,"tag":39,"props":12448,"children":12450},{"id":12449},"create-your-first-ocr-script",[12451],{"type":36,"value":12452},"Create your first ocr script",{"type":27,"tag":77,"props":12454,"children":12456},{"className":166,"code":12455,"language":168,"meta":8,"style":8},"from PIL import Image\nimport pytesseract\nimport argparse\nimport sys\n\noriginal_image = \"image.jpg\"\nimage = cv2.imread(original_image)\ngray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)\n\n# Convert to grayscale for better performance\nfilename = \"grayscale_image.png\"\ncv2.imwrite(filename, gray)\n\n# Load the image as a PIL/Pillow image and apply OCR\ntext = pytesseract.image_to_string(Image.open(filename))\nos.remove(filename)\nprint(text)\n",[12457],{"type":27,"tag":15,"props":12458,"children":12459},{"__ignoreMap":8},[12460,12482,12494,12506,12518,12525,12542,12559,12585,12592,12600,12617,12625,12632,12640,12657,12665],{"type":27,"tag":87,"props":12461,"children":12462},{"class":89,"line":90},[12463,12467,12472,12477],{"type":27,"tag":87,"props":12464,"children":12465},{"style":178},[12466],{"type":36,"value":181},{"type":27,"tag":87,"props":12468,"children":12469},{"style":288},[12470],{"type":36,"value":12471}," PIL",{"type":27,"tag":87,"props":12473,"children":12474},{"style":178},[12475],{"type":36,"value":12476}," import",{"type":27,"tag":87,"props":12478,"children":12479},{"style":184},[12480],{"type":36,"value":12481}," Image\n",{"type":27,"tag":87,"props":12483,"children":12484},{"class":89,"line":200},[12485,12489],{"type":27,"tag":87,"props":12486,"children":12487},{"style":178},[12488],{"type":36,"value":192},{"type":27,"tag":87,"props":12490,"children":12491},{"style":184},[12492],{"type":36,"value":12493}," pytesseract\n",{"type":27,"tag":87,"props":12495,"children":12496},{"class":89,"line":222},[12497,12501],{"type":27,"tag":87,"props":12498,"children":12499},{"style":178},[12500],{"type":36,"value":192},{"type":27,"tag":87,"props":12502,"children":12503},{"style":184},[12504],{"type":36,"value":12505}," argparse\n",{"type":27,"tag":87,"props":12507,"children":12508},{"class":89,"line":235},[12509,12513],{"type":27,"tag":87,"props":12510,"children":12511},{"style":178},[12512],{"type":36,"value":192},{"type":27,"tag":87,"props":12514,"children":12515},{"style":184},[12516],{"type":36,"value":12517}," sys\n",{"type":27,"tag":87,"props":12519,"children":12520},{"class":89,"line":257},[12521],{"type":27,"tag":87,"props":12522,"children":12523},{"emptyLinePlaceholder":261},[12524],{"type":36,"value":264},{"type":27,"tag":87,"props":12526,"children":12527},{"class":89,"line":267},[12528,12533,12537],{"type":27,"tag":87,"props":12529,"children":12530},{"style":184},[12531],{"type":36,"value":12532},"original_image ",{"type":27,"tag":87,"props":12534,"children":12535},{"style":178},[12536],{"type":36,"value":325},{"type":27,"tag":87,"props":12538,"children":12539},{"style":100},[12540],{"type":36,"value":12541}," \"image.jpg\"\n",{"type":27,"tag":87,"props":12543,"children":12544},{"class":89,"line":276},[12545,12550,12554],{"type":27,"tag":87,"props":12546,"children":12547},{"style":184},[12548],{"type":36,"value":12549},"image ",{"type":27,"tag":87,"props":12551,"children":12552},{"style":178},[12553],{"type":36,"value":325},{"type":27,"tag":87,"props":12555,"children":12556},{"style":184},[12557],{"type":36,"value":12558}," cv2.imread(original_image)\n",{"type":27,"tag":87,"props":12560,"children":12561},{"class":89,"line":284},[12562,12567,12571,12576,12581],{"type":27,"tag":87,"props":12563,"children":12564},{"style":184},[12565],{"type":36,"value":12566},"gray ",{"type":27,"tag":87,"props":12568,"children":12569},{"style":178},[12570],{"type":36,"value":325},{"type":27,"tag":87,"props":12572,"children":12573},{"style":184},[12574],{"type":36,"value":12575}," cv2.cvtColor(image, cv2.",{"type":27,"tag":87,"props":12577,"children":12578},{"style":288},[12579],{"type":36,"value":12580},"COLOR_BGR2GRAY",{"type":27,"tag":87,"props":12582,"children":12583},{"style":184},[12584],{"type":36,"value":311},{"type":27,"tag":87,"props":12586,"children":12587},{"class":89,"line":314},[12588],{"type":27,"tag":87,"props":12589,"children":12590},{"emptyLinePlaceholder":261},[12591],{"type":36,"value":264},{"type":27,"tag":87,"props":12593,"children":12594},{"class":89,"line":341},[12595],{"type":27,"tag":87,"props":12596,"children":12597},{"style":1794},[12598],{"type":36,"value":12599},"# Convert to grayscale for better performance\n",{"type":27,"tag":87,"props":12601,"children":12602},{"class":89,"line":374},[12603,12608,12612],{"type":27,"tag":87,"props":12604,"children":12605},{"style":184},[12606],{"type":36,"value":12607},"filename ",{"type":27,"tag":87,"props":12609,"children":12610},{"style":178},[12611],{"type":36,"value":325},{"type":27,"tag":87,"props":12613,"children":12614},{"style":100},[12615],{"type":36,"value":12616}," \"grayscale_image.png\"\n",{"type":27,"tag":87,"props":12618,"children":12619},{"class":89,"line":699},[12620],{"type":27,"tag":87,"props":12621,"children":12622},{"style":184},[12623],{"type":36,"value":12624},"cv2.imwrite(filename, gray)\n",{"type":27,"tag":87,"props":12626,"children":12627},{"class":89,"line":707},[12628],{"type":27,"tag":87,"props":12629,"children":12630},{"emptyLinePlaceholder":261},[12631],{"type":36,"value":264},{"type":27,"tag":87,"props":12633,"children":12634},{"class":89,"line":725},[12635],{"type":27,"tag":87,"props":12636,"children":12637},{"style":1794},[12638],{"type":36,"value":12639},"# Load the image as a PIL/Pillow image and apply OCR\n",{"type":27,"tag":87,"props":12641,"children":12642},{"class":89,"line":1039},[12643,12648,12652],{"type":27,"tag":87,"props":12644,"children":12645},{"style":184},[12646],{"type":36,"value":12647},"text ",{"type":27,"tag":87,"props":12649,"children":12650},{"style":178},[12651],{"type":36,"value":325},{"type":27,"tag":87,"props":12653,"children":12654},{"style":184},[12655],{"type":36,"value":12656}," pytesseract.image_to_string(Image.open(filename))\n",{"type":27,"tag":87,"props":12658,"children":12659},{"class":89,"line":1052},[12660],{"type":27,"tag":87,"props":12661,"children":12662},{"style":184},[12663],{"type":36,"value":12664},"os.remove(filename)\n",{"type":27,"tag":87,"props":12666,"children":12667},{"class":89,"line":1060},[12668,12672],{"type":27,"tag":87,"props":12669,"children":12670},{"style":288},[12671],{"type":36,"value":731},{"type":27,"tag":87,"props":12673,"children":12674},{"style":184},[12675],{"type":36,"value":12676},"(text)\n",{"type":27,"tag":32,"props":12678,"children":12679},{},[12680,12682],{"type":36,"value":12681},"You can find the complete code of this example in ",{"type":27,"tag":1410,"props":12683,"children":12686},{"href":12684,"rel":12685},"https://github.com/JaimeDeArcos/ocr-python",[1414],[12687],{"type":36,"value":12688},"this GitHub repository",{"type":27,"tag":39,"props":12690,"children":12692},{"id":12691},"references",[12693],{"type":36,"value":12694},"References",{"type":27,"tag":46,"props":12696,"children":12697},{},[12698],{"type":27,"tag":50,"props":12699,"children":12700},{},[12701],{"type":27,"tag":1410,"props":12702,"children":12704},{"href":12276,"rel":12703},[1414],[12705],{"type":36,"value":12706},"PyTesseract pip documentation",{"type":27,"tag":1439,"props":12708,"children":12709},{},[12710],{"type":36,"value":1443},{"title":8,"searchDepth":200,"depth":200,"links":12712},[12713,12714,12715],{"id":12284,"depth":200,"text":12287},{"id":12449,"depth":200,"text":12452},{"id":12691,"depth":200,"text":12694},"content:posts:playing-with-ocr-libraries.md","posts/playing-with-ocr-libraries.md","posts/playing-with-ocr-libraries",1790510063184]