Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
nitinksh1
Participant

Introduction


In the previous blog, we have discussed about the URI calls which do not require any custom implementation. In this blog, we will go through the URI's which do require custom implementation.

Steps


We can divide OData URI to 2 parts:

  1. Do Not Need Custom Implementation (Implementing All OData Query/URI Options – Part 1)


    1. $select

    2. $count

    3. $expand

    4. $format

    5. $links

    6. $value



  2. Need Custom Implementation (This Blog)

    1. $orderby

    2. $top

    3. $skip

    4. $filter

    5. $inlinecount

    6. $skiptoken




 

Implementation


1. $orderby: The $orderby option is used to specify a sort order for the results of a query. It is used in the URL of an OData service to indicate how the results should be sorted.

The syntax for the $orderby option is as follows: $orderby=propertyName [asc|desc], where propertyName is the name of the property by which the results should be sorted, and "asc" or "desc" is used to specify the sort order (ascending or descending, respectively).

For example, if we want to retrieve a list of customers and sort them by last name in descending order, the URL would look like this:
http://<host>/sap/opu/odata/sap/<service>/Customers?$orderby=LastName desc

It is also possible to sort by multiple properties using the $orderby option, by separating each property with a comma.
http://<host>/sap/opu/odata/sap/<service>/Customers?$orderby=LastName desc, FirstName asc

 

The code the $orderby can be written as:
  METHOD ekkoset_get_entityset.

*- To get data from DB
SELECT * FROM ekko INTO TABLE @DATA(lt_ekko) UP TO 10 ROWS.

*- Check the $orderby in the Odata Query
READ TABLE it_order INTO DATA(ls_order) INDEX 1.
IF sy-subrc IS INITIAL.
IF ls_order-order = 'desc'.
SORT lt_ekko BY (ls_order-property) DESCENDING.
ELSE.
SORT lt_ekko BY (ls_order-property) ASCENDING.
ENDIF.
ENDIF.

*- Check the size of the table for $inlinecount
IF io_tech_request_context->has_inlinecount( ) = abap_true.
DESCRIBE TABLE lt_ekko LINES DATA(lv_size).
es_response_context-inlinecount = lv_size.
ENDIF.

MOVE-CORRESPONDING lt_ekko TO et_entityset.

ENDMETHOD.

 

Below is the output:



1. $orderby.jpg


Another better way to use the $orderby can be the standard way of using it, displayed below:
*- Check the $orderby in the Odata Query
/iwbep/cl_mgw_data_util=>orderby(
EXPORTING
it_order = it_order " the sorting order
CHANGING
ct_data = lt_ekko
).

 

2. $top: The $top option is used to specify the maximum number of results that should be returned in a query. It is used in the URL of an OData service to indicate how many results should be returned. The syntax for the $top option is as follows: $top=n, where n is an integer indicating the number of results that should be returned.

For example, if we want to retrieve the top 10 customers, the URL would look like this:
http://<host>/sap/opu/odata/sap/<service>/Customers?$top=10

The $top option can be used in combination with other options such as $filter, $select and $orderby to further refine the results of a query.
http://<host>/sap/opu/odata/sap/<service>/Customers?$filter=Country eq 'US'&$top=5&$orderby=LastName desc

It's important to note that the $top option is used to limit the number of records returned in one response and not to restrict the total number of records returned by the OData service.

 
  METHOD ekkoset_get_entityset.

*- To get data from DB
SELECT * FROM ekko INTO TABLE @DATA(lt_ekko) UP TO 10 ROWS.

*- Check the $orderby in the Odata Query
/iwbep/cl_mgw_data_util=>orderby(
EXPORTING
it_order = it_order " the sorting order
CHANGING
ct_data = lt_ekko
).

*- For paging i.e. $top and $skip
/iwbep/cl_mgw_data_util=>paging(
EXPORTING
is_paging = is_paging " paging structure
CHANGING
ct_data = lt_ekko
).

*- Check the size of the table for $inlinecount
IF io_tech_request_context->has_inlinecount( ) = abap_true.
DESCRIBE TABLE lt_ekko LINES DATA(lv_size).
es_response_context-inlinecount = lv_size.
ENDIF.

MOVE-CORRESPONDING lt_ekko TO et_entityset.

ENDMETHOD.

We can use it as below:


2. $top.jpg


3. $skip: The $skip option is used to specify the number of results that should be skipped before returning the results in a query. It is used in the URL of an OData service to indicate how many results should be skipped. The syntax for the $skip option is as follows: $skip=n, where n is an integer indicating the number of results that should be skipped.

For example, if we want to retrieve all customers but skip the first 10, the URL would look like this:
http://<host>/sap/opu/odata/sap/<service>/Customers?$skip=10

