Publicar un servicio web SOAP en SAP: del módulo de funciones al WSDL
Convertir un módulo de funciones habilitado para RFC en un servicio web SOAP, configurar el binding en SOAMANAGER, obtener el WSDL y probarlo, con las herramientas de monitorización para cuando algo falla.
OData y REST se llevan toda la atención, pero en los proyectos reales SOAP sigue en todas partes: bancos, operadores logísticos, portales de la administración y middleware antiguo suelen pedir un WSDL. La buena noticia: en un sistema SAP ABAP, publicar un servicio SOAP a partir de un módulo de funciones existente lleva unos quince minutos.
Vamos a crear un pequeño servicio que devuelve los datos básicos de un material a partir de su número.
Es la vía clásica on-premise (S/4HANA o ECC). Para desarrollos nuevos en ABAP Cloud, mejor OData/RAP; en S/4HANA Cloud, los servicios SOAP se ofrecen mediante communication arrangements.
1. Un módulo de funciones habilitado para RFC
Los servicios web generados desde un módulo de funciones (inside-out) requieren un módulo habilitado para RFC. Todos los parámetros deben pasarse por valor.
Primero, una estructura para el resultado:
@EndUserText.label : 'Material info for web service'
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
define structure zs_ws_material_info {
matnr : matnr;
maktx : maktx;
mtart : mtart;
matkl : matkl;
meins : meins;
}
Después, el módulo de funciones (SE37 o ADT). En Atributos, marca Remote-Enabled Module:
FUNCTION z_ws_get_material_info
IMPORTING
VALUE(iv_matnr) TYPE matnr
VALUE(iv_language) TYPE spras DEFAULT sy-langu
EXPORTING
VALUE(es_material) TYPE zs_ws_material_info
VALUE(ev_message) TYPE bapi_msg.
" Remote-enabled module (SE37 → Attributes → Remote-Enabled Module).
" All parameters are passed by value – required for RFC and web services.
DATA matnr TYPE matnr.
" The caller sends the external format (e.g. without leading zeros)
CALL FUNCTION 'CONVERSION_EXIT_MATN1_INPUT'
EXPORTING input = iv_matnr
IMPORTING output = matnr
EXCEPTIONS OTHERS = 1.
IF sy-subrc <> 0.
ev_message = |Invalid material number { iv_matnr }|.
RETURN.
ENDIF.
SELECT SINGLE FROM mara AS m
LEFT OUTER JOIN makt AS t ON t~matnr = m~matnr
AND t~spras = @iv_language
FIELDS m~matnr, t~maktx, m~mtart, m~matkl, m~meins
WHERE m~matnr = @matnr
INTO CORRESPONDING FIELDS OF @es_material.
IF sy-subrc <> 0.
ev_message = |Material { iv_matnr } not found|.
ENDIF.
ENDFUNCTION.
Dos detalles que ahorran tiempo después:
- Devuelve un campo de mensaje en lugar de lanzar excepciones: los clientes SOAP manejan mucho mejor un campo informado que un SOAP fault por «no encontrado».
- Aplica tú mismo las conversion exits (aquí
MATN1): quien llama envía el formato externo.
2. Crear la definición de servicio
En SE37: Utilities → More Utilities → Create Web Service → From the Function Module (o en SE80: Create → Enterprise Service). El asistente pide:
- Nombre de la definición de servicio: por ejemplo
ZWS_MATERIAL_INFOy una descripción. - Endpoint: nuestro módulo de funciones. Desmarca Map Name si quieres que los elementos se llamen exactamente
IV_MATNR,ES_MATERIAL. - Perfil SOAP: el nivel de seguridad del servicio.
- Paquete y orden de transporte.
Recomiendo usuario y contraseña con garantía de transporte: autenticación solo por HTTPS. Al final, activa la definición de servicio.
3. Crear el binding en SOAMANAGER
La definición solo describe la interfaz. Para poder llamarla necesitas un binding (endpoint):
- Ejecuta la transacción SOAMANAGER (se abre en el navegador).
- Service Administration → Web Service Configuration, busca
ZWS_MATERIAL_INFO. - En la pestaña Configurations, pulsa Create Service e introduce un nombre de servicio y de binding.
- Seguridad: Transport Guarantee = HTTPS, Authentication = User ID/Password.
- Guarda: el binding queda activo al momento.
Con Open Binding WSDL Generation obtienes la URL del WSDL. Ese es el enlace que envías al socio.
4. Probar el servicio
Importa el WSDL en SoapUI (o Postman), configura la autenticación básica y envía una petición:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:urn="urn:sap-com:document:sap:rfc:functions">
<soapenv:Header/>
<soapenv:Body>
<urn:Z_WS_GET_MATERIAL_INFO>
<IV_MATNR>MAT-1000</IV_MATNR>
</urn:Z_WS_GET_MATERIAL_INFO>
</soapenv:Body>
</soapenv:Envelope>
La respuesta:
<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
<soap-env:Header/>
<soap-env:Body>
<n0:Z_WS_GET_MATERIAL_INFOResponse xmlns:n0="urn:sap-com:document:sap:rfc:functions">
<ES_MATERIAL>
<MATNR>MAT-1000</MATNR>
<MAKTX>Laptop 14 Developer Edition</MAKTX>
<MTART>HAWA</MTART>
<MATKL>IT01</MATKL>
<MEINS>ST</MEINS>
</ES_MATERIAL>
<EV_MESSAGE/>
</n0:Z_WS_GET_MATERIAL_INFOResponse>
</soap-env:Body>
</soap-env:Envelope>
Quien llama necesita un usuario SAP autorizado para el servicio: objeto S_SERVICE (y S_RFC para el grupo de funciones). Un usuario de sistema o de comunicación con un rol acotado es la solución limpia.
5. Cuando algo falla
| Síntoma | Dónde mirar |
|---|---|
| HTTP 401 / 403 | Usuario, contraseña, autorizaciones S_SERVICE / S_RFC (SU53) |
| HTTP 404 | Falta el binding o el nodo SICF /sap/bc/srt/ está inactivo |
| HTTP 500 / SOAP fault | Transacción SRT_UTIL: log de errores y traza de payload |
| Valores erróneos o vacíos | Conversion exits, opción Map Name, parámetro de idioma |
En SRT_UTIL puedes activar una traza de payload para un usuario durante un tiempo limitado: la forma más rápida de ver qué se envió realmente.
Resumen
- Módulo de funciones habilitado para RFC, parámetros por valor, mensajes en lugar de excepciones.
- Definición de servicio con el asistente, perfil de seguridad con HTTPS.
- Binding en SOAMANAGER, URL del WSDL para el socio.
- Prueba en SoapUI, análisis con SRT_UTIL.
SOAP no es vistoso, pero es fiable; con estos pasos, un socio que «necesita un WSDL» ya no es motivo de preocupación.
Comentarios