Skip to Content
Technical Articles
Author's profile photo Ram Bandla

OData Versioning

OData has become an inevitable topic for any SAP ABAP developer. I am sure most of us are involved in an OData development one way or the other.

Let’s discuss versioning, one of the advanced concepts of OData.

Note – I are working with OData version 2.0 in this article.

Motivation

Ever wondered if the business logic of an OData can be modified and activated as a different version without effecting the current business logic? I did and some of the scenarios I have faced are

Front-end team is not yet ready for the change but I would like to keep going.

I was working on an API and wanted to roll-out version 2 but wanted to maintain an active version 1 as well.

What kind of changes?

Mostly breaking changes that will not go well with the front-end implementation of the OData. Some of them are

  • Adding a mandatory filter to the OData the front-end has not implemented
  • New validation on the back-end that front-end is not adhering to
  • Changing the key fields
  • Deleting a field that is utilized by the front-end

 

Metadata based categorizing of OData versioning

These changes can be broadly categorized into 2 types based on the metadata

  1. OData versioning not including metadata change
  2. OData versioning including metadata change

Let’s discuss each one with an example.

Example OData

I have created an OData with the well known SAP’s FLIGHT test data.

  1. Using SEGW transaction create an OData project ‘ZODATA_VERSIONING’.
  2. From the context menu of ‘Data Model’ create entity type ‘AvailableFlight’ and generate the OData project.
  3. Change the ‘Technical Service Name’ to ‘FLIGHT’ and take a note of the Service Version 1. This is the default version of the OData ‘FLIGHT’ .As displayed below new Model Provider and Data Provider Classes are generated.
  4. Using transaction code ‘/IWBEP/REG_MODEL’ we can verify that the ‘Technical Model Name’, ‘Model Version’, ‘Model Provider Class’  are registered in the back-end system. We can verify the same  and ‘/IWBEP/REG_SERVICE’ respectively.
  5.  The model is registered stand alone.
  6. Using transaction code /IWBEP/REG_SERVICE we can verify that the ‘Technical Service Name’, ‘Service Version’, ‘Data Provider Class’ are registered in the back-end system.
  7. While the model is registered stand alone the service is registered in combination with the model.
  8. Now maintain the service in the Gateway system using T-CODE ‘/IWFND/MAINT_SERVICE’. Please note the service version ‘1’ and the Model version ‘1’ which were retrieved from the FLIGHT Technical Service Registration version 1 in the back-end.
  9. OData service ‘FLIGHT’ with version 1 on both backend and the Gateway is maintained successfully.
  10. The OData can be accessed via URL ‘/sap/opu/odata/sap/FLIGHT/AvailableFlightSet?$format=json’.
  11. This is nothing but the default version 1 of the OData.
  12. Adding ‘?v=1’  to the URL after the OData name provides the same result.

OData versioning not including metadata change

Let’s modify the OData logic without modifying the metadata.

Let’s say the requirement is to add a mandatory filter ‘CONNID’ but only to the new version.

  1. Copy the respective data provider class(*DPC_EXT) class as below and add the required mandatory filter.
    1.   METHOD AVAILABLEFLIGHTS_GET_ENTITYSET.
      
          DATA: LR_CONNID TYPE RANGE OF S_CONN_ID.
      
          DATA(LT_SO) = VALUE #( IT_FILTER_SELECT_OPTIONS[ PROPERTY = 'CONNID' ]-SELECT_OPTIONS OPTIONAL ).
          IF LT_SO IS INITIAL."Return no data if CONNID filter is blank.
            RETURN.
          ENDIF.
      
      
          SELECT *
            FROM
              SFLIGHT
            INTO TABLE @DATA(LT_SFLIGHT)
            WHERE
              CONNID IN @LT_SO.
      
          ET_ENTITYSET = CORRESPONDING #( LT_SFLIGHT ).
      
        ENDMETHOD.
  2. Register the new data provider class using transaction code ‘/IWBEP/REG_SERVICE’.
    1. Make sure to select OData name as ‘FLIGHT’, same as the previous ‘Technical Service Name’ and version 2.
    2. Add the new data provider class as below and save.
    3. Click on ‘Assign Model’ button and assign the old model provider class and version 1.
    4. Maintain the service in the Gateway using T-CODE ‘/IWFND/MAINT_SERVICE’.
    5. Please note the service version ‘2’ and the Model version ‘1’ which are retrieved from the FLIGHT Technical Service version 2 Registration in the back-end.
    6. On Gateway system via T-CODE ‘/IWFND/MAINT_SERVICE’, 2 versions of the OData FLIGHT are maintained.
    7. Both versions with different business logic can be accessed now.
      1. Accessing data via the version 1 or default version of the OData with no mandatory filter.
      2. Version 2 of the OData does not return any data unless mandatory filter is added to the query.

 

