IR
irwinrodriguez.dev
Volver a documentación

Configuración

Cada servidor es un fichero JSON (su manifiesto) en config\servers\. Lo crea foxserver init y lo actualiza el hook al compilar; también puedes editarlo a mano, y FoxForge lo edita con formularios desde el IDE de VFP.

Ubicación del archivo de configuración

Cada proyecto tiene su propio archivo en:

C:\Program Files\FoxServer\config\servers\{projectname}.json

Ejemplo completo

Manifiesto completo de un servidor
{
  "name": "almacen",
  "description": "API de almacen",
  "type": "api",
  "active": true,
  "host": "127.0.0.1",
  "port": 8099,
  "prefix": "",
  "issecure": false,
  "certificatename": "",
  "certificatepassword": "",
  "dllpath": "C:\\proyectos\\almacen\\build\\almacen.dll",
  "allowedorigins": "https://miapp.com",
  "allowedmethods": "GET,POST,PUT,DELETE,OPTIONS",
  "allowedheaders": "Content-Type,Authorization",
  "lifecycle": {
    "enabled": true,
    "classname": "MiErpLifecycleClass"
  },
  "hotreload": {
    "enabled": false,
    "debouncems": 1500,
    "maxretries": 3
  },
  "server": {
    "checkstatusenabled": true,
    "endpoint": "server/status"
  },
  "middleware": {
    "auth": {
      "enabled": true,
      "type": "jwt",
      "secret": "",
      "tokenexpirationseconds": 3600,
      "loginendpoint": "auth/login"
    },
    "logging": {
      "enabled": true,
      "path": "C:\\proyectos\\almacen\\logs\\",
      "fileprefix": "almacen",
      "format": "Detailed",
      "options": {
        "requests": true,
        "responses": true,
        "errors": true,
        "debug": false,
        "performance": true
      }
    }
  }
}
El secreto del JWT va VACÍO en este ejemplo a propósito, y el certificado también: un manifiesto de ejemplo con algo que parezca una clave acaba copiado tal cual a producción. El manifiesto vive en config\servers\ junto a la licencia (config\foxserver.lic), así que trata esa carpeta como lo que es: secretos.

Propiedades del servidor

PropiedadTipoDefectoDescripción
name String — Identificador único del proyecto/servidor
description String "" Descripción legible para humanos
type String api "api" para REST APIs, "web" para servir archivos estaticos
active Boolean false Si el servidor se carga al arrancar FoxServer
host String 127.0.0.1 Dirección de escucha. 0.0.0.0 acepta todas las interfaces
port Number 8080 Puerto HTTP de escucha
prefix String "" Prefijo de ruta URL (ej. "/api/v1")
issecure Boolean false Habilitar HTTPS/SSL
dllpath String — Ruta a la MTDLL compilada del proyecto (requerido). Desde 0.9 el motor activa por ProgID, así que esta ruta apunta a la DLL nativa de VFP, no a un ensamblado .NET
publicdir String "" Directorio de archivos estáticos (solo type: web)

CORS

Configura los orígenes, métodos y cabeceras permitidos para peticiones entre dominios:

{
  "allowedorigins": "https://app.example.com,https://admin.example.com",
  "allowedmethods": "GET,POST,PUT,DELETE,OPTIONS",
  "allowedheaders": "Content-Type,Authorization,X-Requested-With"
}
PropiedadTipoValor por defectoDescripción
allowedoriginsString*Dominios permitidos separados por coma, o "*" para cualquiera
allowedmethodsStringGET,POST,PUT,DELETE,OPTIONSMétodos HTTP permitidos desde el navegador
allowedheadersStringContent-Type,AuthorizationCabeceras que el cliente puede enviar
En producción, especifica siempre dominios exactos en lugar de "*" para mayor seguridad.

HTTPS / SSL

Para habilitar HTTPS necesitas un certificado en formato .pfx o .p12:

{
  "issecure": true,
  "certificatename": "mycert.pfx",
  "certificatepassword": "your-cert-password"
}
Nunca incluyas contraseñas de certificados en el control de versiones. Usa variables de entorno o un gestor de secretos.

Redirecciones (sitios web)

