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 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"
}
]
}
%>