본문 바로가기

SAP Story

OData 기초 - Gateway Service Builder Part II

OData 기초 - Gateway Service Builder Part II

Agenda

    1.    SEGW - Gateway Service Builder 에서 프로젝트 관리

    2.    Data Modeling - Structure, Table Type, SADL Based

    3.    Action Based : Model Class ( Data Provider & Model Provider )

    4.    Redefine Data Provider method get, create..etc

    5.    Register OData Service using '/IWFND/MAINT_SERVICE

    6.    Test(Debug) by Gateway Client


Service Maintenance 에서 SAP Gateway Client 사용 (REST)

OData 기초 시리즈 1편에서 보았던 REST 개념을 상기해보면 리소스 참조 방식의 URI (Uniform Resource Identifier ) 구조에 대한 이해 선행이 필요하다.


[참조] 이전 포스팅 항목 : REST Based APIs


REST 방식의 찾아가기 (= 타겟매핑) 체계인  URI Convention 에 대해 별도로 다루어 볼까 한다. OData Service Catalog 자원에 대해 사용하기 위해서는 이 체계(=문법)에 익숙해져야 하기 때문이다.
SAP S/4 HANA 1709 의 범용 버전은 OData Ver 2.0 이고 대부분의 OData Service Catalog 관리를 /IWFND/MAINT_SERVICE 티코드를 사용하는 것으로 확인할 수 있다. 참고로 OData Ver 4.0 의 경우 티코드 /IWFND/R_V4_ADMIN_SERVICES 를 사용하여 관리한다. 
OData URI 는 1) OData 서비스 루트 2)자원 경로 3)자원에 대한 질의부, 세 가지로 구성된다. 
OData URI Convention
Service Root URI 의 경우 Odata Service Catalog 의 활성화된 서비스 이름이다. 즉 /sap/opu/odata/SAP/ 경로 아래에 OData Service Name 으로부터 시작된다. Resource Path 의 경우 앞으로 소개할 데이터 모델에 관련된 자원 주소이다. 이번 포스팅에서는 예제를 중심으로 문법을 익히는 것을 목표로 하겠다.

URI Componet


반복되는 그림이지만 이 구조는 OData 그리고  fiori  에서 표현하는 모든 찾아가기의 기본 골자이다.  Service Root 는 Gateway Builder 의 프로젝트에 대응하고 이 관문(=Gateway)을 통해 ABAP 의 세계 또는 Native  HANA 의 세계로 들어간다. 이는 Front-end 의 Fiori, Back-end 의 ABAP 혹은 HANA 동시 진행이 가능하다는 뜻이고 Back-end 구현은 액션(=이벤트,거래)을 바탕으로 데이터 모델과 처리 로직 구현에 집중할 수 있다는 뜻이다. 이러한 점은 기업으로 하여 이원화 된 프로젝트 관리 비용의 증가와 함께 웰모델링에 따른 TCO 감소라는 이익을 가져올 수 있는 구조이다. 고민이 클 것으로 본다.


Service Root 에 이어 Resource Path 는 데이터 모델 엔티티 레벨이라고 생각하면 정확하다.

즉 어떤 서비스(=앱의 특성)이냐의 세부 자원(=앱의 정보,액션)을 묘사하는 것으로 정의할 수 있다.


다음의 OData.Org 에서 설명하는 예제를 살펴보자.

서비스 이름은 OData.svc 이고 메타데이터를 보면 상품 구매에 관련된 내용임을 짐작할 수 있다.


링크참조 : https://www.odata.org/


The example URIs below follow the addressing rules stated above and are based on the reference service and its service metadata document available at https://services.odata.org/OData/OData.svc/ and https://services.odata.org/OData/OData.svc/$metadata.


샘플 데이터 모델은 메타데이터로 부터 인지할 수 있는데 xml-json-xlsx 로 변환해보면 아래와 같이 7개의 엔티티를 가진 데이터 모델임을 알 수 있다. 

