IR
irwinrodriguez.dev
Back to docs

Quick Start

In under 5 minutes you will have an HTTP server running in VFP and responding to REST requests.

Prerequisites

  • FoxServer installed and licensed
  • VFP 9 SP2 or higher installed
  • WinFx installed (visual project generator, optional but recommended)

1. Create the project

Open WinFx and create a new API project. This automatically generates the folder structure and configuration file.

Alternatively, manually create a .prg file with the controller:

2. Define the controller

The controller is a VFP class that inherits from ApiController. Each public method with a HELP comment is an endpoint:

* HelloController.prg
DEFINE CLASS HelloController AS ApiController OLEPUBLIC

    PROCEDURE GetHello(req, res) HELP "GET: hello public"
        LOCAL loResp
        loResp = THIS.newObject("status,message")
        loResp.status  = "success"
        loResp.message = "Hello from FoxServer!"
        res.status(200).json(THIS.ToJson(loResp))
    ENDPROC

    PROCEDURE GetVersion(req, res) HELP "GET: hello/version public"
        LOCAL loResp
        loResp = THIS.newObject("version,server")
        loResp.version = "1.0.0"
        loResp.server  = "FoxServer"
        res.status(200).json(THIS.ToJson(loResp))
    ENDPROC

ENDDEFINE
ElementDescription
ApiControllerFoxServer base class — provides request, response and JSON utilities
HELP "GET: hello public"Declares the endpoint: HTTP method + route + visibility (public = no JWT)
reqObject with all information about the incoming request
resObject to build and send the HTTP response
THIS.newObject(fields)Creates a dynamic VFP object with the indicated properties
THIS.ToJson(obj)Serializes a VFP object to a JSON string
res.status(200).json(json)Sends response with HTTP code 200 and JSON body

3. Compile the project

Compile from WinFx or from VFP. The compiler generates an Interop DLL file that FoxServer loads.

4. Start the server

Start FoxServer pointing to your compiled project. If using Windows Service mode, see the Advanced Features section.

FoxServer.exe --project "C:\MiProyecto\config\myapi.json"

5. Test the endpoint

With the server running on port 8080, test from curl, Postman or the browser:

# GET /api/hello
curl http://localhost:8080/api/hello

# Response:
# {"status":"success","message":"Hello from FoxServer!"}

Adding URL parameters

Parameters are declared in curly braces in the route and accessed via req.params:

PROCEDURE GetUser(req, res) HELP "GET: users/{id} public"
    LOCAL lcId, loResp
    lcId = req.params.id        && "123" from /api/users/123
    loResp = THIS.newObject("id,found")
    loResp.id    = lcId
    loResp.found = .T.
    res.status(200).json(THIS.ToJson(loResp))
ENDPROC
curl http://localhost:8080/api/users/123
# {"id":"123","found":true}

Reading the body (POST)

For POST requests with JSON body, access req.json:

PROCEDURE PostProduct(req, res) HELP "POST: products public"
    LOCAL loBody, loResp

    && Body: {"name":"Widget","price":9.99}
    IF ISNULL(req.json) OR EMPTY(req.json.name)
        res.status(400).json('{"error":"name is required"}')
        RETURN
    ENDIF

    loResp = THIS.newObject("status,name,price")
    loResp.status = "created"
    loResp.name   = req.json.name
    loResp.price  = req.json.price
    res.status(201).json(THIS.ToJson(loResp))
ENDPROC
curl -X POST http://localhost:8080/api/products \
  -H "Content-Type: application/json" \
  -d '{"name":"Widget","price":9.99}'
# {"status":"created","name":"Widget","price":9.99}

Next steps