{"id":26232656,"url":"https://github.com/emptyshop/vuerestapiclient","last_synced_at":"2026-04-09T16:03:45.905Z","repository":{"id":280722978,"uuid":"887438977","full_name":"EmptyShop/VueRestApiClient","owner":"EmptyShop","description":"Contact List Client (CRUD \u0026 REST API) (Vue Implementation)","archived":false,"fork":false,"pushed_at":"2025-03-05T00:05:45.000Z","size":19,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-05T01:19:24.908Z","etag":null,"topics":["api-rest","bootstrap5","vue","vuerouter"],"latest_commit_sha":null,"homepage":"","language":"Vue","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/EmptyShop.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-11-12T18:41:08.000Z","updated_at":"2025-03-05T00:05:48.000Z","dependencies_parsed_at":"2025-03-05T01:19:28.641Z","dependency_job_id":"3f385f7d-b8b3-4f3b-9dab-50c1ee3f12d7","html_url":"https://github.com/EmptyShop/VueRestApiClient","commit_stats":null,"previous_names":["emptyshop/vuerestapiclient"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EmptyShop%2FVueRestApiClient","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EmptyShop%2FVueRestApiClient/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EmptyShop%2FVueRestApiClient/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EmptyShop%2FVueRestApiClient/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/EmptyShop","download_url":"https://codeload.github.com/EmptyShop/VueRestApiClient/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243318772,"owners_count":20272136,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api-rest","bootstrap5","vue","vuerouter"],"created_at":"2025-03-13T00:37:54.095Z","updated_at":"2026-04-09T16:03:45.878Z","avatar_url":"https://github.com/EmptyShop.png","language":"Vue","funding_links":[],"categories":[],"sub_categories":[],"readme":"# VueRestApiClient\nCliente de API Rest (Vue)\n\nEste proyecto lo hice como parte de un conjunto de aplicaciones que consumen una API que programé en Python para las operaciones básicas (CRUD) de una lista de contactos: [Contact List App](https://github.com/EmptyShop/FlaskSqlAlchemyApp). Este proyecto (VueRestApiClient) es un cliente para Web, codificado en Vue. La UI contiene una tabla con la lista de contactos registrados y un contenedor con 3 campos de texto correspondientes a nombre, email y teléfono para editar sus valores.\n\n# Cómo lo Hice\n\n## En este proyecto utilicé:\n\n* Vue 3.5.12\n* Vue Router 4.4.5\n* Bootstrap 5.3.3\n* Bootstrap Icons 1.11.3\n* Vite 5.4.10\n\n# Lo implementé así:\n\n  * En el archivo `main.js`, ubicado en `src`, asigné las rutas a la aplicación y generé una variable para la URL de la API externa.\n  * En el componente `router` ubicado en `src/router/index.js` configuré las rutas de la aplicación de la siguiente forma:\n\n    ```js\n    const router = createRouter({\n      history: createWebHistory(import.meta.env.BASE_URL),\n      routes: [\n        {\n          path: '/',\n          name: 'home',\n          component: HomeView\n        },\n        {\n          path: '/create',\n          name: 'create',\n          // route level code-splitting\n          // this generates a separate chunk (About.[hash].js) for this route\n          // which is lazy-loaded when the route is visited.\n          component: () =\u003e import('@/views/CreateView.vue')\n        },\n        {\n          path: '/edit/:id(\\\\d+)',\n          name: 'edit',\n          component: () =\u003e import('@/views/EditView.vue')\n        },\n        {\n          path: '/:pathMatch(.*)*',\n          name: 'NotFound',\n          component: () =\u003e import('@/components/NotFound.vue')\n        }\n      ]\n    })\n    ```\n\n  * El componente `HomeView`, ubicado en `src/views`, contiene el módulo principal de la aplicación. En este componente utilizo `fetch()` para consumir los servicios REST. Utilizo también `ref()` sobre la variable `contacts` para tener actualizada de forma automática la UI con la lista de contactos.\n  * El componente `CreateView` contiene los campos de texto necesarios para crear un nuevo contacto. De igual forma que en el componente principal, uso `fetch()` para enviar la solicitud **POST** hacia la API.\n  * El componente `EditView` contiene los campos de texto necesarios para editar los datos de un contacto existente, especificado por el componente principal. De igual forma que en el componente principal, uso `fetch()` para enviar las solicitudes **GET** y **PUT** hacia la API. También uso `ref()` para actualizar automáticamente los valores del contacto en los campos de texto cuando se recibe desde el servicio externo.\n\n## La ayuda que utilicé:\nPara este proyecto me basé en un video tutorial que muestra cómo consumir servicios Restful con Vue. Yo lo adapté a mi propia API y además me apoyé en información complementaria:\n\n  * [Consumir API con Vue](https://www.youtube.com/watch?v=yKpdX0Fdy60)\n  * [Tutorial Vue.js](https://vuejs.org/tutorial/#step-1)\n  * [Creating a Vue Application](https://vuejs.org/guide/essentials/application.html)\n  * [Named Routes](https://router.vuejs.org/guide/essentials/named-routes.html)\n  * [Dynamic Route Matching with Params](https://router.vuejs.org/guide/essentials/dynamic-matching.html)\n\n# Actualización\nAgregué una ruta alterna de la API para un escenario donde el servidor principal (el que programé en Python) no estuviera ejecutándose. En este caso desarrollé otra API en c# que accede a la misma base de datos. Esta API alterna es un poco distinta a la principal (para POST y PUT devuelve respuestas diferentes), por lo que cuando la vista principal `views/HomeView.vue` detecta que no hay conexión, redirige a la vista `viewsNet/HomeView.vue`. A partir de esta vista se usa la API alterna en todas las operaciones.\n\n## Lo implementé así:\nEn `main.js`agregué la siguiente línea:\n\n```js\napp.provide('urlAPINet','https://localhost:7153/contacts');\n```\n\nEn `router/index.js` agregué las rutas para la API alterna:\n\n```js\n{\n  path: '/HomeNet',\n  name: 'homeNet',\n  component: () =\u003e import('@/viewsNet/HomeView.vue')\n},\n{\n  path: '/createNet',\n  name: 'createNet',\n  component: () =\u003e import('@/viewsNet/CreateView.vue')\n},\n{\n  path: '/editNet/:id(\\\\d+)',\n  name: 'editNet',\n  component: () =\u003e import('@/viewsNet/EditView.vue')\n},\n```\n\nAdemás, declaré 2 referencias para usarlas en el menú para las entradas de Home y Create:\n\n```js\nexport const homeLink = ref(\"/\");\nexport const createLink = ref(\"/create\");\n```\n\nEn `App.vue` importo las variables anteriores y las uso para actualizar el menú de la página:\n\n```js\nimport { homeLink, createLink } from './router';\n\n...\n\n\u003cli class=\"nav-item\"\u003e\n  \u003cRouterLink :to=\"homeLink\" class=\"nav-link active\" aria-current=\"page\" href=\"#\"\u003eContact List\u003c/RouterLink\u003e\n\u003c/li\u003e\n\u003cli class=\"nav-item\"\u003e\n  \u003cRouterLink :to=\"createLink\" class=\"nav-link\" href=\"#\"\u003eCreate\u003c/RouterLink\u003e\n\u003c/li\u003e\n```\n\nEn `views/HomeView.vue` cuando no se conecta a la API principal atrapo el error y redirecciono a la API alterna:\n\n```js\nasync function getContacts(){\n    try {\n        const res = await fetch(urlAPI);\n        \n        if (!res.ok || res.status \u003c 200 || res.status \u003e= 300){\n            console.log(res.status);\n        }\n        const data = await res.json();\n\n        contacts.value = data;\n\n        /* Al inicio de la vista pongo un mensaje de loading para esperar\n           mientras carga la API. Cuando recibe los datos quito el\n           div de loading */\n        var loadingScreen = document.querySelector('.loading');\n        loadingScreen.style.opacity = 0;\n        setTimeout(()=\u003e{\n\t        loadingScreen.style.display = 'none';\n        },1000);\n    } catch (error) {\n        console.log(\"Error fetching contacts: \", error.name, error.message);\n        router.push({name: 'homeNet'});  //redirecciono a la vista alterna\n    }\n}\n```\n\nLas vistas alternas hacen referencia a la API de c#: `const urlAPI = inject('urlAPINet');`. Además actualizo las rutas para el menú:\n\n```js\nif (homeLink.value != \"/homeNet\") {\n    homeLink.value = \"/homeNet\";\n}\nif (createLink.value != \"/createNet\") {\n    createLink.value = \"/createNet\";\n}\n```\n\n# Lo que sigue\nEl alcance de este proyecto es comparar el desempeño y las implementaciones de cada versión de app cliente para consumo de servicios Restful que tengo en este repositorio ([Angular](https://github.com/EmptyShop/AngularRestApiClient), [React](https://github.com/EmptyShop/ReactRestApiClient), Vue y [Kotlin](https://github.com/EmptyShop/KotlinRestApiClient)). Por lo que no tengo planeado agregar o modificar funcionalidades muy seguido.\n\nSiéntete libre de comentar y sugerir cosas para esta app.\n\n# Documentación Autogenerada por Vue y Vite\n\n# rest-api-client\n\nThis template should help get you started developing with Vue 3 in Vite.\n\n## Recommended IDE Setup\n\n[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur).\n\n## Customize configuration\n\nSee [Vite Configuration Reference](https://vite.dev/config/).\n\n## Project Setup\n\n```sh\nnpm install\n```\n\n### Compile and Hot-Reload for Development\n\n```sh\nnpm run dev\n```\n\n### Compile and Minify for Production\n\n```sh\nnpm run build\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Femptyshop%2Fvuerestapiclient","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Femptyshop%2Fvuerestapiclient","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Femptyshop%2Fvuerestapiclient/lists"}