como-servir-y-consumir-un-api-rest-con-esp8266-axios-y-vuejs

Cómo servir y consumir un Api Rest con ESP8266, Axios y VueJs

Nueva entrada sobre el ESP8266 en la que vamos a ver cómo consumir un API Rest con la librería Axios, desde una aplicación en VueJs servida desde el ESP8266.

En la entrada anterior nos quedamos viendo cómo consumir con un ESP8266 y la librería Axios, usando únicamente Vanilla Javascript. Por otro lado, ya vimos cómo servir una aplicación en VueJs en esta entrada.

Hoy toca dar un pasito más y unir ambos componentes, Axios y VueJS, para hacer una aplicación Web que se comunique con el ESP8266 como backend a través de un API Rest, empleando Axios.

Por supuesto, si aún no habéis visto las entradas anteriores, sería buen momento para echarles un repaso porque vamos a con lo que vimos.

¡Comencemos! En primer lugar, el backend en este ejemplo es idéntico al de la entrada anterior. Es decir, el código en el ESP8266 no va a cambiar.

Así que para no ser pesado y hacer innecesariamente larga la entrada lo vamos a omitir. Lo tenéis en los ejemplos anteriores de la serie y en el código en Github.

Lo que sí va a cambiar, por supuesto, es el frontend que vamos a servir desde el SPIFFS, que ahora pasa a ser.

Donde vemos que el código de nuestra página ha pasado a estar adornado por las etiquetas propias de una App en VueJs.

<!DOCTYPE html>
<html>
<head>
  <title>ESP8266 Vue + Axios</title>
  <meta charset="utf-8">
  <meta http-equiv="x-ua-compatible" content="ie=edge">
  <meta name="description" content="">
  <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
 
  <!-- Nuestra simple APP de ejemplo -->
  <div id="app">
  <div>
    <button v-on:click="getAll()">GetAll</button>
  </div>
  <div>
    <button v-on:click="get()">Get</button>
    <input v-model="getId" placeholder="getId">
  </div>
  <div>
    <button v-on:click="getFiltered()">Filter</button>
    <input v-model="filter" placeholder="filter">
  </div>
  <div>
    <button v-on:click="create()">Create</button>
  </div>
    <div>
      <my-component v-for="item in items" v-bind:my="item" v-bind:key="item.id"></my-component>
   </div>
  </div>
 
  <!-- Desde CDN -->
  <!--<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.min.js"></script>-->
  <!--<script src="https://cdn.jsdelivr.net/npm/axios@0.18.0/dist/axios.min.js"></script>-->

  <script type="text/javascript" src="./vendor/vue.min.js"></script>
  <script type="text/javascript" src="./vendor/axios.min.js"></script>
    
  <!-- Cargamos los ficheros que simular nuestro API y nuestra App en Vue.JS -->
  <script type="text/javascript" src="./js/API.js"></script>
  <script type="text/javascript" src="./js/app.js"></script>
</body>
</html>

La aplicación en VueJS la tenemos definida en el fichero ‘app.js’. Es muy sencilla, y básicamente expone una colección de objetos ‘items’, y los métodos necesarios para llamar a nuestro API del ejemplo.

Vue.component('my-component', {
    props: ['my'],
    template: '<div>{{my.text}}<button v-on:click="get(my.id)">Get</button><button v-on:click="update(my.id)">Update</button><button v-on:click="replac(my.id)">Replace</button><button v-on:click="delet(my.id)">Delete</button></div>',
    methods: {
        get: function (id) {
            API_get(id);
        },
        
        update: function (id) {
            API_update(id, 'NewItem');
        },
        
        replac: function (id) {
            API_replace(id, 'NewItem');
        },
        
        delet: function (id) {
            API_delete(id);
        }
    }
})

var app = new Vue({
    el: '#app',
    data: {
        filter: "",
    getId: "",
        items: [
            { id: 0, text: 'Item1'},
            { id: 1, text: 'Item2' },
            { id: 2, text: 'Item3'}
        ]
    },
    
    methods: {
        getAll() {
            API_getAll();
        },
        
    get() {
            API_get(this.$data.getId);
        },
    
        getFiltered() {
            API_getFiltered(this.$data.filter);
        },
        
        create() {
            API_create('NewItem');
        },  
    }
})

El API que, a su vez, tenemos definido en el fichero ‘API.js’. Estas funciones emplean Axios para realizar las llamadas de nuestro API Rest, como vimos en la entrada anterior.

function API_get(id) {
    axios.get('item/' + id)
    .then(function (response) {
        console.log(response);
    })
    .catch(function (error) {
        console.log(error);
    })
    .then(function () {
    });
}

function API_getFiltered(filter) {
    axios.get('item', {
        params: {
            filter: filter
        }
    })
    .then(function (response) {
        console.log(response);
    })
    .catch(function (error) {
        console.log(error);
    })
    .then(function () {
    });
}

function API_getAll() {
    axios.get('item')
    .then(function (response) {
        console.log(response);
    })
    .catch(function (error) {
        console.log(error);
    })
    .then(function () {
    });
}

function API_create(data) {
    axios.post('item', {
        data: data
    })
    .then(function (response) {
        console.log(response);
    })
    .catch(function (error) {
        console.log(error);
    })
    .then(function () {
    });
}

function API_replace(id, data) {
    axios.put('item/ ' + id, {
        data: data
    })
    .then(function (response) {
        console.log(response);
    })
    .catch(function (error) {
        console.log(error);
    })
    .then(function () {
    });
}

function API_update(id, data) {
    axios.patch('item/ ' + id, {
        data: data
    })
    .then(function (response) {
        console.log(response);
    })
    .catch(function (error) {
        console.log(error);
    })
    .then(function () {
    });
}

function API_delete(id) {
    axios.delete('item/' + id)
    .then(function (response) {
        console.log(response);
    })
    .catch(function (error) {
        console.log(error);
    })
    .then(function () {
    });
}

Resultado

Subimos nuestra nueva página a la memoria del SPIFFS, y al cargarla en el navegador vemos la misma página que el anterior.

esp8266-vuejs-axios-web

Si interactuamos con los botones comprobamos en la consola de desarrollador del navegador que las acciones se realizan correctamente.

esp8266-vuejs-axios-console

Así como podemos verificar en el terminal del puerto serie del ESP8266 que, efectivamente, las acciones e información se reciben correctamente en el backend.

esp8266-vuejs-axios-serial

Que diréis. ¡Pero si es la misma página fea que el ejemplo anterior! Bueno, no, hemos dado un pasito más en la integración para servir e interactuar con Apps complejas desde el ESP8266. Ahora no usamos Javascript ‘pelao’, si no que incorporamos dos potentes librerías como Axios y VueJS.

En la próxima entrada daremos un pasito más integrando Vuetify, volviendo a conseguir un aspecto Material Design más moderno para nuestra aplicación. ¡Hasta la próxima entrada!

Descarga el código

Todo el código de esta entrada está disponible para su descarga en GitHub. github-full