REST parameter strangeness

Hi again, back with the REST stuff…

I’m having a weird issue with a specific function/endpoint.
I have these two functions defined:

    [ROServiceMethod]
    [ROCustom('HttpApiPath','customer')]
    [ROCustom('HttpApiMethod','POST')]
    procedure AddCustomer(customer : TCustomer);

    [ROServiceMethod]
    [ROCustom('HttpApiPath','customer/{accountref}')]
    [ROCustom('HttpApiMethod','PUT')]
    procedure UpdateCustomer(accountref : string; customer : TCustomer);

The AddCustomer function works fine. Using Postman, I can supply the properties of the TCustomer class in my body and this passes through to the function perfectly.

With the UpdateCustomer function however, things get weird. It takes the same TCustomer class so I supply the exact same body in Postman, the only difference is that I’m also providing an account reference parameter in the URL itself too.

When I call UpdateCustomer, the accountref parameter is passed through but the TCustomer object is empty and contains none of the values from the body in my original call.

Clearly I’m doing something wrong when combining a URL parameter with a body parameter but can’t work out exactly what.

Hi,

it you replace PUT with POST, will it fix this case?

Aha, yes it does!

Any idea why PUT wouldn’t work?

From what I’ve read and understood about REST conventions, PUT is more appropriate when updating rather than creating.

Hi,

can you retest this case with CURL as client-side program, pls?

How do I do that?

something like

curl -v -X "POST" "http://localhost:8099/api/login/login" -H "accept: application/json" -H "Content-Type: application/json" -d "{\"NewParam\": \"a\", \"NewParam1\": \"a\"}"

Nope, CURL shows the same - POST works, PUT doesn’t.

Hi,

Can you create a simple testcase that reproduces this case, pls?

You can drop it to support@ for keeping privacy.

btw, what http server (indy, synapse, socket, etc) you are using?

I’ll see if I can rig something up.

Using the TROHTTPServer

Ok have reproduced it with the attached sample.
This works if you change the method to a POST but not when it’s a PUT.

RESTSample.rar (108.9 KB)

Was using this CURL to call it:

curl -X "POST" --location "http://localhost:8099/api/customer/CUST001" --header "Content-Type: application/json" --data-raw "{  \"customer\": {\"CompanyName\": \"Company\", \"Address1\": \"ADD1\", \"Address2\": \"ADD2\", \"Address3\": \"ADD3\", }}"

Logged as bugs://D19447.

Hi,

quick temporary workaround:

  • update uROAsyncHttpServer.pas as
procedure TROAsyncContext.cbHeaderLine(aSender: TROAsyncSocket);
..
  else begin
    if (fRequest.Method = 'POST') or
       (fRequest.Method = 'PUT') or
       (fRequest.Method = 'PATCH') then begin  // changed

Thanks

bugs://D19447 was closed as fixed.

1 Like