( 참고로 json to csv 라는 아주 좋은 사이트가 있다... 고마운 사이트이다.  https://konklone.io/json/ )


상상해 보자. 상품,공급처,담당자,판촉 등의 업무를 위와 같이 자원베이스로 정의를 했다고 볼 수 있고 이는 통상적인 SAP ERP 업무에서 사용하여 인식하는 구조와 맥락이 동일하다. 개별 엔티티가 존재하고 각 엔티티간의 연결고리가 있다는것, 이 부분을 OData 에서는 자원 Resource 로 이해하고 있고 이를 가져와라(Get), 반영해라 (Post), 만들어라 (Create), 날려라 (Delete) 의 행위와 결합하여 업무의 결과를 반영한다. 


Products, Categories 등 자원의 정보를 가져오는 URI Convention 의 예를 들면 다음과 같다.


1
2
3
4
https://services.odata.org/OData/OData.svc/Categories
 
Identifies all Categories Collection.
Is described by the Entity Set named "Categories" in the service metadata document.
cs



카테고리 정보를 가져오는 의미.. 너무 쉽게 표현된다. 일반적으로 리소스만 언급되면 Set 단위 ABAP 표현으로는 테이블 타입 파라미터로 전달. 


안에 무엇으로 구현이 되었건 간에 카테고리 가져와 !! 이런 의미이다. ( 고객의 요청은 이렇게 간단하다 )


리소스에 특정한 Key 값을 부여하는 패턴의 경우 단일 레코드가 반환이 되는데 ABAP 표현으로는 Work Area 와 유사한 개념으로 볼 수 있다. 

Products, Categories 등 자원의 정보를 가져오는 URI Convention 의 예를 들면 다음과 같다.



1
2
3
4
https://services.odata.org/OData/OData.svc/Categories(1)
 
Identifies a single Category Entry with key value 1.
Is described by the Entity Type named "Categories" in the service metadata document.
cs

Categories(1) 의 의미는 카테고리 id = 1 을 가져오라는 의미이다. (메타데이터 참조) 즉 자원을 통으로 가져오거나 Predicated Key를 사용하여 특정 자원만 가져오거나 하는 행위를 할 수 있는데 URI 컨벤션의 사용 문법을 잘 이해하면 된다.


이후 다음과 같은 예를 들 수 있다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
https://services.odata.org/OData/OData.svc/Categories
 
Identifies all Categories Collection.
Is described by the Entity Set named "Categories" in the service metadata document.
https://services.odata.org/OData/OData.svc/Categories(1)
 
Identifies a single Category Entry with key value 1.
Is described by the Entity Type named "Categories" in the service metadata document.
https://services.odata.org/OData/OData.svc/Categories(1)/Name
 
Identifies the Name property of the Categories Entry with key value 1.
Is described by the Property named "Name" on the "Categories" Entity Type in the service metadata document.
https://services.odata.org/OData/OData.svc/Categories(1)/Products
 
Identifies the collection of Products associated with Category Entry with key value 1.
Is described by the Navigation Property named "Products" on the "Category" Entity Type in the service metadata document.
https://services.odata.org/OData/OData.svc/Categories(1)/Products/$count
 
Identifies the number of Product Entries associated with Category 1.
Is described by the Navigation Property named "Products" on the "Category" Entity Type in the service metadata document.
https://services.odata.org/OData/OData.svc/Categories(1)/Products(1)/Supplier/Address/City
 
Identifies the City of the Supplier for Product 1 which is associated with Category 1.
Is described by the Property named "City" on the "Address" Complex Type in the service metadata document.
https://services.odata.org/OData/OData.svc/Categories(1)/Products(1)/Supplier/Address/City/$value
 
Same as the URI above, but identifies the "raw value" of the City property.
cs


Resource Component 에 추가 주제는 Association 으로 이 부분은 별도의 포스팅에서 다룰 예정이다.

위 예시에서 Categories(1)/Name 의 형식을 보면 카테고리와 그 네임은 릴레이션이 있음을 짐작할 수 있고

인간 사회나 데이터 모델링이 닮은 점은 모두 "관계"를 가지고 살아 간다는 점이다.


이번 포스팅에서는 자원사용측면에 대해 다루는 것으로 하고가고 다음 요소로는 

Query 부문인데, 이 개념은 기존의 Web Site URL 을 유심히 봤다면 "?" 이후 전개되는 패턴과 동일하다.

즉 이제부터는 카운트를 하거나 필터링을 하거나 탑부분 몇개만 보여달라거나, 특정 필드만 보여주세요 라거나... 자원을 활용하기 위한 부가 질의에 관련이 있다. 패턴은 다음과 같다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
https://services.odata.org/OData/OData.svc/Products?$orderby=Rating
 
All Product Entries returned in ascending order when sorted by the Rating Property.
https://services.odata.org/OData/OData.svc/Products?$orderby=Rating asc
 
Same as the example above.
https://services.odata.org/OData/OData.svc/Products?$orderby=Rating,Category/Name desc
 
Same as the URI above except the set of Products is subsequently sorted (in descending order) by the Name property of the related Category Entry.
 
https://services.odata.org/OData/OData.svc/Products?$top=5
 
The first 5 Product Entries returned where the Collection of Products are sorted using a scheme determined by the OData service.
https://services.odata.org/OData/OData.svc/Products?$top=5&$orderby=Name desc
 
The first 5 Product Entries returned in descending order when sorted by the Name property
 
A URI with a $filter System Query Option identifies a subset of the Entries from the Collection of Entries identified by the Resource Path section of the URI. The subset is determined by selecting only the Entries that satisfy the predicate expression specified by the query option.
 
The expression language that is used in $filter operators supports references to properties and literals. The literal values can be strings enclosed in single quotes, numbers and boolean values (true or false) or any of the additional literal representations shown in the Abstract Type System section.
 
Note: The $filter section of the normative OData specification provides an ABNF grammar for the expression language supported by this query option.
 
The operators supported in the expression language are shown in the following table.
 
Operator    Description    Example
Logical Operators
Eq    Equal    /Suppliers?$filter=Address/City eq 'Redmond'
Ne    Not equal    /Suppliers?$filter=Address/City ne 'London'
Gt    Greater than    /Products?$filter=Price gt 20
Ge    Greater than or equal    /Products?$filter=Price ge 10
Lt    Less than    /Products?$filter=Price lt 20
Le    Less than or equal    /Products?$filter=Price le 100
And    Logical and    /Products?$filter=Price le 200 and Price gt 3.5
Or    Logical or    /Products?$filter=Price le 3.5 or Price gt 200
Not    Logical negation    /Products?$filter=not endswith(Description,'milk')
Arithmetic Operators
Add    Addition    /Products?$filter=Price add 5 gt 10
Sub    Subtraction    /Products?$filter=Price sub 5 gt 10
Mul    Multiplication    /Products?$filter=Price mul 2 gt 2000
Div    Division    /Products?$filter=Price div 2 gt 4
Mod    Modulo    /Products?$filter=Price mod 2 eq 0
Grouping Operators
( )    Precedence grouping    /Products?$filter=(Price sub 5) gt 10
 
cs


마지막으로 SEGW 에서 서비스 테스트를 해보면 다음과 같은 항목을 발견하는데 이를 위해 지금까지 장황하게 URI Convention 을 말했다고 해도 과언이 아니다.



 위 화면에서 Entity Set 부분이 자원할당에 관련된 URI 이고 URI Option 이 Query 에 관련된 URI 이다.

화면에 가려진 Full URI 를 보면서 이번 개념 설명 포스트는 마무리 한다.