{"id":307,"date":"2026-07-11T17:34:29","date_gmt":"2026-07-12T00:34:29","guid":{"rendered":"https:\/\/www.mariatech.com.mx\/blog\/?p=307"},"modified":"2026-07-11T17:34:30","modified_gmt":"2026-07-12T00:34:30","slug":"get-vs-post-cuando-usar-cada-metodo-en-desarrollo-web","status":"publish","type":"post","link":"https:\/\/www.mariatech.com.mx\/blog\/laravel-php\/get-vs-post-cuando-usar-cada-metodo-en-desarrollo-web\/","title":{"rendered":"GET vs POST: cu\u00e1ndo usar cada m\u00e9todo en desarrollo web"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Cuando desarrollamos una aplicaci\u00f3n web, una de las decisiones m\u00e1s comunes es elegir qu\u00e9 m\u00e9todo HTTP utilizar para una ruta: <code>GET<\/code> o <code>POST<\/code>. A simple vista puede parecer una decisi\u00f3n menor, sobre todo cuando no estamos enviando par\u00e1metros, pero elegir correctamente el m\u00e9todo ayuda a mejorar la seguridad, mantener una arquitectura m\u00e1s clara y evitar comportamientos inesperados.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">En este art\u00edculo explicaremos de forma pr\u00e1ctica cu\u00e1ndo usar <code>GET<\/code>, cu\u00e1ndo usar <code>POST<\/code> y por qu\u00e9 no todas las acciones deber\u00edan ejecutarse desde un simple enlace.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">La regla b\u00e1sica<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Una forma sencilla de verlo es la siguiente:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">GET  \u2192 consultar, mostrar o leer informaci\u00f3n.\nPOST \u2192 enviar informaci\u00f3n, ejecutar acciones o modificar el estado del sistema.<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Esta diferencia es importante porque no todos los accesos a una URL deber\u00edan tener consecuencias dentro del sistema. Una ruta que solamente muestra informaci\u00f3n puede trabajar con <code>GET<\/code>. En cambio, una ruta que guarda, actualiza, elimina o dispara un proceso deber\u00eda utilizar <code>POST<\/code> u otro m\u00e9todo apropiado.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Cu\u00e1ndo usar GET<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">El m\u00e9todo <code>GET<\/code> se utiliza principalmente para consultar informaci\u00f3n. Es decir, cuando el usuario entra a una URL y espera ver datos, una p\u00e1gina, un listado o un formulario, pero sin modificar nada en el sistema.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ejemplos comunes de rutas que s\u00ed pueden usar <code>GET<\/code>:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Mostrar el listado de productos.<\/li>\n\n\n\n<li>Ver el detalle de un pedido.<\/li>\n\n\n\n<li>Abrir un formulario de registro.<\/li>\n\n\n\n<li>Consultar reportes.<\/li>\n\n\n\n<li>Filtrar informaci\u00f3n en una tabla.<\/li>\n\n\n\n<li>Mostrar una pantalla de configuraci\u00f3n.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Ejemplo gen\u00e9rico en Laravel:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Route::get('\/admin\/productos', &#91;ProductController::class, 'index'])\n    -&gt;name('admin.products.index');<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">En este caso, la ruta solamente muestra informaci\u00f3n. No guarda datos, no elimina registros y no dispara procesos internos. Por eso <code>GET<\/code> es adecuado.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Cu\u00e1ndo usar POST<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">El m\u00e9todo <code>POST<\/code> se utiliza cuando el usuario va a enviar informaci\u00f3n o cuando una acci\u00f3n puede modificar el estado de la aplicaci\u00f3n.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ejemplos comunes de acciones que deber\u00edan usar <code>POST<\/code>:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Guardar un producto.<\/li>\n\n\n\n<li>Crear un pedido.<\/li>\n\n\n\n<li>Registrar un cliente.<\/li>\n\n\n\n<li>Enviar un formulario.<\/li>\n\n\n\n<li>Ejecutar una sincronizaci\u00f3n.<\/li>\n\n\n\n<li>Procesar informaci\u00f3n externa.<\/li>\n\n\n\n<li>Generar una acci\u00f3n administrativa.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Ejemplo gen\u00e9rico:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Route::post('\/admin\/productos', &#91;ProductController::class, 'store'])\n    -&gt;name('admin.products.store');<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Aqu\u00ed la ruta recibe informaci\u00f3n y crea un nuevo registro. Por lo tanto, usar <code>POST<\/code> es lo correcto.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u00bfY si no estoy enviando par\u00e1metros?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Una duda com\u00fan aparece cuando tenemos un bot\u00f3n que no env\u00eda datos visibles, pero s\u00ed ejecuta una acci\u00f3n. Por ejemplo:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Sincronizar productos.<\/li>\n\n\n\n<li>Procesar pedidos pendientes.<\/li>\n\n\n\n<li>Actualizar inventario.<\/li>\n\n\n\n<li>Ejecutar una tarea interna.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">En estos casos podr\u00eda parecer pr\u00e1ctico usar un enlace con <code>href<\/code> y una ruta <code>GET<\/code>, porque no estamos enviando campos de formulario. Sin embargo, la decisi\u00f3n no depende solamente de si enviamos par\u00e1metros, sino de lo que ocurre cuando se visita la URL.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Si al abrir la URL se ejecuta un proceso, se modifica informaci\u00f3n o se cambia el estado del sistema, entonces no deber\u00eda ser <code>GET<\/code>. Deber\u00eda ser <code>POST<\/code>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Ejemplo: ejecutar una sincronizaci\u00f3n<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Supongamos que tenemos una aplicaci\u00f3n administrativa y queremos agregar un bot\u00f3n para sincronizar informaci\u00f3n con un servicio externo.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Una opci\u00f3n incorrecta ser\u00eda hacerlo as\u00ed:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;a href=\"\/admin\/sincronizar-productos\" class=\"btn btn-primary\"&gt;\n    Sincronizar productos\n&lt;\/a&gt;<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Y definir la ruta como <code>GET<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Route::get('\/admin\/sincronizar-productos', &#91;SyncController::class, 'syncProducts']);<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">El problema es que esa URL ejecuta un proceso. No solo muestra informaci\u00f3n. Por lo tanto, puede activarse accidentalmente si el usuario recarga la p\u00e1gina, abre el enlace en otra pesta\u00f1a, el navegador intenta previsualizarlo o incluso si alg\u00fan rastreador accede a esa URL.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">La forma m\u00e1s adecuada ser\u00eda usar una ruta <code>POST<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Route::post('\/admin\/sincronizar-productos', &#91;SyncController::class, 'syncProducts'])\n    -&gt;name('admin.products.sync');<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Y ejecutarla desde un formulario:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;form action=\"{{ route('admin.products.sync') }}\" method=\"POST\"&gt;\n    @csrf\n\n    &lt;button type=\"submit\" class=\"btn btn-primary\"&gt;\n        Sincronizar productos\n    &lt;\/button&gt;\n&lt;\/form&gt;<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Aunque el formulario no env\u00ede campos adicionales, el uso de <code>POST<\/code> comunica correctamente que se trata de una acci\u00f3n, no de una simple consulta.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Por qu\u00e9 evitar GET para acciones importantes<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Usar <code>GET<\/code> para ejecutar acciones puede provocar varios problemas:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>La acci\u00f3n puede ejecutarse accidentalmente al recargar la p\u00e1gina.<\/li>\n\n\n\n<li>La URL puede compartirse o abrirse sin intenci\u00f3n.<\/li>\n\n\n\n<li>Un navegador puede intentar previsualizar o precargar el enlace.<\/li>\n\n\n\n<li>Un bot o rastreador podr\u00eda visitar la ruta.<\/li>\n\n\n\n<li>No se aprovecha la protecci\u00f3n CSRF de la misma manera que con formularios <code>POST<\/code>.<\/li>\n\n\n\n<li>Se rompe la sem\u00e1ntica de la aplicaci\u00f3n, porque una consulta termina modificando el sistema.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Por eso, aunque usar <code>GET<\/code> pueda parecer m\u00e1s c\u00f3modo visualmente, no siempre es la opci\u00f3n correcta.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">La importancia del CSRF<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">En frameworks como Laravel, los formularios <code>POST<\/code> suelen incluir un token CSRF para validar que la petici\u00f3n realmente fue generada desde la aplicaci\u00f3n y no desde un sitio externo.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ejemplo:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;form action=\"{{ route('admin.products.sync') }}\" method=\"POST\"&gt;\n    @csrf\n\n    &lt;button type=\"submit\"&gt;\n        Ejecutar sincronizaci\u00f3n\n    &lt;\/button&gt;\n&lt;\/form&gt;<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">La directiva <code>@csrf<\/code> genera un token oculto que Laravel verifica al recibir la solicitud. Esto ayuda a proteger acciones sensibles como guardar informaci\u00f3n, eliminar registros o ejecutar procesos administrativos.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u00bfQu\u00e9 pasa si el formulario afecta el dise\u00f1o?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">En ocasiones se evita usar un formulario porque visualmente no encaja bien dentro de un grupo de botones o dentro de una interfaz administrativa. Sin embargo, ese es un problema de presentaci\u00f3n, no de arquitectura.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Podemos mantener el m\u00e9todo correcto y ajustar el dise\u00f1o con CSS:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;div class=\"btn-group\" role=\"group\">\n    &lt;a href=\"{{ route('admin.products.index') }}\" class=\"btn btn-secondary\">\n        Regresar\n    &lt;\/a>\n\n    &lt;form action=\"{{ route('admin.products.sync') }}\" method=\"POST\" class=\"m-0 d-inline\">\n        @csrf\n        &lt;button type=\"submit\" class=\"btn btn-primary\">\n            Sincronizar\n        &lt;\/button>\n    &lt;\/form>\n&lt;\/div><\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Tambi\u00e9n puede resolverse con una petici\u00f3n AJAX usando <code>fetch<\/code>, manteniendo el m\u00e9todo <code>POST<\/code> y enviando el token CSRF en los encabezados.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;button type=\"button\" id=\"btn-sync\" class=\"btn btn-primary\"&gt;\n    Sincronizar\n&lt;\/button&gt;\n\n&lt;script&gt;\ndocument.getElementById('btn-sync').addEventListener('click', function () {\n    fetch('\/admin\/sincronizar-productos', {\n        method: 'POST',\n        headers: {\n            'X-CSRF-TOKEN': document.querySelector('meta&#91;name=\"csrf-token\"]').content,\n            'Accept': 'application\/json'\n        }\n    });\n});\n&lt;\/script&gt;<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Lo importante es no cambiar a <code>GET<\/code> solo porque est\u00e9ticamente es m\u00e1s c\u00f3modo usar un enlace.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">GET no debe tener efectos secundarios<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Una buena pr\u00e1ctica es que las rutas <code>GET<\/code> no tengan efectos secundarios importantes. Es decir, visitar una URL con <code>GET<\/code> no deber\u00eda crear registros, eliminar informaci\u00f3n, actualizar inventario ni ejecutar procesos internos.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Por ejemplo, estas rutas deber\u00edan evitarse:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">GET \/admin\/eliminar-producto\/10\nGET \/admin\/procesar-pedidos\nGET \/admin\/sincronizar-inventario\nGET \/admin\/ejecutar-comando<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Aunque t\u00e9cnicamente puedan funcionar, no son una buena pr\u00e1ctica porque una simple visita a la URL puede cambiar el estado del sistema.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Entonces, \u00bfcu\u00e1ndo usar cada uno?<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Situaci\u00f3n<\/th><th>M\u00e9todo recomendado<\/th><th>Motivo<\/th><\/tr><\/thead><tbody><tr><td>Mostrar un listado<\/td><td>GET<\/td><td>Solo consulta informaci\u00f3n.<\/td><\/tr><tr><td>Ver detalle de un registro<\/td><td>GET<\/td><td>No modifica datos.<\/td><\/tr><tr><td>Mostrar un formulario<\/td><td>GET<\/td><td>Solo carga la interfaz.<\/td><\/tr><tr><td>Guardar un formulario<\/td><td>POST<\/td><td>Crea o modifica informaci\u00f3n.<\/td><\/tr><tr><td>Ejecutar una sincronizaci\u00f3n<\/td><td>POST<\/td><td>Dispara un proceso interno.<\/td><\/tr><tr><td>Eliminar un registro<\/td><td>DELETE o POST<\/td><td>Modifica el estado del sistema.<\/td><\/tr><tr><td>Actualizar informaci\u00f3n<\/td><td>PUT, PATCH o POST<\/td><td>Modifica datos existentes.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">M\u00e1s all\u00e1 de GET y POST<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">En aplicaciones modernas tambi\u00e9n es com\u00fan utilizar otros m\u00e9todos HTTP:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>PUT<\/code>: para actualizar completamente un recurso.<\/li>\n\n\n\n<li><code>PATCH<\/code>: para actualizar parcialmente un recurso.<\/li>\n\n\n\n<li><code>DELETE<\/code>: para eliminar un recurso.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Sin embargo, en formularios HTML tradicionales normalmente se trabaja con <code>GET<\/code> y <code>POST<\/code>. Frameworks como Laravel permiten simular m\u00e9todos como <code>PUT<\/code>, <code>PATCH<\/code> o <code>DELETE<\/code> mediante campos ocultos.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;form action=\"{{ route('admin.products.destroy', $product) }}\" method=\"POST\">\n    @csrf\n    @method('DELETE')\n    &lt;button type=\"submit\">\n        Eliminar producto\n    &lt;\/button>\n&lt;\/form><\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Esto permite mantener una estructura m\u00e1s clara y alineada con las buenas pr\u00e1cticas de desarrollo web.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Ejemplo pr\u00e1ctico de flujo correcto<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Supongamos que tenemos un m\u00f3dulo de pedidos y necesitamos estas acciones:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">GET    \/admin\/pedidos              \u2192 Mostrar pedidos\nGET    \/admin\/pedidos\/15           \u2192 Ver detalle del pedido\nGET    \/admin\/pedidos\/create       \u2192 Mostrar formulario\nPOST   \/admin\/pedidos              \u2192 Guardar pedido\nPOST   \/admin\/pedidos\/sincronizar  \u2192 Ejecutar sincronizaci\u00f3n\nDELETE \/admin\/pedidos\/15           \u2192 Eliminar pedido<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Este tipo de estructura permite entender r\u00e1pidamente qu\u00e9 hace cada ruta y qu\u00e9 impacto tiene dentro de la aplicaci\u00f3n.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusi\u00f3n<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Elegir entre <code>GET<\/code> y <code>POST<\/code> no deber\u00eda depender \u00fanicamente de si enviamos par\u00e1metros o de qu\u00e9 opci\u00f3n se ve mejor en la interfaz. La decisi\u00f3n debe basarse en la intenci\u00f3n de la ruta.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Si la ruta solo consulta o muestra informaci\u00f3n, <code>GET<\/code> es correcto. Si la ruta guarda, modifica, elimina o ejecuta un proceso dentro del sistema, entonces debe usarse <code>POST<\/code> u otro m\u00e9todo adecuado.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">En proyectos reales, esta diferencia ayuda a construir aplicaciones m\u00e1s seguras, ordenadas y f\u00e1ciles de mantener. Adem\u00e1s, evita que acciones importantes se ejecuten accidentalmente desde una URL que deber\u00eda ser \u00fanicamente de consulta.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">La interfaz siempre se puede ajustar con CSS o JavaScript, pero la intenci\u00f3n t\u00e9cnica de una ruta debe mantenerse clara desde el dise\u00f1o de la aplicaci\u00f3n.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>En este art\u00edculo veremos cu\u00e1ndo usar el m\u00e9todo GET o POST y porque en el desarrollo web&#8230;<\/p>\n","protected":false},"author":1,"featured_media":308,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6],"tags":[],"class_list":["post-307","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-laravel-php"],"_links":{"self":[{"href":"https:\/\/www.mariatech.com.mx\/blog\/wp-json\/wp\/v2\/posts\/307","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.mariatech.com.mx\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.mariatech.com.mx\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.mariatech.com.mx\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.mariatech.com.mx\/blog\/wp-json\/wp\/v2\/comments?post=307"}],"version-history":[{"count":0,"href":"https:\/\/www.mariatech.com.mx\/blog\/wp-json\/wp\/v2\/posts\/307\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.mariatech.com.mx\/blog\/wp-json\/wp\/v2\/media\/308"}],"wp:attachment":[{"href":"https:\/\/www.mariatech.com.mx\/blog\/wp-json\/wp\/v2\/media?parent=307"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.mariatech.com.mx\/blog\/wp-json\/wp\/v2\/categories?post=307"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.mariatech.com.mx\/blog\/wp-json\/wp\/v2\/tags?post=307"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}