delphimvcframework
delphimvcframework copied to clipboard
Issue with Endpoints
Hi,
I face a problem with Endpoints when no parameters are passed :
I have
[MVCDoc('Get a customer')] [MVCPath('/v1/customer/($id)')] [MVCHTTPMethod([httpGET])] [MVCRequiresRole('admin;standard;read', MVCRoleEval.reOR)] Procedure Get_Client(id: String);
And
[MVCDoc('Returns a list of customer Addresses')] [MVCPath('/v1/customer/addresses')] [MVCHTTPMethod([httpGET])] [MVCRequiresRole('admin;standard;read', MVCRoleEval.reOR)] Procedure Get_Client_Adresses;
When I call
curl -X GET "http://localhost:8080/api/v1/customer/attached_files" -H "accept: application/json"
Get_Client(id: String); is called instead of Get_Client_Adresses;
If I change to [MVCPath('/v1/customer_addresses')] it's ok, but I would like to keep Rest compliance as possible. Best regards
Armindo
Just declare MVCPath('/v1/customer_addresses') before the other. The router path resolution is from the top of the class declaration to the bottom.
Thanks Daniele, will try like that !
Yep it works like that. Thanks again.
faq
Hi Daniele, I face a similar problem and this time I don't find a workaround I have a Controler for Customer and one for Customer's Contacts. (So 2 delphi units, more easy to manage).
For the customers I have something like this in its controler
Type
[MVCDoc('CUSTOMERS')]
[MVCPath('/api')]
TControlerClient = Class(TMVCController)
Protected
Procedure OnBeforeAction(Context: TWebContext; Const AActionName: String; Var Handled: Boolean); Override;
Procedure OnAfterAction(Context: TWebContext; Const AActionName: String); Override;
Public
[MVCPath('/v1/customers')]
[MVCHTTPMethod([httpGET])]
[MVCSwagSummary('customer', 'Returns a list of customers')]
[MVCSwagParam(plQuery, 'id', 'ID of a customer', ptString, False)]
[MVCSwagParam(plQuery, 'privateId', 'Private ID Mode', ptBoolean, True, 'false')]
[MVCSwagParam(plQuery, 'limit', 'Maximum number of rows returned', ptInteger, False)]
[MVCSwagParam(plQuery, 'offset', 'Rows returned start from this offset', ptInteger, False)]
[MVCSwagParam(plQuery, 'sort', 'Sorting Field', ptString, False)]
[MVCSwagParam(plQuery, 'order', 'Sort direction (ASC or DESC)', ptString, False, '', 'ASC;DESC')]
[MVCSwagParam(plQuery, 'where', 'WHERE clause', ptString, False)]
[MVCSwagResponses(200, 'Sucess', TCustomer_Response, true)]
[MVCSwagResponses(401, 'Requires Authentication')]
[MVCSwagResponses(403, 'Authorization Forbidden - Insufficient rights check your role')]
[MVCSwagResponses(500, 'Internal Server Error')]
[MVCRequiresRole('admin;standard;read', MVCRoleEval.reOR)]
Procedure Get_Clients;
//Customer mode unitaire
[MVCDoc('Get a customer')]
[MVCPath('/v1/customer/($id)')]
[MVCHTTPMethod([httpGET])]
[MVCSwagSummary('customer', 'Get a specific customer')]
[MVCSwagParam(plPath, 'id', 'Customer id', ptString)]
[MVCSwagParam(plQuery, 'privateId', 'Private ID Mode', ptBoolean, True, 'false')]
[MVCSwagResponses(200, 'Sucess', TCustomer)]
[MVCSwagResponses(401, 'Requires Authentication')]
[MVCSwagResponses(403, 'Authorization Forbidden - Insufficient rights check your role')]
[MVCSwagResponses(500, 'Internal Server Error')]
[MVCRequiresRole('admin;standard;read', MVCRoleEval.reOR)]
Procedure Get_Client(id: String);
For the Customer Contact I have
Type
[MVCDoc('CUSTOMER CONTACTS')]
[MVCPath('/api')]
TControlerCustomerContact = Class(TMVCController)
Protected
Procedure OnBeforeAction(Context: TWebContext; Const AActionName: String; Var Handled: Boolean); Override;
Procedure OnAfterAction(Context: TWebContext; Const AActionName: String); Override;
Public
[MVCPath('/v1/customer/contacts')]
[MVCHTTPMethod([httpGET])]
[MVCSwagSummary('customer contact', 'Returns a list of contacts')]
[MVCSwagParam(plQuery, 'id', 'ID of a contact', ptString, False)]
[MVCSwagParam(plQuery, 'privateId', 'Private ID Mode', ptBoolean, True, 'false')]
[MVCSwagParam(plQuery, 'limit', 'Maximum number of rows returned', ptInteger, False)]
[MVCSwagParam(plQuery, 'offset', 'Rows returned start from this offset', ptInteger, False)]
[MVCSwagParam(plQuery, 'sort', 'Sorting Field', ptString, False)]
[MVCSwagParam(plQuery, 'order', 'Sort direction (ASC or DESC)', ptString, False, '', 'ASC;DESC')]
[MVCSwagParam(plQuery, 'where', 'WHERE clause', ptString, False)]
[MVCSwagResponses(200, 'Sucess', TCustomerContact_Response, true)]
[MVCSwagResponses(401, 'Requires Authentication')]
[MVCSwagResponses(403, 'Authorization Forbidden - Insufficient rights check your role')]
[MVCSwagResponses(500, 'Internal Server Error')]
[MVCRequiresRole('admin;standard;read', MVCRoleEval.reOR)]
Procedure Get_Customer_Contacts;
Since the contact is a customer contact, it's better to use the Rest logic using /v1/customer/contacts
But here calling http://localhost:8081/api/v1/customer/contacts?privateId=false give this behaviour
URL : /api/v1/customer/contacts Query String : privateId=false Body :
03/08/2020 15:21:36: [Before Action] Controller : Controller.Client.TControlerClient Action : Get_Client
The strange thing is that you compile one time it will work fine, another time it will use the wrong controller, without modifying any code.
I have try to register first the contact contoller like this
TControllersRegister.Instance.RegisterController(TControlerCustomerContact, 'myAPI');
TControllersRegister.Instance.RegisterController(TControlerClient, 'myAPI');
no more luck. Any idea or tips ?
Best regards Armindo
Any news on this?