[REST API] Questions and improvements

by bohte, Thursday, April 27, 2023, 06:22 (365 days ago)

Hello!

My name is Bohdan and currently I'm working on making application communicate with SQL-Ledger by REST API using HTTP requests with JSON payloads.
During my initial attempts to set up SQL-Ledger with REST API (based on branch "326_rest_api" from "ledger123/runmyaccounts" repository), i've managed to address SQL-Ledger via HTTP.
After some testing and investigation, i've gathered some info/questions that I'd like to discuss.
Please, see listing below:

1) Authentication:

a. api_key must not be constant in case of public access.
(currently api_key is stored as constant in ‘defaults’ table)
* not RMA case
b. api_key must be passed to server as header.
(now passed as header in case of POST and as query parameter in case of GET)

2) Error handling:

a. Error responses must be of the same content-type as usual responses:
If client is expecting to get JSON, but error occurred during processing, JSON with error details should be returned.
b. HTTP request status must always represent actual result (regardless of problem was on client side - 4XX code or server side 5XX code):

[image]

3) Response payload:

a. When requesting an entity OR list of entities, but they do not exist – empty response with “404 Not Found” code must be returned.
(screenshot - get transaction by id case; the same applies to get transaction list where empty array with 200 OK is returned in current version):

[image]

b. Response payload of POST, PUT, PATCH requests must be the same as for GET:
(non-bulk case described)
GET by id – returns entity as JSON
POST / PUT / PATCH – creates / replaces / updates entity and returns it as JSON
Code for
GET – 200 OK
POST – 200 OK / 201 Created
PUT – 200 OK / 201 Created
PATCH – 200 OK
In current version POST gl transactions responses with:
{ “code”: 300, message: “7649” } 200 OK

4)Ambiguity:

Entities JSON representations must not create any ambiguity when it comes to understanding of attributes. Currently POST of gl transaction requires both “accno” and “chart_id” to be sent despite to the fact that they are pointing to the same chart of accounts. The same applies to such attribute pairs as “department_id” + “department”, “project_id” + “projectnumber”.
Best practice would be to keep only identifier as required field for POST request, BUT in case of need to render names on client side – they can be wrapped as a ObjectRef’s:
{
…,
“chart”: {
“chart_id”: number (required)
“accno”: string (optional)
“description”: string (optional)

},

}

Also, would be great to have descriptors for request/response payloads to clarify them for API consumers.
Descriptors should explain
a. JSON example
b. Value types for attributes
c. Mandatory/non-mandatory attributes

5) Actual issues OR lack of understanding:

During testing of API behavior (mostly POST gl transaction) I found out that
a. ‘department’, ‘project’ and ‘currency’ are not set to new transaction even if they were sent
b. ‘exchange rate’ is always set to 1 even if default currency is used

6) improvedgl.pl:

a. has simplified request payload, has better response (tested on https://ledgeri.mnapk.com/login.pl)
b. Is it possible to use it instead?

*** end of listing

Thanks in advance for your attention!

[REST API] Questions and improvements

by Armaghan Saqib, Tuesday, May 02, 2023, 01:17 (360 days ago) @ bohte

Hi Bohdan,

Nice to meet you.

Yes you are right regarding error handling, not found status code on empty result as well as other standard status codes, json response for error messages. Fixes for these will be done this week hopefully and I shall update.

Regarding Authentication, I am not familiar with the architecture of new version you are working on. Can you please explain it a bit to me? Is it being built with server side rendering (node, express) or client side rendering (vue, react, angular) etc? Most importantly how user's session is created and maintained in the application. This can help us decide on authentication. If you have your own idea of key rotation, please share that too.

Regarding your point 5 (actual issue or lack of understanding), I investigate and fix this too.

Regarding your point 4 (ambiguity), yes, you are right. But what we are doing is not developing our own API functionality from scratch. Rather we are using SQL-Ledger's existing code for all the work from the SL/*.pm folder.

This method requires least testing effort as this code is already tested. So we need to send data to the API in the format required by SQL-Ledger which you can always see by looking at the source of respective screens form fields in SQL-Ledger. So this code many times will include both department_id as well as department--department_id.

Similarly data returned by our API is in the format which is returned by SL/*.pm modules search procedures.

Ideally we should build a brand new API for clarify and efficiency reasons but that will require a lot of development time as well as testing which probably is not feasible for this project right now due to tight deadlines.

Regarding LedgerImproved, I have asked, Hashim, who is developing it to respond with details about that work including Authentication and API.

[REST API] Questions and improvements

by Hashim, Tuesday, May 02, 2023, 09:14 (360 days ago) @ bohte

Hi Bohdan,

My codebase is completely different Armaghan's code. I went through sql-ledger api in SL/.pm and noticed a lot of things to be complicated and difficult which needed to be improved. Since it is more error prone to make changes in the SL/.pm files and requires a lot more testing time, I have decided to build my own API from scratch.

I am defining and building my API using OpenAPI specifications and have hosted it on swagger. You can see the work done so far here: https://app.swaggerhub.com/apis/HASHIM1SAQIB/LedgerINN/1.0.0. Please note this is still in it's initial stages and a lot of refinement is required. I'm building the basic routes required first and once done, will work on better validation and security.

The API uses real arrays for data transfer rather than the SL's api which uses parts_id_1, parts_id_2, parts_id_3 kind of elements for array.

I've also made LedgerI to be a standalone app built with the Vue framework. You can have a look at the stand alone application too at:
app.ledgerinn.com/ / email: [email protected] pw: HelloDemo123!@#
The app is also still a work in progress.

I will keep updating my swagger link with my progress. Since I am learning SQL-Ledger and building at the same time, the development is not very fast paced.

[REST API] Questions and improvements

by bohte, Thursday, May 04, 2023, 06:27 (358 days ago) @ bohte

Hello Hashim!

Thanks a lot for your response.

Now I see, improvedgl.pl is part of something new and big, which will probably take time to be developed and tested. I do think that new UI will bring freshness to SQL-Ledger views and APIs developed according to OpenAPI specification will one day replace older ones and make SQL-Ledger more convinient.

Good luck with your project!

P.S. For RMA side - new APIs usage would be great idea, but rather in future, than now.

[REST API] Questions and improvements

by bohte, Thursday, May 04, 2023, 06:54 (358 days ago) @ bohte

Hello Armaghan!

Thanks a lot for your response and intension to help with all points described in thread-root.

In reply to your answer there are two things from my side:

In regard to "ambiguity" topic, I got the point and cannot argue with that, it makes sense. Therefore anything related to that we will discuss and handle on our side.

In regard to "authentication" topic, generally, as You mentioned in your reply, key rotation is the best solution in this case. I would suggest to change constant api_key to JWT (JSON Web Token) which would be:
1) Generated on session instantiation (login)
2) Kept somewhere in DB or any other persistance and easy-accessible place
3) Invalidated along with session
4) * also topic of refresh-token may come in handy

Speaking of best practices - please, check out this link telling about authentication standard: https://auth0.com/intro-to-iam/what-is-oauth-2 (other topics on this resource may be useful).
To apply OAuth approach to your application You can either develop it by yourself or use third-party solution.

Although security is important topic, please, consider that as RMA - we are going to use IP whitelist protection strategy which works fine for us. Therefore no pressure from us in regard to authentication topic.

Looking forward to hear about any changes done to SQL-Ledger APIs in regard to points from root-thread.

Good luck and best regards!

[REST API] Questions and improvements

by Armaghan Saqib, Monday, May 08, 2023, 05:14 (354 days ago) @ bohte

Hi,

Since authentication is something not related to SQL-Ledger, please feel free to define its specification and development on your side while I shall take care of all the sql-ledger functionality in the API.

In Hashim's project, when his user logins, a session id is generated and stored in a database table. It is also returned by api and stored by the front end application. (written in vue). This session id is then passed in each api call in the header part and . So this way, this key/session id is always unique for every session. You can write your authentication on this line or using JWT whatever you feel like necessary.

Regards

RSS Feed of thread