OData versioning including metadata change

Now the new requirement is to add version 3 of FLIGHT OData with no Price field and add the mandatory CONNID filter as per version 2 to ‘AvailableFlight’ entity.

For the metadata change we need to create a new version of the Model Provider Class. But we need to do this without loosing SAP Gateway Service Builder(SEGW) tool assistance.

  1. Copy the existing project via the SEGW T-CODE.
  2. Remove the ‘PRICE’ field from the OData ‘AvailableFlight’ entity.
  3. Generate the OData and change the ‘Technical Service Name’ to ‘FLIGHT’ and the ‘Service Version’ to 3.
  4. Add the mandatory filter logic as required in the data provider class ‘ZCL_ZODATA_VERSIONING3_DPC_EXT’. This code is same as version 2 of the OData.
    1.   METHOD AVAILABLEFLIGHTS_GET_ENTITYSET.
      
          DATA: LR_CONNID TYPE RANGE OF S_CONN_ID.
      
          DATA(LT_SO) = VALUE #( IT_FILTER_SELECT_OPTIONS[ PROPERTY = 'CONNID' ]-SELECT_OPTIONS OPTIONAL ).
          IF LT_SO IS INITIAL."Return no data if CONNID filter is blank.
            RETURN.
          ENDIF.
      
      
          SELECT *
            FROM
              SFLIGHT
            INTO TABLE @DATA(LT_SFLIGHT)
            WHERE
              CONNID IN @LT_SO.
      
          ET_ENTITYSET = CORRESPONDING #( LT_SFLIGHT ).
      
        ENDMETHOD.
  5. Now maintain the service in the Gateway using T-CODE ‘/IWFND/MAINT_SERVICE’. Please note the service version ‘3’ and the Model version ‘1’ which are retrieved from the FLIGHT Technical Service version 3 registered in the back-end.
  6. All 3 versions of the OData SFLIGHT are registered on the Gateway system.
  7. Query the version 3 of the OData with the mandatory filter and the deleted PRICE field.

 

In this article, you learned

  1. Registering the OData Technical Model Name in the back-end.
  2. Registering the OData Technical Service Name in the back-end.
  3. Maintaining the OData Service in the Gateway.
  4. Registering different versions of OData Technical Model Name and Technical Service Name in the backend.
  5. Maintaining different versions of OData Service in the Gateway.

Further reading

  • You can get a overview of ABAP OData from ABAP OData
  • Check ABAP Profiling for performance analysis of OData or general ABAP.

 

