
Rest Nedir?
REST, HTTP protokolünü kullanarak client ve server arasında veri transferini sağlayan, web standartlarına dayalı bir mimaridir. Rest mimarisi SOAP ve WSDL servislerine alternatif olarak geliştirilmiştir. Veri iletişimi http protokolü üzerinden http metotları(get, post, put, delete) kullanılarak yapılan istekler ile gerçekleştirilir. Yapılan isteklere ise; XML, JSON vb. formatlarda yanıtlar dönderilir.
Neden Rest?
- SOAP mimarisine göre daha basit ve hızlıdır. Kompleks yapılar yerine http protokolünü kullanır.
- SOAP mimarisine göre katı standartları yoktur.
- SOAP mimarisinde olduğu gibi proxy kullanmaya gerek duymaz.
- Platform ve dil bağımsızdırlar.
- Esnek ve genişletilebilmesi oldukça kolaydır.
- SOAP sadece XML veri formatını desteklerken REST JSON, XML, HTML, vb. gibi birden fazla veri formatını desteklemektedir.
AFAD Web Servisi
Afad web servisi AFAD’ın sunduğu bir web hizmeti olup, ilgili veri ve bilgileri paylaşmak ve entegrasyonunu sağlamak amacıyla kullanılır. Rest mimari tabanlı olup, http protokolünü kullanarak yapılan http metotları istekleri ile JSON, XML, CSV vb. veri formatlarında yanıt dönebilmektedir.
SAP Abap CL_HTTP_CLIENT Sınıfı
SAP Abap ile HTTP protokolünü destekleyen ve herhangi bir sunucuyla iletişim kurmak için için gerekli olan özellikleri ve metotları içeren bir sınıftır. Bu sınıfı kullanarak http istekleri oluşturabilir, gönderilebilir, yanıt alınabilir.
SAP Abap İle Rest API Uygulaması
SAP ABAP ile CL_HTTP_CLIENT sınıfını kullanarak rest mimarisi üzerinden AFAD web servisine bağlanarak seçilen giriş parametrelerine göre deprem bilgilerini filtreleyip, raporlayan bir ekran yapacağız.
"Verilerin Tutulacağı Internal Table
DATA : BEGIN OF GT_DATA OCCURS 0,
COUNTRY LIKE DFIES-SCRTEXT_L,
DATE LIKE DFIES-SCRTEXT_L,
DISTRICT LIKE DFIES-SCRTEXT_L,
EVENTID LIKE DFIES-SCRTEXT_L,
ISEVENTUPDATE LIKE DFIES-SCRTEXT_L,
LASTUPDATEDATE LIKE DFIES-SCRTEXT_L,
LATITUDE LIKE DFIES-SCRTEXT_L,
LONGITUDE LIKE DFIES-SCRTEXT_L,
LOCATION LIKE DFIES-FIELDTEXT,
MAGNITUDE LIKE DFIES-SCRTEXT_L,
DEPTH LIKE DFIES-SCRTEXT_L,
NEIGHBORHOOD LIKE DFIES-SCRTEXT_L,
PROVINCE LIKE DFIES-SCRTEXT_L,
RMS LIKE DFIES-SCRTEXT_L,
TYPE LIKE DFIES-SCRTEXT_L,
END OF GT_DATA.
"URL Bilgisini İçeren Değişken
DATA : LV_SERVICE_URL TYPE STRING.
"Rest API İçi Kullanılan Değişkenler
DATA : CL_HTTP_CLIENT TYPE REF TO CL_HTTP_CLIENT.
DATA : CLIENT TYPE REF TO IF_HTTP_CLIENT.
DATA : REQUEST TYPE REF TO IF_HTTP_ENTITY.
DATA : LV_RESPONSE_DATA TYPE STRING.
"List Box İçin Kullanılan Değişkenler
DATA : LV_ID TYPE VRM_ID.
DATA : LT_VALUES TYPE VRM_VALUES.
"Ekran Giriş Parametreleri
SELECTION-SCREEN BEGIN OF BLOCK B1.
PARAMETERS : P_SDATE TYPE SY-DATUM OBLIGATORY,
P_EDATE TYPE SY-DATUM OBLIGATORY,
P_STIME TYPE SY-UZEIT OBLIGATORY,
P_ETIME TYPE SY-UZEIT OBLIGATORY.
PARAMETERS : P_MINMAG TYPE INT1.
PARAMETERS : P_CITY(2) AS LISTBOX VISIBLE LENGTH 10.
SELECTION-SCREEN END OF BLOCK B1.
"Giriş Ekranın Oluşması Sırasında Listbox'ın Doldurulması
AT SELECTION-SCREEN OUTPUT.
SELECT REGIO AS KEY, BEZEI AS TEXT
INTO CORRESPONDING FIELDS OF TABLE @LT_VALUES
FROM ZCITIES.
LV_ID = 'P_CITY'.
CALL FUNCTION 'VRM_SET_VALUES'
EXPORTING
ID = LV_ID
VALUES = LT_VALUES
* EXCEPTIONS
* ID_ILLEGAL_NAME = 1
* OTHERS = 2
.
IF SY-SUBRC <> 0.
* Implement suitable error handling here
ENDIF.
"Ekranın Çalıştırılması Olayı
START-OF-SELECTION.
PERFORM GET_DATA.
IF GT_DATA[] IS NOT INITIAL.
PERFORM DISPLAY_DATA.
ELSE.
MESSAGE 'Belirtilen Kriterlere Ait Veri Bulunamadı' TYPE 'I'.
ENDIF.
"Ekranın Çalıştırılması Olayı
FORM GET_DATA .
DATA : LV_STARTDATE TYPE CHAR10,
LV_ENDDATE TYPE CHAR10,
LV_STARTTIME TYPE CHAR8,
LV_ENDTIME TYPE CHAR8.
P_STIME+0(2) = P_STIME+0(2) - 03.
P_ETIME+0(2) = P_ETIME+0(2) - 03.
"Başlangıç Tarihi
LV_STARTDATE = P_SDATE(4) && '-' &&
P_SDATE+4(2) && '-' &&
P_SDATE+6(2).
"Bitiş Tarihi
LV_ENDDATE = P_EDATE(4) && '-' &&
P_EDATE+4(2) && '-' &&
P_EDATE+6(2).
"Başlangıç Saati
LV_STARTTIME = P_STIME(2) && ':' &&
P_STIME+2(2) && ':' &&
P_STIME+4(2).
"Bitiş Saati
LV_ENDTIME = P_ETIME(2) && ':' &&
P_ETIME+2(2) && ':' &&
P_ETIME+4(2).
"URL
LV_SERVICE_URL = 'https://deprem.afad.gov.tr/apiv2/event/filter?' &
'start=' && LV_STARTDATE &&
'%20' && LV_STARTTIME &&
'&' &
'end=' && LV_ENDDATE &&
'%20' && LV_ENDTIME &&
'&orderby=timedesc'.
"Min Büyüklük Bilgisi Girili İse URL
IF P_MINMAG IS NOT INITIAL.
LV_SERVICE_URL = 'https://deprem.afad.gov.tr/apiv2/event/filter?' &
'start=' && LV_STARTDATE &&
'%20' && LV_STARTTIME &&
'&' &
'end=' && LV_ENDDATE &&
'%20' && LV_ENDTIME &&
'&' &
'minmag=' && P_MINMAG &&
'&orderby=timedesc'.
ENDIF.
"Verilen URL bilgisi ile bir HTTP istemci nesnesi oluşturulur.
CL_HTTP_CLIENT=>CREATE_BY_URL(
EXPORTING
URL = LV_SERVICE_URL " URL
IMPORTING
CLIENT = CLIENT " HTTP Client Abstraction
EXCEPTIONS
ARGUMENT_NOT_FOUND = 1
PLUGIN_NOT_ACTIVE = 2
INTERNAL_ERROR = 3
OTHERS = 4
).
IF SY-SUBRC <> 0.
MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.
"Oluşturulan HTTP istemci nesnesi ile HTTP isteği gönderilir.
CLIENT->SEND( ).
IF SY-SUBRC <> 0.
MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.
"Gönderilen İsteğe Ait Gelen Yanıt Okunur.
CLIENT->RECEIVE( ).
IF SY-SUBRC <> 0.
MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.
"Gelen isteğe ait yanıtın içeriği String tipinde alınır.
LV_RESPONSE_DATA = CLIENT->RESPONSE->GET_CDATA( ).
DATA : LR_DATA TYPE REF TO DATA.
"String tipinde olan JSON verisi Internal Table'a Aktarılır.
/UI2/CL_JSON=>DESERIALIZE(
EXPORTING
JSON = LV_RESPONSE_DATA " JSON string
PRETTY_NAME = /UI2/CL_JSON=>PRETTY_MODE-USER
" Pretty Print property names
ASSOC_ARRAYS = ABAP_TRUE
CHANGING
DATA = LR_DATA " Data to serialize
).
"HTTP Durum Kodları İçin Değişkenler
DATA : STATUS_CODE TYPE I,
REASON TYPE STRING.
"Gelen Yanıtın HTTP Durum Kodu Alınır
CALL METHOD CLIENT->RESPONSE->GET_STATUS
IMPORTING
CODE = STATUS_CODE " HTTP Status Code
REASON = REASON . " HTTP status description
IF STATUS_CODE EQ 200.
FIELD-SYMBOLS : <LR_RESULT> TYPE ANY TABLE,
<LS_DATA> TYPE ANY,
<LS_DATA2> TYPE ANY,
<LV_RESULT> TYPE ANY,
<LV_RESULT3> TYPE ANY,
<LV_RESULT4> TYPE DATA,
<FS_LINE> TYPE ANY.
FIELD-SYMBOLS: <FS1>.
DATA: GO_STRUCT TYPE REF TO CL_ABAP_STRUCTDESCR,
GT_COMPONENT TYPE ABAP_COMPONENT_TAB.
IF LR_DATA IS BOUND.
DATA : FIELDNAME TYPE CHAR50.
DATA : FIELDVALUE TYPE CHAR60,
INDEX(3) TYPE C.
ASSIGN LR_DATA->* TO <LR_RESULT>.
LOOP AT <LR_RESULT> ASSIGNING <LS_DATA>.
ASSIGN <LS_DATA>->* TO <LS_DATA2>.
IF SY-TABIX EQ 1.
GO_STRUCT ?= CL_ABAP_TYPEDESCR=>DESCRIBE_BY_DATA( <LS_DATA2> ).
GT_COMPONENT = GO_STRUCT->GET_COMPONENTS( ).
ENDIF.
CLEAR : GT_DATA.
LOOP AT GT_COMPONENT ASSIGNING FIELD-SYMBOL(<GS_COMPONENT>).
FIELDNAME = <GS_COMPONENT>-NAME.
ASSIGN COMPONENT <GS_COMPONENT>-NAME OF STRUCTURE <LS_DATA2> TO
<LV_RESULT>.
ASSIGN <LV_RESULT>->* TO <LV_RESULT3>.
FIELDVALUE = <LV_RESULT3>.
IF FIELDNAME EQ 'DATE'.
DATA : LV_ISOTIME TYPE STRING.
DATA : LV_TMSTMP TYPE TIMESTAMP.
LV_ISOTIME = |{ FIELDVALUE }Z|.
CALL METHOD CL_XLF_DATE_TIME=>PARSE
EXPORTING
ISO8601 = LV_ISOTIME
RECEIVING
TIMESTAMP = LV_TMSTMP
" UTC Time Stamp in Short Form (YYYYMMDDhhmmss)
.
LV_ISOTIME = |{ LV_TMSTMP TIMESTAMP = ISO TIMEZONE = 'UTC+3' }|
.
FIELDVALUE = LV_ISOTIME.
ENDIF.
ASSIGN <LV_RESULT3> TO <LV_RESULT4>.
ASSIGN COMPONENT FIELDNAME OF STRUCTURE GT_DATA TO <FS1>.
<FS1> = FIELDVALUE.
ENDLOOP.
APPEND GT_DATA.
ENDLOOP.
ENDIF.
IF P_CITY IS NOT INITIAL.
READ TABLE LT_VALUES ASSIGNING FIELD-SYMBOL(<LS_VALUE>)
WITH KEY KEY = P_CITY.
IF SY-SUBRC EQ 0.
DELETE GT_DATA WHERE PROVINCE NP <LS_VALUE>-TEXT.
ENDIF.
ENDIF.
ELSEIF STATUS_CODE EQ '500'.
FIELD-SYMBOLS : <LR_ERRESULT> TYPE ANY,
<LS_ERRDATA> TYPE ANY,
<LS_ERRDATA2> TYPE ANY.
ASSIGN LR_DATA->* TO <LR_ERRESULT>.
ASSIGN COMPONENT 'MESSAGE' OF STRUCTURE <LR_ERRESULT> TO
<LS_ERRDATA>.
ASSIGN <LS_ERRDATA>->* TO <LS_ERRDATA2>.
IF <LS_ERRDATA2> IS NOT INITIAL.
MESSAGE <LS_ERRDATA2> TYPE 'I'.
ENDIF.
ENDIF.
ENDFORM.
FORM DISPLAY_DATA .
"Verinin ALV Ekranına Aktarılması İşlemleri
DATA : GT_FIELCAT TYPE SLIS_FIELDCAT_ALV OCCURS 0 WITH HEADER LINE.
CALL FUNCTION 'REUSE_ALV_FIELDCATALOG_MERGE'
EXPORTING
I_PROGRAM_NAME = SY-REPID
I_INTERNAL_TABNAME = 'GT_DATA'
I_INCLNAME = SY-REPID
I_BYPASSING_BUFFER = 'X'
CHANGING
CT_FIELDCAT = GT_FIELCAT[]
EXCEPTIONS
INCONSISTENT_INTERFACE = 1
PROGRAM_ERROR = 2
OTHERS = 3
.
IF SY-SUBRC <> 0.
* Implement suitable error handling here
ENDIF.
LOOP AT GT_FIELCAT ASSIGNING FIELD-SYMBOL(<GS_FIELDCAT>).
<GS_FIELDCAT>-SELTEXT_S = <GS_FIELDCAT>-FIELDNAME.
<GS_FIELDCAT>-SELTEXT_M = <GS_FIELDCAT>-FIELDNAME.
<GS_FIELDCAT>-SELTEXT_L = <GS_FIELDCAT>-FIELDNAME.
<GS_FIELDCAT>-REPTEXT_DDIC = <GS_FIELDCAT>-FIELDNAME.
ENDLOOP.
DATA : GS_LAYOUT TYPE SLIS_LAYOUT_ALV.
GS_LAYOUT-COLWIDTH_OPTIMIZE = 'X'.
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
EXPORTING
IS_LAYOUT = GS_LAYOUT
IT_FIELDCAT = GT_FIELCAT[]
TABLES
T_OUTTAB = GT_DATA[]
* EXCEPTIONS
* PROGRAM_ERROR = 1
* OTHERS = 2
.
IF SY-SUBRC <> 0.
* Implement suitable error handling here
ENDIF.
ENDFORM.