Web Connection
General guidelines for returning responses
Gravatar is a globally recognized avatar based on your email address. General guidelines for returning responses
  VFPJCOOK
  All
  Nov 9, 2023 @ 11:50am

I have a WWWC REST web service. I am in one of my endpoints (custom wwProcess function). I have gathered the data to return to the website that requested the data. I have read everything I can find but do not fully get some details about building my Response object. First, I would think there is something like a Response.lError that I would set True if an error was encountered and probably a Response.cErrorMessage that I would load with an error code or message. After that my question would be, wouldn't I just add my properties to the already existing Response object? This is what I have:

         Response.ContentType = "application/json"

         loInmateObject = CREATEOBJECT("EMPTY")
         ADDPROPERTY(loInmateObject,"cid",loposinmaterec.cid)
         ADDPROPERTY(loInmateObject,"cname",ALLTRIM(loposinmaterec.clast)+", "+ALLTRIM(loposinmaterec.cfirst)+" "+ALLTRIM(loposinmaterec.cmiddle))
         ADDPROPERTY(loInmateObject,"ddob",loposinmaterec.ddateofbirth)
         ADDPROPERTY(loInmateObject,"ybalance",server.oVFE_LPSO.yposinmatebal)
         ADDPROPERTY(loInmateObject,"yspendable",server.oVFE_LPSO.yposmaxpurch)
         ADDPROPERTY(loInmateObject,"cwebsessiontoken",lcwebsessiontoken)

         loMenuObject = CREATEOBJECT("EMPTY")
         ADDPROPERTY(loMenuObject,"menu","cursor:inmatemenucursor")

         ADDPROPERTY(Response,"LError",.f.)
         ADDPROPERTY(Response,"cErrorMessage","")
         ADDPROPERTY(Response,"InmateDetails",loInmateObject)
         ADDPROPERTY(Response,"InmateMenu",loMenuObject)

         RETURN loInmateObject

I know I need to make the properties camelCase, etc. Any guidance appreciated, John

Gravatar is a globally recognized avatar based on your email address. re: General guidelines for returning responses
  Rick Strahl
  VFPJCOOK
  Nov 9, 2023 @ 03:57pm

You don't use the Response object to return a result in a REST Service (well OK - you can but it's a special case if you override explicitly). You return a result object or value via the return value of the method. There are things you can set on the Response object, but it only relates to the headers, not the result content.

For example you can do:

Response.ContentType = "application/json"
Response.Status = "200 OK"

loResult = CREATEOBJECT("Empty")
ADDPROPERTY(loResult, "name", "Rick")

RETURN loResult

You can only return a single value as a result, but you can certainly build nested JSON objects:

loResult = CREATEOBJECT("Empty")
ADDPROPERTY(loResult, "name", "Rick")

loNested = CREATEOBJECT("EMPTY")
ADDPROPERTY(loNested,"StreetAddress","123 Nowhere Lane")

*** Add nested property to the top level object
ADDPROPERTY(loResult,"address",loNested)

SELECT * from Customers into CURSOR TQuery

*** Add a nested array (from the cursor) to the top level object
ADDPROPERTY(loResult,"cursor:TQuery")

RETURN loResult
Gravatar is a globally recognized avatar based on your email address. re: General guidelines for returning responses
  Rick Strahl
  VFPJCOOK
  Nov 9, 2023 @ 04:02pm

I think what you're thinking of perhaps is to use some sort of standard result structure that is in message format where the message has a few things:

  • Some sort of transaction or request id
  • A data member
  • A status member

The Json might look like this:

{
   "id": "x123456",
   "data": { 
        "name": "Rick",
        "address": "123 nowhere lane"
    },
    "status": {
       "isError": false,
       "errorMessage": null
    }
}

Every request then returns a structure like this, so every request can be checked for the status and you always know whether the request was successful or not.

You can use variations of this. Personally flatten the status members into the top level, but using status is more explicit.

+++ Rick ---

Gravatar is a globally recognized avatar based on your email address. re: General guidelines for returning responses
  VFPJCOOK
  Rick Strahl
  Nov 27, 2023 @ 12:52pm

Rick, I have my WWWC Server app for my REST service written with most of my endpoints coded and tested.

I need help with what seems to be the simplest thing. I coded my endpoints to accept query string values OR JSON. I tested using query string values but want to test using JSON.

So the call to: http://localhost/ITFBO/InmateCreateCommSale.ip?citf=LPSO&citfuserid=2314627&citfsessiontoken=26842D62912641A5

works and returns the expected JSON results.

My question: How do I do exactly the same except passing JSON? I purchased WebSurge. I see in the Web Connection documentation:

The Web Connection documentation show you using WebSurge to do this:

So, I am trying to use WebSurge to do the same thing. Where/How in websurge do I fill in the Request Content which would look something like the following:

{
"citf": "LPSO",
"citfuserid": "2314627",
"citfsessiontoken": "26842D62912641A5"
}

Thanks, John

Gravatar is a globally recognized avatar based on your email address. re: General guidelines for returning responses
  Rick Strahl
  VFPJCOOK
  Nov 27, 2023 @ 01:38pm

