Is there an example project for the client of a web service?

Hello. I’ve been practicing with web services, and I almost have enough to start implementing it. I watched Paul’s tutorials on this and saw there were links for the example projects for 1) the web service, and 2) the client (EE iOS), but these were from 2015, so I couldn’t follow along completely. Then I found Javier’s blog post, which was more relevant for me (Web Services Part II: Xojo Web, at your service – Xojo Programming Blog)

This blog post shows how to return all of the data to a listbox and how to update a record. So far, I’ve gotten the ShowAll, Add, Update, and Delete. What I am needing help with is the web service returning the data for one specific record.

I found an updated example project in Communication > Internet > Web Services > EddiesWebService, which is obviously for the web service. If there is a project in the examples that is a companion to this project as the client, I think that would help me out because the web service example includes a function to GetCustomer (a single record), but I don’t know how it is called from the client side

I did get the process to work for the purposes, but I know it is not the most streamlined way of doing it. On the client, I am following Javier’s post to find a record, similar to how an Update or Delete would work

dim d As New Dictionary
d.Value("RegCodes") = txtCode.Text
dim item As New JSONItem
item.Value("newCode") = d

CodesSocket11.sendItem(item,"http://127.0.0.1:8080/FindCode")

Then on the web service side, the FindCode method looks like this

dim title As String = item.Value("RegCodes")

Dim sql As String = "SELECT * FROM registerCodesTEST WHERE RegCodes = ?"
Dim rs As RowSet = mDbRegister.SelectSQL(sql, title)

if rs.RowCount > 0 then
  theSearchedCode = rs.Column("RegCodes").StringValue
  CodeFound = True
else
  CodeFound = False
end if

In the HandleURL, I have it like this

Case "FindCode"
  dim data As String = Request.Body.DefineEncoding(encodings.UTF8)
  dim Input As JSONItem = New JSONItem(data)
  FindCode(Input.Value("newCode"))
  
  
  if CodeFound = true then
    dim output As JSONItem = DisplayCode 
    
    Response.Header("charset") = "utf-8"
    Response.MIMEType = "application/json"
    Response.Status = 200
    response.write( output.ToString ) // And send it back to the client that made the request, converting the JSON to a String in first place
  end if

I know this is not the best practice, but it was the only way I could figure out how to first find the record based on user input and if found, then return the result back to the client. I feel like on the client side, I should be able to send the request to the web service with the input data and then have that returned back to the client. Any suggestions? This is a new area for me

As I just helped another user with a similar situation, I’m going to drop in my 2 cents…

Make sure that your queries don’t run too long. If they do, use a callback mechanism where you make an initial query and the server immediately returns a 202 Accepted response with a url that the client should use to request the results. While the sql query is still going on, the client periodically calls the url to see if the data is ready and the server either returns a 200 OK with the data in the body or a 102 Processing to indicate that it’s still working on it. 204 No Content may also be used if no results were returned.

The reason I suggest these values is that they infer meaning, allowing the client to decide the status by simply looking at an integer.

More info can be found here

2 Likes

This is helpful Greg. Thank you.

So needing to do two separate calls from the client is a must? One to call to check for a record and a second to call to pull in the data back to the client? The example project made me think there could be one that does both. I was hoping to find the example project for the client that accompanies the example for the web service to see how the GetCustomer was done (a single call was made to find the single customer and also display the results back to the client). Figured that would prevent the need to make back to back calls when the server could be busy working on the first

Technically it could be a single call, but the trick is that without the use of threads, a long running query could lock up the server for all of the other clients. Using a thread to convert a recordset into a JSON string in the background while the client periodically polls to see if it’s done means that the server doesn’t lock up and the client can show a “please wait” banner if necessary.

You really should be thinking about working asynchronously when creating or communicating wit an API because you just don’t know what the network conditions are going to be like coming into or going out of the server or what other loads are going to be affecting performance. Doing the request in three pieces may seem like overkill now, but it gives you a lot of room to grow in the long run:

  1. Client Query Request GET => server 202 Accepted
  2. Client info request HEAD => server 102 Processing or 200 OK
  3. Repeat step 2 until response is 200
  4. Client GET request => server 200 with json payload

The whole point of the HEAD requests in the middle is that they are fast and take very little cpu cycles for the client and server to process. Other types of requests (like GET, POST and PUT) carry some overhead of having to look for and possibly process a payload.

Definitely giving me some things to think about. I hadn’t thought of a process possibly tying up things for other clients. Certainly something to consider. That was actually something on my mind as well

Thanks again for the tips!