Hi,
I’m trying to implement a REST API on existing custom Delphi server.
I need to accept some data via the body in the form of a JSON object. I have got as far as the following code:
TLoginRequest = class(TROComplexType)
private
fpassword: ROUTF8String;
fusername: ROUTF8String; // this will be the body of the DoSessionLogin
public
{$IFDEF RO_RTTI_Support} [ROSerializeAsUTF8String] {$ENDIF}
property username : ROUTF8String read fusername write fuserName;
{$IFDEF RO_RTTI_Support} [ROSerializeAsUTF8String] {$ENDIF}
property password : ROUTF8String read fpassword write fpassword;
end;
and then the service declares the following:
[ROService]
TLoginService = class(TSimpleLoginService)
public
[ROServiceMethod]
[ROCustom('HttpApiPath','sessions/')]
[ROCustom('HttpApiMethod','POST')]
[ROCustom('HttpApiResult', '201')] // 201 = created
function createSession(loginRequest : TLoginRequest): Userinfo;
// ...
end;
The problems I have are:
The api at localhost:8099/api shows the TLoginRequest, but doesn’t show any attributes for the TLoginRequest in the definitions object.
,
TLoginRequest: {
type: “object”,
properties: { }
},
When I use postman to call the method with the JSON as the body of the request, the createSession method itself receives a TLoginRequest object with empty params.
If the createSession method fails, I raise a 403 as follows:
EROHttpApiException.Create(HTTP_403_code, HTTP_403_status);
This code is called, but the method still returns 201 to Postman.
Thanks
Stuart
EvgenyK
(Evgeny Karpov)
March 5, 2019, 12:35pm
2
Hi,
specify username
& password
as published properties instead of public ones
check that you have raise
here like
raise EROHttpApiException.Create(HTTP_403_code, HTTP_403_status);
Hi Evgeny,
Thanks for the reply.
The properties are now showing up in the API description & the exception is now being raised okay.
I still have the problem of getting the JSON data from postman into the createSession. When I debug the server, the loginRequest.username and loginRequest.password are both empty strings.
This is my PostMan setup:
Thanks
EvgenyK
(Evgeny Karpov)
March 5, 2019, 1:47pm
4
try to use CURL:
>curl -X POST "http://localhost:8099/MyPath/sessions/" -H "accept: application/json" -H "content-type: application/json" -d "{ \"loginRequest\": { \"password\": \"password\", \"username\": \"user\" }}"
Forbidden
>curl -X POST "http://localhost:8099/MyPath/sessions/" -H "accept: application/json" -H "content-type: application/json" -d "{ \"loginRequest\": { \"password\": \"user\", \"username\": \"user\" }}"
"logged"
this is for
function TSampleService.createSession(loginRequest: TLoginRequest): ROUTF8String;
begin
if loginRequest.username <> loginRequest.password then raise EROHttpApiException.Create(HTTP_403_code, HTTP_403_status);
result := 'logged';
end;
Hi Evgeny,
I didn’t use curl, but looking at your command line, I changed my PostMan data to:
{
"loginRequest": {
"username": "user2",
"password": "letmein98"
}
}
(added in the parent “loginRequest” attribute which wasn’t there before. The username and password properties are coming through now - thanks.
ONE more question please - what do I need to do in my HTTP API methods to ensure the SessionID is valid? I have RequiresSession to true on my services.
Do I need to pass SessionID as the first param to all methods?
Thanks in advance
Stuart
EvgenyK
(Evgeny Karpov)
March 5, 2019, 2:17pm
6
stuartclennett:
I didn’t use curl
I’m using swagger-editor and it generated curl
requests for me.
it can be usable for you too.
as for SessionID
: it was returned as Access-Token
header
< HTTP/1.1 200 OK
< Connection: close
< Content-Type: application/json; charset=utf-8
< Content-Length: 0
< Date: Tue, 05 Mar 2019 14:10:09 GMT
< Accept-Encoding: gzip, identity
< Access-Token: {7FCBCC75-846B-41F0-BDD7-68052C4AEDE2}
for using this token, you should pass it as http header in your request:
>curl -verbose -X POST "http://localhost:8099/api/test/Sum" -H "accept: application/json" -H "Access-Token: {7FCBCC75-846B-41F0-BDD7-68052C4AEDE2}" -H "content-type: application/json" -d "{ \"A\": 1, \"B\": 2}"
Note: Unnecessary use of -X or --request, POST is already inferred.
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8099 (#0)
> POST /api/test/Sum HTTP/1.1
> Host: localhost:8099
> User-Agent: curl/7.56.0
> Referer: rbose
> accept: application/json
> Access-Token: {7FCBCC75-846B-41F0-BDD7-68052C4AEDE2}
> content-type: application/json
> Content-Length: 19
* upload completely sent off: 19 out of 19 bytes
< HTTP/1.1 200 OK
< Connection: close
< Content-Type: application/json; charset=utf-8
< Content-Length: 1
< Date: Tue, 05 Mar 2019 14:13:51 GMT
< Accept-Encoding: gzip, identity
< Access-Token: {7FCBCC75-846B-41F0-BDD7-68052C4AEDE2}
3
* Closing connection 0
Hi Evgeny,
Very useful information - thanks very much.
I will try curl, I promise
Thanks