The $skip option can be used in combination with other options such as $top, $filter, $select, and $orderby to further refine the results of a query.
http://<host>/sap/opu/odata/sap/<service>/Customers?$filter=Country eq 'US'&$skip=5&$top=5&$orderby=LastName desc

It's important to note that the $skip option is used to skip the records from the beginning of the result set, so it is typically used in combination with the $top option to retrieve a specific page of results.

Same code of paging(used in 3. $top). The below snippet is showing the second 2nd record as it is fetching the 1st record after skipping 1st one.


3. $skip.jpg


 

4. $filter: The $filter option is used to specify filter criteria for the results of a query. It is used in the URL of an OData service to indicate which results should be returned based on certain conditions. The syntax for the $filter option is as follows: $filter=condition, where the condition is a logical expression that evaluates to true or false.

The condition can be built using comparison and logical operators (eq, ne, gt, ge, lt, le, and, or, not).

For example, if we want to retrieve all customers whose last name starts with "S", the URL would look like this:
http://<host>/sap/opu/odata/sap/<service>/Customers?$filter=startswith(LastName,'S')

If we want to retrieve all customers whose last name starts with "S" and whose first name is "John", the URL would look like this:
http://<host>/sap/opu/odata/sap/<service>/Customers?$filter=startswith(LastName,'S') and FirstName eq 'John'

The $filter option can be used in combination with other options such as $top, $skip, $select, and $orderby to further refine the results of a query.
  METHOD ekkoset_get_entityset.

*- To get data from DB
*- it_filter_select_options will have filter values for $filter keyword
IF it_filter_select_options IS INITIAL.
SELECT * FROM ekko INTO TABLE @DATA(lt_ekko) UP TO 10 ROWS.
ELSE.
READ TABLE it_filter_select_options INTO DATA(ls_sopt)
WITH KEY property = 'Ebeln'.
IF sy-subrc IS INITIAL.
SELECT * FROM ekko INTO TABLE @lt_ekko WHERE ebeln IN @ls_sopt-select_options.
ENDIF.
ENDIF.

*- Check the $orderby in the Odata Query
/iwbep/cl_mgw_data_util=>orderby(
EXPORTING
it_order = it_order " the sorting order
CHANGING
ct_data = lt_ekko
).

*- For paging i.e. $top and $skip
/iwbep/cl_mgw_data_util=>paging(
EXPORTING
is_paging = is_paging " paging structure
CHANGING
ct_data = lt_ekko
).

*- Check the size of the table for $inlinecount
IF io_tech_request_context->has_inlinecount( ) = abap_true.
DESCRIBE TABLE lt_ekko LINES DATA(lv_size).
es_response_context-inlinecount = lv_size.
ENDIF.

MOVE-CORRESPONDING lt_ekko TO et_entityset.

ENDMETHOD.

We can test the above code as:



4. $filter.jpg


5. $inlinecount: It is used to include the total count of all the matching results in the response. It is used in the URL of an OData service to indicate that the total count of the matching results should be included in the response. The syntax for the $inlinecount option is as follows: $inlinecount=allpages, where "allpages" is a keyword indicating that the total count should be included.

For example, if we want to retrieve all customers and include the total count of customers in the response, the URL would look like this:
http://<host>/sap/opu/odata/sap/<service>/Customers?$inlinecount=allpages

The $inlinecount option can be used in combination with other options such as $filter, $top, $skip, $select and $orderby to further refine the results of a query.
http://<host>/sap/opu/odata/sap/<service>/Customers?$filter=Country eq 'US'&$top=5&$skip=5&$orderby=LastName desc&$inlinecount=allpages

It's important to note that the $inlinecount option will include the count of the matching results in the response, the count will be included in the ".count" attribute of the response.


5. $filter.jpg


6. $skiptoken: The $skiptoken option is used with the $top option to retrieve a specific page of results by providing a token that represents the position in the result set from where the next set of results should be retrieved. When a partial response is returned by the server, the $skiptoken value is included in the __next link of the response, allowing clients to easily retrieve the next set of results without having to construct or interpret the $skiptoken value themselves.

The syntax for the $skiptoken option is as follows: $skiptoken=token, where the token is a string value representing the position in the result set from where the next set of results should be retrieved.

For example, if we want to retrieve the next set of 10 customers starting from the 11th customer, the URL would look like this:
http://<host>/sap/opu/odata/sap/<service>/Customers?$top=10&$skiptoken='11'

The $skiptoken option can be used in combination with other options such as $filter, $top, $select and $orderby to further refine the results of a query.
http://<host>/sap/opu/odata/sap/<service>/Customers?$filter=Country eq 'US'&$top=5&$skiptoken='11'&$orderby=LastName desc

It's important to note that the $skiptoken option is used to navigate through the result set in a pagination manner, and it should be used in conjunction with $top option and the result set should be sorted in the same order as in the query that generated the skiptoken.


