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

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

  • 4 min

Axios y VueJS nos permiten montar un frontend reactivo que consume un API REST servido desde un ESP32 o ESP8266, separando la interfaz web de la lógica del dispositivo.

La idea es unir dos piezas que encajan muy bien: Axios para realizar las peticiones HTTP y VueJS para mantener sincronizada la interfaz. El microcontrolador actúa como backend, sirviendo el API REST y la página web que ejecuta el navegador.

Con esto podemos hacer una aplicación web bastante más limpia que un conjunto de botones y llamadas sueltas. Cada parte se ocupa de lo suyo, que siempre ayuda a que el código no acabe convertido en una madeja.

En primer lugar, el backend en este ejemplo es el mismo que usamos para servir un API REST con JSON. Es decir, el código en el ESP8266 no va a cambiar.

Así que para no ser pesado y hacer innecesariamente largo el artículo lo vamos a omitir. Lo tenéis en los ejemplos anteriores del curso 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>ESP32 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/[email protected]/dist/vue.min.js"></script>-->
  <!--<script src="https://cdn.jsdelivr.net/npm/[email protected]/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>
Copied!

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');
        },  
    }
})
Copied!

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 () {
    });
}
Copied!

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 ESP32 que las acciones e información se reciben correctamente en el backend.

esp8266-vuejs-axios-serial

Aunque visualmente la página todavía sea sencilla, hemos dado un paso importante en la integración de aplicaciones web más complejas desde el ESP32. Ahora no usamos JavaScript “pelao”, sino dos librerías muy útiles como Axios y VueJS.

Con esto tenemos una base más mantenible para construir interfaces web que consumen un API REST servido desde el propio dispositivo.

Descarga el código

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