Tu primera App para BigCommerce - Parte II
Un ejemplo paso a paso de una aplicación basada en Laravel que usa el módulo bigcommerce-app-adapter para comunicarse con BigCommerce
En la primera parte de este artículo hablamos de los mecanismos de extensión de BigCommerce y de cómo podemos crear y configurar nuestras propias Apps. También presentamos el módulo bigcommerce-app-adapter que nos soluciona una buena parte de la complejidad de construir una App para BigCommerce.
En esta segunda parte vamos a crear una App muy simple para demostrar:
Cómo se integra bigcommerce-app-adapter en una App
Cómo se usa el proxy incluido en bigcommerce-app-adapter
Cómo se puede desarrollar la App en un entorno local
Cómo se integra la App con BigCommerce
Nuestra App tiene una sola página: la página de inicio o home page. En está página vamos a mostrar un logotipo de nuestra empresa y un texto con el nombre de la tienda. Así de sencillo.
A pesar de esta aparente simplicidad, para que la App funcione y el nombre de la tienda se muestre tendremos que ser capaces de hacer una llamada a la API de BigCommerce que nos da este dato en particular (/v2/store
). Si esta llamada funciona, hacer uso de cualquier otro end-point de la API de BigCommerce será ya solo un asunto de tener los permisos adecuados.
Nuestra aplicación estará escrita en PHP y usaremos el framework Laravel para crearla.
Creando nuestra App paso a paso
Nuestra primera aproximación será crear una App operativa que funcione en nuestro entorno de trabajo local y con Docker.
El primer paso será crear una nueva aplicación Laravel que llamaremos ‘bc-sample-app
’:
curl -s https://laravel.build/bc-sample-app | bash
A continuación vamos a añadir el módulo bigcommerce-app-adapter a nuestra App:
cd bc-sample-app/
composer config repositories.ebolution-bigcommerce-app-adapter git https://github.com/ebolution/bigcommerce-app-adapter.git
composer require ebolution/bigcommerce-app-adapter:dev-master
Como veremos nuestro módulo arrastra una dependencia mas que es ebolution/laravel-module-manager
. Arrancamos nuestra aplicación con Docker y Sail:
vendor/bin/sail up
Abrimos una nueva ventana de shell en el mismo directorio de la App y ejecutamos los comandos de instalación del módulo:
vendor/bin/sail artisan migrate
vendor/bin/sail artisan vendor:publish --tag=bigcommerce-app-adapter --ansi
Ahora vamos a crear el código de nuestra App. Nuestra App es muy simple y consta de lo siguientes elementos:
Una ruta (
routes/web.php
)Un controlador (
app/Http/Controllers/SampleHomeController.php
)Una vista (
resources/views/home.blade.php
)Un script en JS (
public/js/home.js
)Una hoja de estilos (
public/css/styles.css
)Una imagen (
public/img/logo.png
)
Para la ruta editamos el archivo routes/web.php
dejando este contenido:
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\SampleHomeController;
Route::get('/', SampleHomeController::class);
Para el controlador creamos un nuevo controlador (vendor/bin/sail artisan make:controller SampleHomeController
) con este código:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Illuminate\View\View;
class SampleHomeController extends Controller
{
public function __invoke(Request $request): View
{
$token = $request->input('token');
return view('home', compact('token'));
}
}
Como vemos el controlador es muy sencillo y simplemente muestra la vista de la home pasándola un único dato que recibe como parámetro de entrada (token
). Más adelante hablaremos de la importancia de este parámetro. De momento lo vamos a ignorar.
La vista de nuestra home es muy sencilla, muestra una imagen y un texto centrados en el view-port:
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{ config('app.name') }}</title>
<!-- Fonts -->
<link rel="preconnect" href="https://fonts.bunny.net">
<link href="https://fonts.bunny.net/css?family=figtree:400,600&display=swap" rel="stylesheet" />
<!-- Styles -->
<link href="{{ asset('css/styles.css') }}" rel="stylesheet" />
</head>
<body>
<div class="container">
<div class="data">
<img class="image" src="{{ asset('img/logo.png') }}" alt="centered-image">
<div id="store-name"></div>
</div>
</div>
<script>
var auth_token = '{{ $token }}'
</script>
<script defer src="{{ asset('js/home.js') }}"></script>
</body>
</html>
El token
que se le pasa desde el controlador se publica como una variable JS (auth_token
). De momento solo es necesario tener en cuenta que este dato vendrá con valor null
.
Nuestro script es el que va a hacer la llamada al proxy incluido dentro de bigcommerce-app-adapter para obtener le nombre de la tienda. Si la llamada tiene éxito, se mostrará el dato recibido en el contenedor store-name
.
window.onload = function () {
fetch('/api/bc-api/v2/store', {
headers: {
'X-Auth-Token': auth_token
}
}).then(function (response) {
return response.json();
}).then(function (data) {
let container = document.getElementById("store-name");
container.innerHTML = data.name;
}).catch(function (err) {
console.warn('Something went wrong.', err);
});
};
Vemos que hacemos una llamada a la ruta /api/bc-api/v2/store
que representa una llamada a https://api.bigcommerce.com/stores/{{STORE_HASH}}/v2/store
a través del proxy, dado que esta llamada a Get Store Information nos devuelve el nombre de la tienda, entre otros detalles.
Nuestra hoja de estilos simplemente se encarga de que las cosas estén centradas:
html, body {
height: 100%;
margin: 0;
padding: 0;
}
.container {
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.data {
display: block;
text-align: center;
}
.image {
max-width: 100%;
max-height: 100%;
}
Nos faltaría la imagen (el logo de la App) que sería un archivo PNG cualquiera, con una resolución lo suficientemente pequeña para que entre en nuestro view-port (ej. aprovechamos el logo de la App para BigCommerce que es de 350×130 px).
Bien, ya tenemos nuestra App. Si tratamos de cargar la página de inicio (http://localhost), veremos esto:
Nuestra App se muestra, pero el nombre de la tienda no aparece. Si miramos los mensaje de la consola veremos un error:
Failed to load resource: the server responded with a status of 500 (Internal Server Error) /api/bc-api/v2/store:1
Básicamente nuestro problema es que no tenemos credenciales válidas para hacer llamadas autorizadas a BigCommerce y tampoco hemos configurado ningún store_hash
para hacer la llamada sobre una tienda en concreto.
Desarrollo local
En nuestra primera aproximación queremos poder desarrollar nuestra App sin necesidad de que sea realmente una App de BigCommerce instalada en una tienda. Sí necesitamos, no obstante, que nuestro proxy de BigCommerce haga llamadas a una tienda real de BigCommerce (seguramente un Sandbox) para trabajar con datos reales.
El módulo bigcommerce-app-adapter tiene un modo de desarrollo local en el que no es necesario que se invoque como una App de BigCommerce. Para activarlo hay que fijar un parámetro en nuestro .env
:
APP_ENV=local
Cuando la aplicación trabaja en modo local, hay otra serie de variables del .env
que nuestro módulo va a usar para comunicarse con BigCommerce:
BC_LOCAL_CLIENT_ID=<api-account-client-id>
BC_LOCAL_SECRET=<api-account-client-secret>
BC_LOCAL_ACCESS_TOKEN=<api-account-access-token>
BC_LOCAL_STORE_HASH=<api-account-store-hash>
Para poder asignar un valor a estas variables, debemos ir a nuestra tienda Sandbox y crear una clave de API para desarrolladores: Settings > Store-level API accounts > Create API account
Los permisos (OAuth scopes) que le demos a la clave dependerán de las llamadas que queramos hacer a la API y ya describimos en la primera parte del artículo como deducir que permisos necesitamos. Para nuestra sencilla App solo necesitamos acceso de lectura a la información y configuración básica de la tienda:
Al guardar esta clave BigCommerce descargará un fichero con un contenido similar a este:
ACCESS TOKEN: zoxzovn4u2m9bf1qidspe2aph5rhyhw
CLIENT NAME: bc-sample-app
CLIENT ID: hajgwgcb6co3176l6iyslswpk34oh6m
CLIENT SECRET: 46e123dc2435c13a969097468f8207a3ebdbee1c09c40aaea29028d8dd82c032
NAME: bc-sample-app
API PATH: https://api.bigcommerce.com/stores/23uu8ke7g0/v3/
Esta información es la necesaria para configurar nuestras variables de entorno:
BC_LOCAL_CLIENT_ID=hajgwgcb6co3176l6iyslswpk34oh6m
BC_LOCAL_SECRET=46e123dc2435c13a969097468f8207a3ebdbee1c09c40aaea29028d8dd82c032
BC_LOCAL_ACCESS_TOKEN=zoxzovn4u2m9bf1qidspe2aph5rhyhw
BC_LOCAL_STORE_HASH=23uu8ke7g0
Nótese que el store_hash
es una de las partes del API PATH.
Una vez configuradas estas variables, si recargamos la página deberíamos ver ya el nombre de nuestra tienda:
Siguientes pasos
Llegados a este punto toca desarrollar de forma local el dashboard de nuestra aplicación, junto con toda la complejidad que que conlleven nuestras reglas de negocio, y la API que nuestra App va a exponer a terceros.
Podemos hacer todo este desarrollo de forma local y sin necesidad de actuar como una verdadera App de BigCommerce, a la vez que podemos integrar llamadas a la API de BigCommerce para actuar con datos reales.
En la tercera parte de esta serie te vamos a mostrar cómo integrar nuestro desarrollo con BigCommerce, y cómo hacer que nuestra App tenga en cuenta los aspectos multi-tenant que toda buena App de BigCommerce debe observar.
Grande!! Da gusto cuando las cosas están bien explicadas y funcionan copiando y pegando... Muchas gracias por compartir Carlos!
¡¡Calidad!!