6. $skiptoken.jpg


 

The $skip and $skiptoken looks same in first look but they are some difference. To know further about $skip and $skiptoken you can visit this blog: Difference between $skip and $skiptoken in Odata

 

Conclusion


SAP has provided us multiple options to play with for real-time requirements with a little effort. I would recommend you to try these query options and debug to see how it works. The blog was divided into the following parts.

  • $orderby: sorts data by one or more fields.

  • $top and $skip: enable server-side paging.

  • $filter: retrieves specific data from an entity set based on a set of criteria.

  • $inlinecount: provides the total number of records in an entity set.

  • $skiptoken: enables server-side paging using a continuation token.


 




Edit 1: Thanks @gregorw for helping to enrich the blog.

In the world of Odata services, there are two types of services -

  • Those created from SEGW

  • Those based on CDS views


When creating Odata services from SEGW, custom implementation is required for the $orderby, $top, $skip, $filter, and $inlinecount query options. However, this is not the case when the Odata service is based on a CDS view. In this scenario, SAP provides these query options without the need for implementation, making the development process simpler and more efficient.

It’s important to note that this difference exists because of the fundamental architectural differences between SEGW and CDS views. SEGW generates ABAP code based on metadata, whereas CDS views are defined in the ABAP repository and translated into Open SQL. By leveraging the capabilities of CDS views, developers can benefit from SAP’s pre-built query options and focus on delivering value to their customers.

If you have any thoughts or questions on the topic, please feel free to leave a comment below. I would love to hear from you.




 

If you found this post helpful, please like and share it with your network 🙂

 

Kind Regards,

Nitin Sharma


9 Comments
matt
Active Contributor
0 Kudos
It would be helpful in this series if at the top you link to the previous and at the bottom you link to the next.
nitinksh1
Participant
Hello Matthew,

Thank you for taking the time to read and comment on my blog series. I appreciate your suggestion and will be happy to implement it to enhance the user experience. The series is covered in two parts, and I have already included a link to the second part at the beginning of the first part.

To further assist readers in navigating through the series, I will also include a link to the second part at the end of the first part, as you suggested.

Thank you again for your suggestion, and please feel free to share any further comments or feedback.

Thanks,
Nitin Sharma
RalfHandl
Product and Topic Expert
Product and Topic Expert
0 Kudos
The blog says
It’s important to note that the $filter option is applied after the $skip option, meaning that it filters the results after skipping the specified number of records.

This contradicts the evaluation sequence defined in the OData specification: $filter must be applied before applying $skip.
RalfHandl
Product and Topic Expert
Product and Topic Expert
0 Kudos

The blog says

5. $inlinecount: The $inlinecount option is used to include the total number of results that match a query in the response, in addition to the results themselves.

This is misleading:

  • Assume the People data source contains 5000 people with first name "John".
  • Assume you
    GET People?$filter=firstname eq 'John'&$top=10

This means that the response will contain 10 people objects with a firstname of 'John', and an __count of 5000.

It's not the response that matters, it is the number of matching data objects on the server, that is typically the number of matching records in the database

Try https://services.odata.org/V2/Northwind/Northwind.svc/Customers?$format=json&$inlinecount=allpages&$...

This returns one customer record, and a __count of 91.

RalfHandl
Product and Topic Expert
Product and Topic Expert
0 Kudos
Regarding $skiptoken: the author correctly states that
The $skiptoken option is used to retrieve the next set of results when the result of a query exceeds the maximum number of items that can be returned in a single response.

The important part here is that the server injects $skiptoken in a __next-link when it returns a partial response, clients SHOULD NEVER try to construct a $skiptoken value because it is service-specific how the $skiptoken value is constructed and interpreted.

Try for example https://services.odata.org/V2/Northwind/Northwind.svc/Customers?$format=json&$inlinecount=allpages

This will return this server's maximum of 20 data objects, plus a __count of 91, and a __next link.

A client interested in the next page simply fires a GET request with that __next link, without having to care how the server constructed that __next link, or needing to interpret the $skiptoken.

Being curious we can look at the __next link we get here, and it contains $skiptoken='ERNSH'. This happens to be the primary key value of the last data object returned, which is a more stable and thus much better implementation than using a numeric offset.
nitinksh1
Participant
Hi Ralf,

Thanks for pointing out the correction.

Thanks,
Nitin Sharma
nitinksh1
Participant
Hi Ralf,

Thanks for pointing out the correction.

Thanks,
Nitin Sharma
nitinksh1
Participant
Hi Ralf,

Thanks for pointing out the correction.

Thanks,
Nitin Sharma
wilbertkarremans
Participant
0 Kudos
Is it possible to increase the value of the $skiptoken which the server injects? By default the values is 100 which is rather small for a API I have built.

Wilbert
Labels in this area