无SAP Gateway时,SICF构建REST服务的GET请求参数(含if_http_extension)使用咨询
Alright, I’ve been in your shoes before—building REST services via SICF when Gateway isn’t an option can feel a bit manual, but it’s totally doable. Let’s walk through how to extract and use GET parameters (including filter-style queries) in your IF_HTTP_EXTENSION~HANDLE_REQUEST method.
1. Extract GET Query Parameters First
All your GET request parameters (whether they’re simple import params like ?id=123 or filter-style ones like ?$filter=status eq 'ACTIVE') live in the request’s query string. You can pull them directly using the HTTP server object:
METHOD if_http_extension~handle_request. DATA(lo_request) = server->request. " Option 1: Get all parameters as a key-value pair table DATA(lt_query_params) = lo_request->get_form_fields( ). " Loop through the table if you need to process multiple params LOOP AT lt_query_params INTO DATA(ls_param). CASE ls_param-name. WHEN 'id'. DATA(lv_entity_id) = ls_param-value. WHEN '$filter'. DATA(lv_filter_string) = ls_param-value. ENDCASE. ENDLOOP. " Option 2: Get a single parameter directly (faster for known params) DATA(lv_direct_id) = lo_request->get_query_field( name = 'id' ). DATA(lv_direct_filter) = lo_request->get_query_field( name = '$filter' ). ENDMETHOD.
2. Process Filter Logic (Simulate OData-Style $filter)
If you’re aiming for OData-like filter behavior, you’ll need to parse the filter string and translate it into ABAP logic. Here’s a basic example (you can expand this for more complex operators like gt, contains, etc.):
" Assume we're querying a custom table ZEMPLOYEE DATA(lt_employees) = VALUE zemployee( ). IF lv_filter_string IS NOT INITIAL. " Simple split for a basic filter like "status eq 'ACTIVE'" SPLIT lv_filter_string AT ' eq ' INTO DATA(lv_filter_field) DATA(lv_filter_value). " Clean up quotes if present lv_filter_value = lv_filter_value+1( STRLEN(lv_filter_value) - 2 ). " Safe dynamic WHERE clause (avoid SQL injection!) DATA(lv_where_clause) = |{ lv_filter_field } = @lv_filter_value|. SELECT * FROM zemployee INTO TABLE lt_employees WHERE (lv_where_clause). ELSE. " No filter? Return all records SELECT * FROM zemployee INTO TABLE lt_employees. ENDIF.
Pro Tip: For more robust filter parsing, use
CL_ABAP_DYN_PRGto validate field names and build safe dynamic statements—this prevents SQL injection risks.
3. Return the Processed Data as JSON
Since it’s a REST service, you’ll want to return JSON. Use SAP’s built-in JSON serializer to convert your internal table to a JSON string:
" Serialize the internal table to JSON DATA(lo_json_serializer) = cl_trex_json_serializer=>create( lt_employees ). lo_json_serializer->serialize( ). DATA(lv_json_response) = lo_json_serializer->get_json( ). " Set response headers and content server->response->set_content_type( 'application/json' ). server->response->set_status( code = 200 reason = 'OK' ). server->response->set_cdata( lv_json_response ).
4. Best Practices to Avoid Headaches
- Validate Parameters: Always check if incoming params are valid (e.g., numeric IDs should only contain digits). Return a 400 Bad Request if something’s off:
IF lv_entity_id IS NOT INITIAL AND lv_entity_id CA '^0-9'. server->response->set_status( code = 400 reason = 'Invalid ID Format' ). server->response->set_cdata( '{"error": "ID must be a numeric value"}' ). RETURN. ENDIF. - Log Everything: Use
server->log_message( )or write to SLG1 to track requests and errors—this saves you hours when debugging. - Handle Edge Cases: What if the filter string is malformed? Add error handling to catch that and return a meaningful error response.
内容的提问来源于stack exchange,提问作者Matthijs Mennens

