IR
irwinrodriguez.dev
Volver a documentación

Primeros pasos

De cero a un endpoint sirviendo, en siete pasos. Cada salida que aparece aquí está copiada de una ejecución real, no escrita de memoria. Válido para FoxServer 0.9.38.

Antes de empezar

  • Visual FoxPro 9 SP2. Es tu código el que se publica: FoxServer no traduce nada.
  • FoxServer 0.9.38 instalado y con licencia. El instalador deja bin\ (el host), cli\ (la línea de comandos) e ide\ (el taller). Ver Instalación.
  • Una consola elevada, y sólo para el paso 4. Sin ella, ese comando sale con 17 y no toca nada.
  • curl, que Windows ya trae, o cualquier cliente HTTP.

Si usas la CLI de una instalación no tienes que configurar nada: encuentra el taller y el host mirándose los pies (<raíz>\ide\providers\web y <raíz>\bin\), esté la raíz donde esté. Con una CLI suelta, define FOXSERVER_TOOLING una vez.

Dos cosas que conviene entender antes

Tu código sigue siendo tuyo. Sólo se publica.

Una PROCEDURE de una clase VFP se convierte en un endpoint HTTP declarando una cláusula HELP. No hay framework que aprender ni arquitectura que cambiar.

pHola: una PROCEDURE publicada como endpoint
PROCEDURE pHola(req, res) HELP "GET: hola public"
    RETURN THIS.Ok(THIS.NewObject("mensaje"))
ENDPROC

La ruta no existe hasta que compilas.

La ruta nace en esa cláusula HELP y sólo llega al servidor cuando el hook la extrae durante el build. Es la causa número uno de «he añadido el endpoint y me da 404». Si añades una ruta y no aparece: falta compilar.

1. Crear el proyecto

La CLI vive en cli\foxserver.exe de la instalación. Este comando deja el árbol de carpetas, el .pjx y el manifiesto del servidor en build\.

foxserver init --name Almacen --path C:\proyectos\almacen --port 8099 --format json
{
  "created": true,
  "name": "Almacen",
  "path": "C:\\proyectos\\almacen\\"
}

Fíjate en que el manifiesto existe antes de compilar nada: es lo que hace que los comandos de consulta funcionen desde ya.

2. Añadir un controlador

Escribe el .prg y lo enlaza al .pjx. Es idempotente: sobre uno que ya existe sale con 0 y un aviso, sin pisar el contenido.

foxserver controller-add --project C:\proyectos\almacen --name Articulos --format json
{
  "created": true,
  "controller": "Articulos",
  "file": "C:\\proyectos\\almacen\\src\\controllers\\Articulos.prg"
}

Si el fichero se crea pero no queda enlazado, sale con 14: un controlador que no está en el proyecto, para el servidor no existe.

3. Añadir un endpoint

Esto escribe en el fuente un procedure con su cláusula HELP, que es lo que crea la ruta. Ábrelo: dentro hay una clase VFP que hereda de ApiController.

