[{"data":1,"prerenderedAt":956},["ShallowReactive",2],{"navigation:es":3,"index:es":4,"index-blogs:es":114},[],{"id":5,"title":6,"about":7,"blog":10,"body":14,"description":15,"experience":16,"extension":32,"faq":33,"hero":52,"meta":81,"navigation":82,"path":83,"seo":84,"stem":87,"testimonials":88,"__hash__":113},"index\u002Fes\u002Findex.yml","Hola, soy Rafael García Desarrollador de Software",{"title":8,"description":9},"Sobre Mí","Soy un desarrollador de software enfocado principalmente en el desarrollo backend. Me apasiona mejorar mis habilidades de programación y ampliar continuamente mis conocimientos en tecnologías modernas, especialmente para la construcción de APIs escalables y aplicaciones web robustas.\n",{"title":11,"description":12,"read_section":13},"Últimos artículos","Algunos artículos de mi blog","Leer Artículo",null,"Construyo soluciones robustas y escalables donde el rendimiento se combina con la arquitectura limpia. Enfocado en APIs, sistemas mantenibles y aprendizaje continuo a través de proyectos reales.",{"title":17,"items":18},"Experiencia de Trabajo",[19,26],{"position":20,"date":21,"company":22},"Software Developer at","06\u002F2025 - Present",{"name":23,"url":24,"color":25},"CODES SRL","https:\u002F\u002Fwww.codestic.net","#39a5c9",{"position":20,"date":27,"company":28},"01\u002F2025 - 06\u002F2025",{"name":29,"url":30,"color":31},"Medialityc","https:\u002F\u002Flinkedin.com\u002Fcompany\u002Fmedialityc","#FF6363","yml",{"title":34,"description":35,"categories":36},"Preguntas Frecuentes","Respuestas a preguntas frcuentes sobre mis servicios.",[37,46],{"title":38,"questions":39},"Servicios & Procesos",[40,43],{"label":41,"content":42},"¿Qué servicios ofrece?","Diseño y elaboro software a la medida de su negocio o servicios, desde un prototipado hasta su despliegue a producción\n",{"label":44,"content":45},"¿Trabaja remoto?","Efectivamente, trabajo remoto, de forma presencial o semi-presencial\n",{"title":47,"questions":48},"Precios y Tiempos",[49],{"label":50,"content":51},"¿Cuánto cuesta un proyecto normalmente?","El precio de un proyecto varía en torno a su alcance, complejidad, features y tiempo de desarrollo.\n",{"images":53},[54,57,60,63,66,69,72,75,78],{"src":55,"alt":56},"\u002Fhero\u002Fdotnet.png","DotNet Framework Logo",{"src":58,"alt":59},"\u002Fhero\u002Fdjango.webp","Django Framework Logo",{"src":61,"alt":62},"\u002Fhero\u002Ffastapi.svg","Fastapi Framework Logo",{"src":64,"alt":65},"\u002Fhero\u002FLaravel.svg.png","Laravel Framework Logo",{"src":67,"alt":68},"\u002Fhero\u002FVue.js_Logo_2.svg.png","Vue.js Framework Logo",{"src":70,"alt":71},"\u002Fhero\u002Fpostgres.png","PostgreSQL Logo",{"src":73,"alt":74},"\u002Fhero\u002FmySql.png","MySQL Logo",{"src":76,"alt":77},"\u002Fhero\u002Fmongodb.png","MongoDB Logo",{"src":79,"alt":80},"\u002Fhero\u002Fyii.png","Yii Framework Logo",{},true,"\u002Fes",{"title":85,"description":86},"Rafael García - Desarrollador de Software","Desarrollador enfocado en construir APIs robustas y escalables utilizando .NET, FastAPI y Django. Apasionado por la arquitectura limpia, el código mantenible y el aprendizaje continuo.","es\u002Findex",[89,97,105],{"quote":90,"author":91},"Emma's approach to UX design completely transformed our product. She has a rare ability to balance beautiful aesthetics with functional simplicity. The redesign not only looked better, but it reduced our customer support tickets by 40% and increased conversion rates across all key metrics.",{"name":92,"description":93,"avatar":94},"Sarah Chen","Product Director at Bloom Finance",{"src":95,"srcset":96},"https:\u002F\u002Fimages.unsplash.com\u002Fphoto-1487412720507-e7ab37603c6f?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=40&h=40&q=80","https:\u002F\u002Fimages.unsplash.com\u002Fphoto-1487412720507-e7ab37603c6f?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=80&h=80&q=80 2x",{"quote":98,"author":99},"Working with Emma was the best decision we made for our startup. She didn't just deliver designs—she challenged our assumptions, conducted thorough user research, and created an experience that truly resonated with our audience. Her technical knowledge of front-end development meant the handoff to our engineering team was seamless.",{"name":100,"description":101,"avatar":102},"Michael Rodriguez","Co-founder of Wavelength Music",{"src":103,"srcset":104},"https:\u002F\u002Fimages.unsplash.com\u002Fphoto-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=40&h=40&q=80","https:\u002F\u002Fimages.unsplash.com\u002Fphoto-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=80&h=80&q=80 2x",{"quote":106,"author":107},"Emma stands out in her ability to translate complex sustainability data into intuitive interfaces. Her work on EcoTrack wasn't just visually stunning—it fundamentally changed how our users interact with environmental information. She approaches each problem with both creativity and analytical rigor, which is exactly what we needed.",{"name":108,"description":109,"avatar":110},"Dr. Aisha Johnson","Chief Innovation Officer at GreenTech Solutions",{"src":111,"srcset":112},"https:\u002F\u002Fimages.unsplash.com\u002Fphoto-1573497019940-1c28c88b4f3e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=40&h=40&q=80","https:\u002F\u002Fimages.unsplash.com\u002Fphoto-1573497019940-1c28c88b4f3e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=80&h=80&q=80 2x","rmZ_6-UChoELxmjsZCtbEQv3TrfXUluM57GpAGqWQEM",[115],{"id":116,"title":117,"author":118,"body":123,"date":946,"description":947,"extension":948,"image":949,"meta":950,"minRead":951,"navigation":82,"path":952,"seo":953,"stem":954,"__hash__":955},"blog\u002Fes\u002Fblog\u002Fclean-arch-template-blog.md","De Boilerplate a Production: Construyendo My Clean Architecture .NET API Template",{"name":119,"avatar":120},"Rafael García González",{"src":121,"alt":122},"https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F158175139?v=4","Mi foto de perfil",{"type":124,"value":125,"toc":923},"minimark",[126,131,135,140,143,146,150,169,190,305,309,314,317,352,355,362,366,372,384,401,406,414,417,422,431,439,441,446,455,467,471,484,486,492,501,509,513,520,522,527,532,536,540,544,551,565,570,598,603,613,621,631,636,650,655,672,674,681,686,694,699,720,726,745,752,754,758,766,770,813,817,842,844,848,875,877,881,898,902,908,912,919],[127,128,130],"h1",{"id":129},"de-boilerplate-a-producción-construyendo-mi-clean-architecture-net-api-template","De Boilerplate a Producción: Construyendo mi Clean Architecture .NET API Template",[132,133,134],"p",{},"Crear un API lista para producción no debería significar empezar desde 0 siempre. En este post, explicaré el diseño y estructura de mi API template de Clean Architecture .NET, qué me motivó a hacerlo, y cómo usarlo para tener una implementación sin sacrificar tiempo y mantenibilidad.",[136,137,139],"h2",{"id":138},"por-qué-hice-este-template","¿Por qué hice este Template?",[132,141,142],{},"Al iniciar un proyecto en .NET, suele perderse mucho tiempo en la configuración inicial y en la instalación de dependencias esenciales para que la aplicación funcione correctamente. Esto incluye aspectos como la configuración de la conexión a la base de datos, la documentación con Swagger, las abstracciones de entidades y servicios, entre otros.",[132,144,145],{},"Por esa razón, decidí crear este template con lo indispensable para comenzar rápidamente el desarrollo de una API REST siguiendo los principios de Clean Architecture.",[136,147,149],{"id":148},"qué-incluye","¿Qué incluye?",[132,151,152,153,157,158,157,161,164,165,168],{},"Este template reúne los bloques fundamentales necesarios para iniciar una API .NET lista para producción, con una estructura limpia y mantenible. Incluye una arquitectura por capas con una separación clara de responsabilidades entre ",[154,155,156],"strong",{},"Domain",", ",[154,159,160],{},"Application",[154,162,163],{},"Infrastructure"," y ",[154,166,167],{},"Presentation.Api",".",[132,170,171,172,175,176,182,183,164,186,189],{},"También implementa ",[154,173,174],{},"CQRS"," para organizar commands y queries de una forma más escalable, junto con un enfoque unificado para el manejo de resultados y errores, lo que permite respuestas consistentes en toda la aplicación. Además, incorpora validación con ",[177,178,179],"em",{},[154,180,181],{},"FluentValidation",", inyección de dependencias mediante métodos de extensión, funcionalidades de autenticación y autorización, envío de correos con plantillas, y persistencia con ",[154,184,185],{},"EF Core",[154,187,188],{},"PostgreSQL",". Además viene con el Dokerfile y Docker compose pre-configurado, listo para desplegar.",[191,192,193,206],"table",{},[194,195,196],"thead",{},[197,198,199,203],"tr",{},[200,201,202],"th",{},"Área",[200,204,205],{},"Qué incluye",[207,208,209,218,225,233,241,249,257,265,273,281,289,297],"tbody",{},[197,210,211,215],{},[212,213,214],"td",{},"Arquitectura",[212,216,217],{},"Clean Architecture con separación clara entre Domain, Application, Infrastructure y Presentation.Api",[197,219,220,222],{},[212,221,174],{},[212,223,224],{},"Commands y Queries con handlers y abstracciones de sender",[197,226,227,230],{},[212,228,229],{},"Manejo de resultados",[212,231,232],{},"Respuestas unificadas para éxito, error, no autorizado, conflicto y no encontrado",[197,234,235,238],{},[212,236,237],{},"Validación",[212,239,240],{},"FluentValidation integrado en la capa de aplicación",[197,242,243,246],{},[212,244,245],{},"Inyección de dependencias",[212,247,248],{},"Configuración limpia mediante métodos de extensión como AddApi, AddApplication, AddDatabase y AddEmailService",[197,250,251,254],{},[212,252,253],{},"Autenticación",[212,255,256],{},"Registro, inicio de sesión, refresh token, generación de JWT y verificación de correo",[197,258,259,262],{},[212,260,261],{},"Autorización",[212,263,264],{},"Control de acceso basado en policies y permisos",[197,266,267,270],{},[212,268,269],{},"Usuarios",[212,271,272],{},"Búsqueda con paginación, ordenamiento y obtención por ID con relaciones",[197,274,275,278],{},[212,276,277],{},"Seguridad",[212,279,280],{},"Funcionalidades de gestión de roles y policies",[197,282,283,286],{},[212,284,285],{},"Correo",[212,287,288],{},"Servicio de correo SMTP con soporte para renderizado de plantillas",[197,290,291,294],{},[212,292,293],{},"Persistencia",[212,295,296],{},"EF Core con PostgreSQL, inicialización de base de datos y seeding",[197,298,299,302],{},[212,300,301],{},"Despliegue",[212,303,304],{},"Dokerfile y Docker compose para despliegues más sencillos",[136,306,308],{"id":307},"project-structure","Project structure",[310,311,313],"h3",{"id":312},"solution-layout","Solution layout",[132,315,316],{},"Este repositorio contiene los siguientes proyectos, a nivel general:",[318,319,320,327,332,337,342],"ul",{},[321,322,323],"li",{},[324,325,326],"code",{},"CleanArchTemplate.Domain",[321,328,329],{},[324,330,331],{},"CleanArchTemplate.Application",[321,333,334],{},[324,335,336],{},"CleanArchTemplate.Infrastructure",[321,338,339],{},[324,340,341],{},"CleanArchTemplate.SharedKernel",[321,343,344,347,348,351],{},[324,345,346],{},"CleanArchTemplate.Presentation.Api"," (",[154,349,350],{},"startup project",")",[132,353,354],{},"Y el archivo solution:",[318,356,357],{},[321,358,359],{},[324,360,361],{},"CleanArchTemplate.sln",[136,363,365],{"id":364},"estructura-del-proyecto-donde-poner-que","Estructura del proyecto (donde poner que)",[367,368,370],"h4",{"id":369},"cleanarchtemplatedomain",[324,371,326],{},[132,373,374,377,378,381],{},[154,375,376],{},"Qué es:"," El núcleo del sistema.",[379,380],"br",{},[154,382,383],{},"Qué va aquí:",[318,385,386,389,392,395,398],{},[321,387,388],{},"Entities \u002F Aggregates",[321,390,391],{},"Value Objects",[321,393,394],{},"Domain Events",[321,396,397],{},"Domain services (pura lógica de negocio)",[321,399,400],{},"Business rules\u002Finvariants",[132,402,403],{},[154,404,405],{},"Notas:",[318,407,408,411],{},[321,409,410],{},"Evita dependencias de ASP.NET Core, EF Core o cualquier librería externa que interactúe con el mundo exterior.",[321,412,413],{},"Este proyecto debe ser el más estable a lo largo del tiempo.",[415,416],"hr",{},[367,418,420],{"id":419},"cleanarchtemplateapplication",[324,421,331],{},[132,423,424,426,427,429],{},[154,425,376],{}," Casos de uso y orquestación de la aplicación.",[379,428],{},[154,430,383],{},[318,432,433,436],{},[321,434,435],{},"Casos de uso \u002F Servicios de la aplicación (commands\u002Fqueries - CQRS)",[321,437,438],{},"Validaciones y flujos del negocio que interactúan con los objetos del dominio",[415,440],{},[367,442,444],{"id":443},"cleanarchtemplateinfrastructure",[324,445,336],{},[132,447,448,450,451,453],{},[154,449,376],{}," Detalles de implementación e integraciones.",[379,452],{},[154,454,383],{},[318,456,457,464],{},[321,458,459,460,463],{},"EF Core ",[324,461,462],{},"DbContext",", mappings, configurations",[321,465,466],{},"Clientes de servicios externos (message brokers, file storage, etc.)",[132,468,469],{},[154,470,405],{},[318,472,473,481],{},[321,474,475,476,478,479,168],{},"Esta capa depende de ",[324,477,160],{}," y ",[324,480,156],{},[321,482,483],{},"Aquí es donde viven las preocupaciones del “mundo real”.",[415,485],{},[367,487,489,491],{"id":488},"cleanarchtemplatepresentationapi-startup-project",[324,490,346],{}," (Startup Project)",[132,493,494,496,497,499],{},[154,495,376],{}," La capa de entrada HTTP de la API (ASP.NET Core).",[379,498],{},[154,500,383],{},[318,502,503,506],{},[321,504,505],{},"Controladores",[321,507,508],{},"Configuración de la API (DI wiring, middleware, Swagger, auth, etc.)",[132,510,511],{},[154,512,405],{},[318,514,515],{},[321,516,517,518,168],{},"Este proyecto es el punto de entrada de la aplicación y es el ",[154,519,350],{},[415,521],{},[367,523,525],{"id":524},"cleanarchtemplatesharedkernel",[324,526,341],{},[132,528,529,531],{},[154,530,376],{}," Bloques compartidos y transversales utilizados entre capas.",[136,533,535],{"id":534},"cómo-usarlo","¿Cómo usarlo?",[310,537,539],{"id":538},"correr-el-proyecto","Correr el proyecto",[367,541,543],{"id":542},"opción-a-correr-con-docker-compose-recomendado","Opción A — Correr con Docker Compose (Recomendado)",[132,545,546,547,550],{},"Este repositorio incluye un ",[324,548,549],{},"compose.yaml"," que inicia:",[318,552,553,559],{},[321,554,555,556,351],{},"API container (expone el ",[154,557,558],{},"puerto 8080",[321,560,561,562,351],{},"PostgreSQL container (expone el ",[154,563,564],{},"puerto 5432",[132,566,567],{},[154,568,569],{},"Start:",[571,572,577],"pre",{"className":573,"code":574,"language":575,"meta":576,"style":576},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","docker compose up --build\n","bash","",[324,578,579],{"__ignoreMap":576},[580,581,584,588,592,595],"span",{"class":582,"line":583},"line",1,[580,585,587],{"class":586},"sBMFI","docker",[580,589,591],{"class":590},"sfazB"," compose",[580,593,594],{"class":590}," up",[580,596,597],{"class":590}," --build\n",[132,599,600],{},[154,601,602],{},"API URL:",[318,604,605],{},[321,606,607],{},[608,609,610],"a",{"href":610,"rel":611},"http:\u002F\u002Flocalhost:8080",[612],"nofollow",[132,614,615],{},[154,616,617,618,620],{},"Base de datos (de ",[324,619,549],{},"):",[622,623,624],"blockquote",{},[132,625,626,627,630],{},"Nota: dentro de la red de Docker, la API usa ",[324,628,629],{},"Host=db"," en su cadena de conexión.",[132,632,633],{},[154,634,635],{},"Stop:",[571,637,639],{"className":573,"code":638,"language":575,"meta":576,"style":576},"docker compose down\n",[324,640,641],{"__ignoreMap":576},[580,642,643,645,647],{"class":582,"line":583},[580,644,587],{"class":586},[580,646,591],{"class":590},[580,648,649],{"class":590}," down\n",[132,651,652],{},[154,653,654],{},"Stop + remove volumes (deletes local DB data):",[571,656,658],{"className":573,"code":657,"language":575,"meta":576,"style":576},"docker compose down -v\n",[324,659,660],{"__ignoreMap":576},[580,661,662,664,666,669],{"class":582,"line":583},[580,663,587],{"class":586},[580,665,591],{"class":590},[580,667,668],{"class":590}," down",[580,670,671],{"class":590}," -v\n",[415,673],{},[310,675,677,678],{"id":676},"opción-b-correr-condotnet-run","Opción B — Correr con ",[324,679,680],{},"dotnet run",[132,682,683],{},[154,684,685],{},"Prerequisitos:",[318,687,688,691],{},[321,689,690],{},".NET SDK instalado",[321,692,693],{},"Una instacia de PostgreSQL (puedes usar Docker para la BD si quieres)",[132,695,696],{},[154,697,698],{},"1) Levantar solo la BD por Docker (opcional):",[571,700,704],{"className":701,"code":702,"language":703,"meta":576,"style":576},"language-shell shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","docker compose up -d db\n","shell",[324,705,706],{"__ignoreMap":576},[580,707,708,710,712,714,717],{"class":582,"line":583},[580,709,587],{"class":586},[580,711,591],{"class":590},[580,713,594],{"class":590},[580,715,716],{"class":590}," -d",[580,718,719],{"class":590}," db\n",[132,721,722,725],{},[154,723,724],{},"2) Levantar la API (startup project):"," Desde la raíz del repo:",[571,727,729],{"className":701,"code":728,"language":703,"meta":576,"style":576},"dotnet run --project CleanArchTemplate.Presentation.Api\n",[324,730,731],{"__ignoreMap":576},[580,732,733,736,739,742],{"class":582,"line":583},[580,734,735],{"class":586},"dotnet",[580,737,738],{"class":590}," run",[580,740,741],{"class":590}," --project",[580,743,744],{"class":590}," CleanArchTemplate.Presentation.Api\n",[132,746,747,748,751],{},"Para las variables de entorno y ",[177,749,750],{},"connection strings",", setealos en tu shell, appsettings o user secrets como convenga.",[415,753],{},[136,755,757],{"id":756},"migraciones-de-entity-framework-core","Migraciones de Entity Framework Core",[132,759,760,761,763,764,168],{},"Las migraciones están en ",[154,762,163],{},", pero debe correrse usando la API como el ",[154,765,350],{},[310,767,769],{"id":768},"agregar-una-migración","Agregar una migración",[571,771,773],{"className":701,"code":772,"language":703,"meta":576,"style":576},"dotnet ef migrations add \u003CNameOfMigration> --startup-project CleanArchTemplate.Presentation.Api --project CleanArchTemplate.Infrastructure\n",[324,774,775],{"__ignoreMap":576},[580,776,777,779,782,785,788,792,795,799,802,805,808,810],{"class":582,"line":583},[580,778,735],{"class":586},[580,780,781],{"class":590}," ef",[580,783,784],{"class":590}," migrations",[580,786,787],{"class":590}," add",[580,789,791],{"class":790},"sMK4o"," \u003C",[580,793,794],{"class":590},"NameOfMigratio",[580,796,798],{"class":797},"sTEyZ","n",[580,800,801],{"class":790},">",[580,803,804],{"class":590}," --startup-project",[580,806,807],{"class":590}," CleanArchTemplate.Presentation.Api",[580,809,741],{"class":590},[580,811,812],{"class":590}," CleanArchTemplate.Infrastructure\n",[310,814,816],{"id":815},"aplicar-una-migración-database-update","Aplicar una migración (database update)",[571,818,820],{"className":701,"code":819,"language":703,"meta":576,"style":576},"dotnet ef database update --startup-project CleanArchTemplate.Presentation.Api --project CleanArchTemplate.Infrastructure\n",[324,821,822],{"__ignoreMap":576},[580,823,824,826,828,831,834,836,838,840],{"class":582,"line":583},[580,825,735],{"class":586},[580,827,781],{"class":590},[580,829,830],{"class":590}," database",[580,832,833],{"class":590}," update",[580,835,804],{"class":590},[580,837,807],{"class":590},[580,839,741],{"class":590},[580,841,812],{"class":590},[415,843],{},[136,845,847],{"id":846},"típico-flujo-de-trabajo-para-agregar-un-nuevo-feature","Típico flujo de trabajo para agregar un nuevo feature",[849,850,851,857,863,869],"ol",{},[321,852,853,856],{},[154,854,855],{},"Domain:"," crear\u002Factualizar entities, value objects",[321,858,859,862],{},[154,860,861],{},"Application:"," agregar casos de uso (command\u002Fquery), interfaces necesarias",[321,864,865,868],{},[154,866,867],{},"Infrastructure:"," implementar persistencia o integraciones (EF Core, external APIs)",[321,870,871,874],{},[154,872,873],{},"Presentation:"," exponer caso de uso vía HTTP endpoint\u002Fcontroller",[415,876],{},[136,878,880],{"id":879},"qué-mejoraría-o-agregaría","¿Qué mejoraría o agregaría?",[318,882,883,886,889,892,895],{},[321,884,885],{},"Migrar a OAuth 2.0",[321,887,888],{},"Agregar servicios de exportación a PDF y Excel",[321,890,891],{},"Agregar AutoMapper",[321,893,894],{},"Agregar implementación de MinIO (S3)",[321,896,897],{},"Agregar implementación de Redis",[136,899,901],{"id":900},"pensamientos-finales","Pensamientos Finales",[132,903,904,905,907],{},"Este template es el resultado de muchas pequeñas decisiones guiadas por necesidades reales de proyectos. Con el tiempo, me di cuenta de que contar con un punto de partida bien estructurado marca una gran diferencia tanto en velocidad como en calidad.",[379,906],{},"\nEn lugar de reinventar la misma base en cada proyecto, prefiero comenzar con algo que ya refleje buenas prácticas de arquitectura y que pueda crecer junto con la aplicación.",[136,909,911],{"id":910},"siéntete-libre-de-contribuir-al-proyecto","Siéntete libre de contribuir al proyecto",[132,913,914],{},[608,915,918],{"href":916,"rel":917},"https:\u002F\u002Fgithub.com\u002Frafarush\u002Fclean-arch-dotnet-api-template",[612],"Repo de Github",[920,921,922],"style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}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);}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 .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}",{"title":576,"searchDepth":924,"depth":924,"links":925},2,[926,927,928,932,933,938,942,943,944,945],{"id":138,"depth":924,"text":139},{"id":148,"depth":924,"text":149},{"id":307,"depth":924,"text":308,"children":929},[930],{"id":312,"depth":931,"text":313},3,{"id":364,"depth":924,"text":365},{"id":534,"depth":924,"text":535,"children":934},[935,936],{"id":538,"depth":931,"text":539},{"id":676,"depth":931,"text":937},"Opción B — Correr con dotnet run",{"id":756,"depth":924,"text":757,"children":939},[940,941],{"id":768,"depth":931,"text":769},{"id":815,"depth":931,"text":816},{"id":846,"depth":924,"text":847},{"id":879,"depth":924,"text":880},{"id":900,"depth":924,"text":901},{"id":910,"depth":924,"text":911},"2025-04-23","Un recorrido práctico por mi template de .NET Clean Architecture, las decisiones arquitectónicas detrás de él y cómo ayuda a entregar APIs mantenibles más rápido.","md","https:\u002F\u002Fopengraph.githubassets.com\u002F47b5e78a0a1b26714c38706c3f354355f8389b8469d117c034556fd60938f2ca\u002Frafarush\u002Fclean-arch-dotnet-api-template",{},8,"\u002Fes\u002Fblog\u002Fclean-arch-template-blog",{"title":117,"description":947},"es\u002Fblog\u002Fclean-arch-template-blog","52ndnacmsqiS9B3VrYhcCkjeu23J-2lrac9DzCbcie0",1775934440362]