Search code examples
restdelphiprestashopdelphi-xe8

delphi XE8 REST Interface PUT in prestashop


I'm trying to update a manufacturer in Prestashop through the REST interface. So far I've been able to GET the information, but when I try to PUT, I Always get an HTTP 500 error.

try
    Memo1.Text := '<prestashop><manufacturer><id><![CDATA[804]]></id><name><![CDATA[DisneyLand]]></name></manufacturer></prestashop>';

    RESTRequest1.Params.Clear;
    //authentication does not work with PUT, use token as suffix....
    RESTClient1.Authenticator := nil; //SimpleAuthenticator1;//
    //SimpleAuthenticator1.UserNameKey := 'ws_key';
    //SimpleAuthenticator1.UserName := 'HEREIGOESTHETOKEN';
    RESTRequest1.Resource := 'manufacturers';
    RESTRequest1.ResourceSuffix := '?ws_key=HEREIGOESTHETOKEN';
    RESTRequest1.Method := rmPut; //update
    RESTClient1.BaseURL := 'http://localhost/prestashop/api';
    RESTRequest1.Params.AddItem('id', '804' ,pkGETorPOST , [], ctTEXT_PLAIN);
    RESTRequest1.Params.AddItem('putXml', Memo1.Text,
                                pkGETorPOST , [], ctAPPLICATION_X_WWW_FORM_URLENCODED);

    RESTRequest1.Execute;

    Memo1.Lines.Clear;
    Memo1.Lines.Add(RESTResponse1.Content);
  except
    on E : Exception do
    begin
      Memo1.Lines.Clear;
      Memo1.Lines.Add('Exception class name = '+E.ClassName);
      Memo1.Lines.Add('Exception message = '+E.Message);
    end;
  end;

I've tried the other TRESTRequestParameterKind posibilities, but no avail.

Anyone tried this before?


Solution

  • UPDATE : After monitoring my network with Wireshark, i noticed that if I use the TSimpleauthenticater component anywhere before, the xml is always appended with the ws_key value, resulting in a 500 server error. This happens even if I clear all the SimpleAuthenticator settings and set the Clients authenticator to nil.

    I also had to set the content type to ctTEXT_XML iso ctAPPLICATION_X_WWW_FORM_URLENCODED when specifying th xml in the body.

    Following code works :

    procedure TForm1.BtnNewMfgClick(Sender: TObject);       //new
    var
      aNode, aCNode, aCCNode : IXMLNode;
      i,j : integer;
      aXml : string;
    begin
      RESTRequest1.Params.Clear;
      RESTClient1.Authenticator := nil;
      SimpleAuthenticator1.UserNameKey := '';
      SimpleAuthenticator1.UserName := '';
    
      RESTClient1.BaseURL := 'http://localhost/prestashop/api';
      RESTRequest1.Resource := 'manufacturers';
      RESTRequest1.ResourceSuffix := '?schema=blank&ws_key=HEREGOESMYKEY';
      RESTRequest1.Method := rmGet;
      RESTRequest1.Execute;
      aXml := RESTResponse1.Content;
      XMLDocument1.LoadFromXML(aXml);
    
      aNode := XMLDocument1.ChildNodes.FindNode('prestashop');
      if assigned(aNode)
      then begin
        for i := 0 to aNode.ChildNodes.Count-1 do
        begin
          aCNode := aNode.ChildNodes.Get(i);
          for j := 0 to aCNode.ChildNodes.Count-1 do
          begin
            aCCNode := aCNode.ChildNodes.Get(j);
            if aCCNode.NodeName = 'id' then aCCNode.NodeValue := ''; //cannot pass id at create
            if aCCNode.NodeName = 'active' then aCCNode.NodeValue := '1' ;
            if aCCNode.NodeName = 'name' then aCCNode.NodeValue := 'New Brand';
          end;
        end;
      end;
    
      XmlDocument1.SaveToXML(aXml);
    
      RESTRequest1.ClearBody;
      RESTRequest1.AddBody(aXml, ctTEXT_XML);
      RESTRequest1.ResourceSuffix := '?ws_key=HEREGOESMYKEY';
    
      RESTRequest1.Method := rmPost;
      RESTRequest1.Execute;
    
      //new id is returned in the contents XML id tag
      Memo1.Lines.Clear;
      Memo1.Lines.Add(RESTResponse1.Content);
    end;
    

    Although this works in test, I'm investigating it further, because in production it has to work over https:// so the key is not exposed...

    In short : Simpleauthenticator only works for GET and DELETE. Once used, PUT and POST will never work.