176
Views
12
Comments
Solved
Expose customized get - rest api
Question

Hello everyone,

I understand the basics of exposing a rest api just with output, where you do an aggregate on the entity and then assign the output of the aggregate to the output parameter.

Unfortunately thats the only think i find while searching about the  expose topic.

But in the use case im developing (academic project)  i need to pass a product code that then output the plans and coverages of that product code, and i am trying to understand out how to do that.

My db have a product group, product, plan,coverage and the m-m plancoverage entity, two static entities as well.

My rough idea is that i will have to do  two or more aggregates, filter the aggregate by that code and then probably do a for each, list append and assign along the way. I want to use a structure instead of the entities directly to follow best practices.

What i want to achieve looks quite more advanced than the info i find in tutorials and guides about exposing a rest api.

Any input is greatly appreciated. 

Thanks

2020-09-15 13-07-23
Kilian Hekhuis
 
MVP
Solution

But in this case, it's still 1:n given you want a per-plan view of the data. As for aux local vars, you could use one for plan, but for coverage you don't need one, as in every iteration you will add a coverage, and you can use mapping in the ListAppend (using the Current of the aggregate output). Don't forget to ListClear the coverages list when starting a new plan though.

Alternatively, you could ListAppend a Plan if it's the first of the list (CurrentRowNumber is 0) or as soon as you find a new one (i.e. Aggregate.List[Aggregate.CurrentRowNumber - 1].Plan <> Aggregate.List.Current.Plan), and then ListAppend the coverages by indexing: PlanList[PlanList.Length - 1].CoverageList. That saves you a local variable and a ListClear. The code may be less legible though.

2024-09-19 13-52-30
Kavinilammurugu (Kavin)

Hi Sergio , 
You are Correct, we have to customize the output. 

As you mentioned, the best way is to first prepare the output based on a Structure. 


The consumer will automatically receive the data in JSON format.


2020-09-15 13-07-23
Kilian Hekhuis
 
MVP

Hi Sergio,

No doubt this is a bit more complex than the examples show, but the complexity doesn't lie in the REST exposure, just in gathering the data.

I'd first design, by creating the structures, a suitable output for the REST method. Then think of how to gather the data. If at all possible, use a single query for best performance. Querying in a For Each means hitting the data base for each record, which can be quite slow if you have a lot of records. Of course, when having a 1:n relationship, the output of the query will contain duplicate records for the parent entity, so you'll have to manage that in your For Each. That has, again, nothing specifically to do with REST, but it is a common pattern when exposing a REST API.

2021-08-11 11-46-20
Mubashar

First, you must write a perfect query that gives you the desired results based on your Product Code.
You can use aggregate or SQL queries to filter your records. Then, the basic knowledge about exposes API is enough. 
I would suggest writing a server action with the required input/output parameters and adding your logic inside. Then Run tests as many as possible via unit test.

2022-02-08 09-40-14
Chandrashekhar Mankar

the best way would be to think of what you want in your output of GET method of the API and define the structure accordingly, I know it's bit sophisticated , but this would be a better way to do it.



2022-12-29 18-41-24
Sérgio Pinto

Hello friends,

Thank you very much for all your insight, which was valuable for sure!

@Kilian Hekhuis Yes you´re correct, the complexity lies on how to get the data correctly using one or more aggregates from the database, i was thinking more clearly and i don´t really need an input parameter, just the output. 

The requisite is to output the list of plans and related coverages on the database.

Maybe i can do this just with one aggregate and joining the two tables, i guess.

In attach i send the screenshot of the API, and the output parameter points to the structure layout i need to output.

Good idea Mubashar, for the possibility to testing it out using a server action.


2020-09-15 13-07-23
Kilian Hekhuis
 
MVP

Yeah, this seems like a straightforward 1:n relationship, with multiple coverages per plan. In that case, I'd definitely use a single query, and have some logic that determines when to add a new plan to your output list (hint: either when it's the last one of the query output list, or when the next one is different from the current).

2022-12-29 18-41-24
Sérgio Pinto

In my case the plan and coverage entities have a many to many relationship, because a plan can have many coverages and a coverage can be part of many plans.

The part that i am having most trouble is that i will need to use some auxiliary local variables (plan and coverage probably) on the method, after the for each i will need to assign the plan, then get the coverages for that plan, assign them to the coverage variable, then list append all to the list and element, and so on. Probably something like that, of course there are more than one way to achieve the same goal.

Do you have any screenshot of a case like this that i can take a look? Maybe actually some ready made apps of outsystems might have this logic in place for me to dig some more.

Thanks

2020-09-15 13-07-23
Kilian Hekhuis
 
MVP
Solution

But in this case, it's still 1:n given you want a per-plan view of the data. As for aux local vars, you could use one for plan, but for coverage you don't need one, as in every iteration you will add a coverage, and you can use mapping in the ListAppend (using the Current of the aggregate output). Don't forget to ListClear the coverages list when starting a new plan though.

Alternatively, you could ListAppend a Plan if it's the first of the list (CurrentRowNumber is 0) or as soon as you find a new one (i.e. Aggregate.List[Aggregate.CurrentRowNumber - 1].Plan <> Aggregate.List.Current.Plan), and then ListAppend the coverages by indexing: PlanList[PlanList.Length - 1].CoverageList. That saves you a local variable and a ListClear. The code may be less legible though.

2022-12-29 18-41-24
Sérgio Pinto

After some trial and error i was able to make it work and list the plans and respective coverages sucessfully. I ended up creating a coverage variable too and that way the mapping of the coverages worked. 

Somehow just with plan variable i was not being able to map the coverages correctly, but now that it works i might review the logic once more to try to eliminate that coverage variable.

Have a nice day!

2020-09-15 13-07-23
Kilian Hekhuis
 
MVP

Hi Sergio,

Good to know you got it working. If any of my previous posts helped you fixing it, I'd appreciate you marking it as Solution. Thanks!

2022-12-29 18-41-24
Sérgio Pinto

Thanks for your insight Kilian, you gave me some valuable info that i was not taking into account. Although i didn´t need to use everything, the API is in a very simple form, no validations or error messages yet, but it´s always good to hear feedback from experienced outsystems developers. 

Cheers

2020-09-15 13-07-23
Kilian Hekhuis
 
MVP
Community GuidelinesBe kind and respectful, give credit to the original source of content, and search for duplicates before posting.