Assigned Tags

      10 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Ram Bandla
      Ram Bandla
      Blog Post Author

      Feel free to check ABAP Profiling for performance analysis.

      Author's profile photo Wouter Peeters
      Wouter Peeters

      Good overview and this is good to keep in the back of your head.

      In a use case where it is a matter of software logistics between backend and frontend, I would prefer to sync between both parties and align transports. If it would be a matter of really going 'API based', where we do not directly control the consumers, we could utilize your mentioned principles and techniques. But if the latter is the case, I wonder what the advantages of the backend techniques are in comparison to the API Management techniques.

      Author's profile photo Ram Bandla
      Ram Bandla
      Blog Post Author

      Transporting both FE(front-end) and BE(back-end) together is what I support and follow as well. But my point is more on keeping the team busy in dev system.

      That is,

      1. FE is not ready for the change in the development system, they are busy with some other change which requires oData to version 1.
      2. But BE team want's to go ahead and make the change without waiting for FE to be ready.

      That is where BE can create version 2 and be done with the work. When FE is ready, FE can integrate with version 2, BE can deactivate version 1 and move both FE and BE changes to next environment.

      Author's profile photo Wouter Peeters
      Wouter Peeters

      I see. Another good topic to mention is that you can create seperate Gateway projects with each their entities, to finally embed the entities under a main endpoint, allowing you to transport each DPC class independently

      E.g.

      • Main Gateway Project ZGW_MAIN
        • Embedded Gateway Project ZGW_ENTITY_GROUP_1
        • Embedded Gateway Project ZGW_ENTITY_GROUP_2
      Author's profile photo Titus Thomas
      Titus Thomas

      Sorry to digress from the main topic, but how can we embed one GW project into another GW project ?

      Author's profile photo Titus Thomas
      Titus Thomas

      Ram Bandla Thanks for this interesting article on versions. One question, can the Front End use version 2 as well by adding the suffix ;v=2 to the OData service url ?

      Author's profile photo Ram Bandla
      Ram Bandla
      Blog Post Author

      Hi Titus Thomas

      Yes, we can. That is the benefit of this approach. The GW client is acting as a browser. If you try it via browser you get the same result. Of course you need right access to the oData both for GW client and browser.

       

      Ram

       

       

      Author's profile photo Jelena Perfiljeva
      Jelena Perfiljeva

      Thanks for sharing, very interesting subject!

      Some questions. To be honest, it lost me at "copy the respective data provider class(*DPC_EXT) class". Is this actually a good idea? I always thought that we should just leave SEGW do its own thing and take care of all the DPC etc. generation. (For the same reason, I always put only minimum code in the ...DPC_EXT methods.)

      Also, it seems that the goal is not to keep two versions indefinitely but actually reconcile them eventually into a single service. Is that correct? Wouldn't having multiple projects / copied classes present some challenges when the time comes to combine everything together?

      I'm familiar with the challenges of "back end works ahead of front end" but the way we resolved this in the past was to use a temporary SEGW project or simply work on a class in isolation as much as possible and then plug it into SEGW project when the other side was ready for implementation. These are not ideal solutions either, of course, so I'm very interested in better development management tools.

      Thank you!

      P.S. It's spelled "OData". Thought I'd point this out. 🙂

      Author's profile photo Ram Bandla
      Ram Bandla
      Blog Post Author

      Thanks  Jelena Perfiljeva for the comment.

      Versioning can be achieved via copying *DPC_EXT class or copying the SEGW project itself.

      Keeping minimum code in *DPC_EXT is what I follow and suggest.

      OData corrected.

      Ram

      Author's profile photo Andre Fischer
      Andre Fischer

      The topic service versioning is nicely explained.

      I would have the following remarks:

      • In point 12. there is a small typo.
        Adding ‘?v=1’  to the URL after the OData name provides the same result.
        should read as follows
        Adding ‘;v=1’  to the URL after the OData name provides the same result.

      • At SAP we do not use service versioning when it comes to delivering the services for SAP Fiori apps but deliver new services, that means a service with a different service name FLIGHT2.
        (Though we have developed service versioning ;-))
        From a technical point of view you use two different URL's when accessing your OData services either by adding a version ;v=2 or by changing the service name.

        /sap/opu/odata/sap/FLIGHT;v=2/AvailableFlightSet
        /sap/opu/odata/sap/FLIGHT2/AvailableFlightSet

       

      Kind regards,

      Andre