foxserver endpoint-add --project C:\proyectos\almacen --controller Articulos `
                      --method get --route articulos --proc pArticulos --public --format json
{
  "created": true,
  "controller": "Articulos",
  "method": "GET",
  "route": "articulos",
  "proc": "pArticulos",
  "public": true
}
ArticulosController: lo que escribe endpoint-add
DEFINE CLASS ArticulosController AS ApiController OLEPUBLIC

    PROCEDURE pArticulos(req, res) HELP "GET: articulos public"
        LOCAL loRes
        loRes = THIS.NewObject("status,data,message")
        loRes.status  = "ok"
        loRes.data    = NULL
        loRes.message = "ok"
        res.status(200).json(THIS.ToJson(loRes))
    ENDPROC

ENDDEFINE

La cláusula HELP se lee así: "<VERBO>: <ruta> [public]". Con public, el endpoint no exige token. Y un aviso que ahorra una tarde: la cláusula HELP no puede pasar de 255 caracteres. A 256, VFP no compila y el error no menciona la longitud por ningún lado.

Aquí es donde todo el mundo se desconcierta. Lanza endpoint-list ahora y te devuelve []. info dirá "endpoints": 0 y openapi dirá "paths": []. No está roto: el endpoint vive en el fuente y no llega al manifiesto hasta que el hook lo extrae al compilar. Sigue al paso 4.

4. Compilar: la única pared

foxserver build --project C:\proyectos\almacen --format json

Desde una consola normal esto no va a funcionar, y es a propósito. Esto es lo que sale:

foxserver: hace falta una consola ELEVADA para compilar.

  BUILD MTDLL registra la coclase en COM al terminar, y sin
  permisos falla con el error 1640 dejando una DLL sin type
  library. Compila, pesa una decima parte y el motor no puede
  activar nada de ella.

  No se ha tocado nada. Abre una consola como administrador y
  repite el comando.

Exit 17, y no ha tocado nada. Abre PowerShell como administrador y repítelo. Un aviso build.register al final no es un fallo: la DLL está compilada y el exit es 0.

Ahora sí, el endpoint existe para el servidor:

foxserver endpoint-list --project C:\proyectos\almacen --format json

5. Servir

Arranca y vuelve, dándote el pid. No bloquea salvo que pases --attach. Para pararlo, mata ese PID.

foxserver serve --project C:\proyectos\almacen --format json

6. Probar

curl http://127.0.0.1:8099/articulos
Si te devuelve 403 y no 200, no es tu endpoint: es la licencia. Una licencia Developer sólo acepta peticiones desde 127.0.0.1. Desde otra máquina hace falta una Runtime.

7. Y cuando quieras que forme parte de la instalación

serve sirve desde el proyecto: levanta el host apuntando a la carpeta build\ del proyecto y no toca nada de la instalación. Está bien para probar, pero ese servidor no lo ve verify.cmd ni lo levanta el servicio de Windows, porque los dos miran la config\servers\ de la raíz.

foxserver deploy --project C:\proyectos\almacen
Desplegado Almacen en la instalacion:
  C:\Program Files\FoxServer\config\servers\ALMACEN.json
  clave: 127.0.0.1:8099:

Comprueba antes de escribir que no haya otro manifiesto con la misma clave host:puerto:prefijo: si lo hay, sale con 11 y dice cuál es, porque el host arrancaría uno y omitiría el otro con un aviso que sólo se ve en el log. --force lo salta.

La alternativa sin línea de comandos. Todo lo anterior se puede hacer desde FoxForge, el taller que el instalador deja en ide\ y que se abre con foxforge.cmd dentro del IDE de Visual FoxPro 9: menú Nuevo › Servicio web / API REST. Hace lo mismo que init, controller-add y endpoint-add, con formularios en vez de comandos. Tienes el tutorial paso a paso desde el IDE.

Comprobar sin levantar nada

Estos funcionan desde el paso 1, con el proyecto sin compilar:

foxserver doctor          --project C:\proyectos\almacen    # que le falta y por donde se expone
foxserver validate        --project C:\proyectos\almacen    # exit 11 si hay errores
foxserver info            --project C:\proyectos\almacen --format json
foxserver openapi         --project C:\proyectos\almacen    # el contrato, sin levantar el servidor
foxserver middleware-list --project C:\proyectos\almacen    # auth, logging, status, sse...

Si algo va mal

ExitQué pasaQué hacer
2Falta un argumento obligatorio, o un enumerado no valefoxserver describe te da el esquema exacto
10No hay manifiesto en build\Esa carpeta no es un proyecto FoxServer. No es «falta compilar»: el manifiesto lo crea init
11El proyecto tiene errores de validaciónfoxserver validate los lista con su severidad
12Falta el tooling de FoxForgeUsa la CLI de una instalación, o define FOXSERVER_TOOLING
13No encuentra vfp9.exe--vfp <ruta> o FOXSERVER_VFP
14La escritura fallóMira si el .prg quedó enlazado al .pjx
16No encuentra FoxServer.Host.exeUsa la CLI de una instalación, o --host <ruta>
17build sin consola elevadaAbre una como administrador
18La compilación fallóLos errores salen por stderr, con fichero y línea, del .ERR de VFP. Si había MTDLL anterior sigue en pie: el servidor estaría sirviendo el código de antes

Siguientes pasos