Limit the Data Returned

Description

Add an optional parameter to the page for 'primarykey' so we can limit data returned to a single record.

Note that the the Primary Key is passed to the cn.Execute() as a parameter, when exposing a service directly to the web, it is imperative that any dynamic SQL data is either validated (as the Products and Customers tablename is), Or when passing data or filter criteria, you must use SQL::Arguments to prevent SQL Injection Attacks.

<%a5
dim tablename as c 
dim primaryKeyName as c

' Validate the tablename
if eval_valid("request.variables.tablename") then
	tablename = request.variables.tablename
    if tablename <> "Customers" .and. tablename <> "Products" then
        ? "{ \"error\" : \"Cannot Access table "+tablename+"\" }"
    	end 
    end if
    if tablename = "Products" then
    	primaryKeyName = "ProductID"
    else
        primaryKeyName = "CustomerID"    
    end if
else
    ? "{ \"error\" : \"No tablename specified \" }"
  	end 
end if


dim args as sql::Arguments
dim sql as c = "select * from "+tablename

if eval_valid("request.variables.primarykey") then
   args.Set("Pkey",request.variables.primarykey)
   sql = sql + " where "+primaryKeyName+" = :PKey"
end if

dim cn as sql::Connection
cn.PortableSQLEnabled = .t.
if cn.Open("::Name::Northwind") then
	 if cn.Execute(sql,args) then
        dim rs as sql::ResultSet = cn.ResultSet
		dim responseJson as c = rs.ToJSONObjectSyntax()
		responseJson =  "{ \"items\" : [" + strtran( alltrim(responseJson) , crlf(), ","+crlf() ) + "] }"
		? json_reformat( responseJson )
     else
        dim resp.error as c = cn.CallResult.Text
        ? json_generate(resp)
	 end if
else
    dim resp.error as c = cn.CallResult.Text
    ? json_generate(resp)
end if
%>

Now we can use the endpoint to look for a specific Record.

>curl "http://127.0.0.1:8081/service_endpoint.a5w?tablename=products&primarykey=2"
{
    "items": [
        {
            "ProductID": "2",
            "ProductName": "Chang",
            "SupplierID": "1",
            "CategoryID": "1",
            "QuantityPerUnit": "24 - 12 oz bottles",
            "UnitPrice": "19",
            "UnitsInStock": "17",
            "UnitsOnOrder": "40",
            "ReorderLevel": "25",
            "Discontinued": "F"
        }
    ]
}
%>