You have to selectively handle the input based on what you're being sent. Easiest is to check if you have a parameter passed in (you won't with query string most likely) or you can check Request.GetHttpVerb() == "POST"

FUNCTION RestCall(loParm)

* citf=LPSO&citfuserid=2314627&citfsessiontoken=26842D62912641A5
IF ISNULLOREMPTY(loParm)
   loParm = CREATEOBJECT("EMPTY")
   ADDPROPERTY(loParm, "citf", Request.QueryString("citf")
   ADDPROPERTY(loParm, "citfuserid", Request.QueryString("citfuserid")
   ADDPROPERTY(loParm, "citfsessiontoken", Request.QueryString("citfsessiontoken")
ENDIF

*** loParm now hold your parameters
loResult = DoWhatever(loParm)

RETURN loResult
ENDFUNC
Gravatar is a globally recognized avatar based on your email address. re: General guidelines for returning responses
  VFPJCOOK
  Rick Strahl
  Nov 29, 2023 @ 06:23am

Hi Rick, That is not what I was looking for. Simply put, I can use the browser to pass values to my endpoints (you call it the query string). I need a way to test my endpoints by sending JSON. I wrote a separate VFP program to do this:

DO wwhttp
DO wwjsonserializer

loProxy = CREATEOBJECT("wwJsonServiceClient")
IF NOT VARTYPE(loProxy)="O"
   loproxy=.NULL.
   RELEASE loproxy
   CLEAR TYPEAHEAD
   MESSAGEBOX("ITF could not create wwJsonServiceClient.",48,"ITF")
   this.setFocus()
   NODEFAULT
   RETURN
ENDIF

*** Create custom Http Object for Authentication
loHttp = loProxy.CreatewwHttp()

*** Now make customization to the HTTP object
loHttp.AddHeader("Content-Type","application/json")

loSer = CREATEOBJECT("wwJsonSerializer")

&& to send JSON
lcserviceurl="http://localhost/ITFBO/InmateCreateCommSale.ip"
loRequestfoxproobject = CREATEOBJECT("EMPTY")
ADDPROPERTY(loRequestfoxproobject, "citf", "LPSO")
ADDPROPERTY(loRequestfoxproobject, "citfuserid", "2314627")
ADDPROPERTY(loRequestfoxproobject, "citfsessiontoken", "26842D62912641A5")

loJSONResponse = loProxy.CallService(lcserviceurl,"loRequestfoxproobject","POST")

I am testing the sending of JSON. I am sending loRequestfoxproobject to my endpoint InmateCreateCommSale.

Here is the code from my wwProcess endpoint function:

*********************************************************************
FUNCTION InmateCreateCommSale(toJSON)
*********************************************************************

lcitf = toJSON.citf
lcitfuserid = toJSON.citfuserid
lcitfsessiontoken = toJSON.citfsessiontoken

I get a server error when the line lcitf = toJSON.citf executes. I have read every article and documentation that I can find. What am I missing? From my understanding toJSON should be a deserialized JSON object with 3 properties, citf, citfuserid and citfsessiontoken.

Thanks, John

Gravatar is a globally recognized avatar based on your email address. re: General guidelines for returning responses
  Rick Strahl
  VFPJCOOK
  Nov 29, 2023 @ 01:45pm

Why not use WebSurge, since you bought it a few days ago, for the request testing?

You can set up both types of URLs easily. Sending from VFP is a pain because you'll have to have two FoxPro instances running one for your server and one for your client.

+++ Rick ---

Gravatar is a globally recognized avatar based on your email address. re: General guidelines for returning responses
  VFPJCOOK
  Rick Strahl
  Nov 29, 2023 @ 11:17pm

Rick, Well, I am able to run two FoxPro instances so that part is not a problem and besides, this would provide me with an easy way to test the WWWC REST service anytime I have issues.

Having said that, I would be happy to use websurge. That is the main reason I purchased it. Problem is I do not know how or where to enter the JSON to setup a request. Look back at my earlier post in this thread. See the screen print that shows where you used websurge to do this. See the Request Content section. See where you entered firstName, lastName and Company. I simply cant figure out how/where you entered that in websurge. It may be really simple and you would think it would be really simple but not to me.

4 hours later: I was able to figure out how to enter the JSON into the Request Content in websurge. I may not be doing that correctly because I created the JSON in Notepad and then copied and pasted it from Notepad into the Request Content window in websurge. I ran the request and I am getting the same server error so I guess the question is still the same. Why does the line of code in my endpoint function "lcitf = toJSON.citf" cause an error?

Thanks, John

Gravatar is a globally recognized avatar based on your email address. re: General guidelines for returning responses
  Rick Strahl
  VFPJCOOK
  Nov 30, 2023 @ 02:22pm

Step into your code with the debugger to find out what's going on. No point guessing. You're probably referencing the wrong object?

+++ Rick ---

Gravatar is a globally recognized avatar based on your email address. re: General guidelines for returning responses
  VFPJCOOK
  Rick Strahl
  Dec 1, 2023 @ 05:37am

I have stepped thru the code and it works perfectly. Of course I am doing that in File Mode. The error only occurs when running the exe in COM Mode. Do you have some time today for a connection? If so please let me know and see if you can get me past this. Thanks, John

© 1996-2024