Desde la 0.9.36 un sitio de tipo web puede contestar que algo está en otra URL. Las reglas van en la lista redirects del manifiesto y el servidor las mira antes de buscar el fichero en el disco. Una regla manda sobre lo que haya en publicdir, así que sirve también para retirar la URL de un fichero que sigue ahí, como el instalador de una versión antigua.

{
  "type": "web",
  "redirects": [
    {
      "from": "/kit/FoxAgent-Setup-1.63.2.exe",
      "to": "/kit/retired/",
      "status": 302
    },
    {
      "from": "/old-docs/",
      "to": "/docs/",
      "status": 301,
      "match": "prefix"
    }
  ],
  "trailingslashredirect": true
}
PropiedadTipoDefectoDescripción
fromString(obligatorio)Ruta que pide el cliente, empezando por /. Se compara con la ruta entera (prefijo del servidor incluido), decodificada y sin distinguir mayúsculas.
toString(obligatorio)Destino: una ruta del mismo sitio o una URL absoluta (https://...).
statusNumber302301 y 308 son permanentes y el navegador los recuerda. 302 y 307 son temporales y salen con Cache-Control: no-store.
matchStringexactexact casa la ruta entera. prefix casa todo lo que empieza por from y pega el resto a to: /old-docs/a/b pasa a /docs/a/b.
  • Gana la primera regla que casa, en el orden del fichero.
  • La query de la petición viaja al destino, salvo que to traiga la suya.
  • La respuesta lleva Location y una página HTML mínima con el enlace, para el cliente que no sigue redirecciones. A un HEAD se le contestan solo las cabeceras.
  • Una regla mal escrita se descarta al arrancar, con un aviso en el log que dice cuál y por qué: from sin la barra inicial, to vacío, un código fuera de la lista, un match desconocido o un bucle evidente (una regla prefix cuyo to empieza por su propio from). El servidor arranca igual y el resto de reglas funciona.
  • Solo las aplica un sitio de tipo web. Un servidor que sirve REST despacha por la API y no las mira; foxserver validate lo avisa.
  • El servidor lee las reglas al arrancar. Después de cambiarlas hay que reiniciarlo.

La barra final de las carpetas

Con "trailingslashredirect": true, una carpeta pedida sin la barra final (/docs/guia) contesta 301 a la misma ruta con la barra (/docs/guia/) y conserva la query, como nginx, Apache o IIS. Así cada página vive en una sola URL y sus enlaces relativos apuntan a la carpeta correcta. Viene apagada porque cambia lo que contesta un sitio ya publicado, y eso lo decide quien lo publica.

Desde la línea de órdenes

foxserver redirect-add --project C:\proyectos\web --from /kit/FoxAgent-Setup-1.63.2.exe --to /kit/retired/
foxserver redirect-add --project C:\proyectos\web --from /old-docs/ --to /docs/ --status 301 --match prefix
foxserver redirect-list --project C:\proyectos\web
foxserver redirect-remove --project C:\proyectos\web --from /old-docs/
foxserver redirect-trailing-slash --project C:\proyectos\web on

Las órdenes editan el manifiesto del proyecto (build\) y llegan al servidor con foxserver deploy, como el resto de la configuración. Un redirect-add con un from que ya existe sustituye esa regla sin moverla de su sitio. Guardar el proyecto desde FoxForge o desde la CLI conserva las reglas escritas a mano, incluidos los campos que la herramienta no conoce.

Logging

Configura el sistema de logs del servidor:

PropiedadTipoDefectoDescripción
enabledBooleanfalseActivar / desactivar el logging
pathString—Directorio donde se escriben los archivos de log (debe existir)
fileprefixStringfoxserverPrefijo del nombre de archivo. Resultado: "{prefix}_2026-04-11.log"
formatStringSimple"Simple" (una linea), "Detailed" (info completa), "JSON"
options.requestsBooleantrueRegistrar peticiones entrantes
options.responsesBooleantrueRegistrar respuestas salientes
options.errorsBooleantrueRegistrar errores
options.debugBooleanfalseRegistrar mensajes de debug (más verboso)
options.performanceBooleanfalseRegistrar tiempos de respuesta por endpoint

Siguiente: Rutas →