Service Registry
The Service Registry maps service codes used in mobile page JSON to the AL codeunits that handle the business logic. It is stored in the Mobile Service Registry 220FDW table and is the bridge between the UI layer and your server-side AL code.
How RPC Dispatch Works
When the mobile client sends an RPC request, the MobileRPCRegistry220FDW codeunit dispatches it. Two built-in methods -- GetPageFlow and GetUserInformation -- are handled directly by the registry codeunit. All other method calls go through the service registry lookup:
service: "MYSERVICE", bundle: "<guid>"Codeunit Id from the matching recordOnResolveService(CU Id) — your subscriber sets the Service interfaceServiceHandler.RPC(State)response JsonObjectStep by step:
- The mobile client sends a JSON-RPC request containing
"service": "MYSERVICE"and"bundle": "<guid>"in the params. MobileRPCRegistry220FDWreads the service code and bundle ID from the request.- It queries the
Mobile Service Registry 220FDWtable, filtering byApp Bundle IDandMobile Service Code. - If a matching record is found, it reads the Codeunit Id field.
- The registry fires the
OnResolveServiceintegration event, passing the codeunit ID. - Your event subscriber checks whether the codeunit ID matches, and if so, sets the
Serviceinterface parameter to its own instance and setsIsServiceResolvedtotrue. - The registry calls
ServiceHandler.RPC(State)on the resolved interface, which returns the response.
Table Structure
The Mobile Service Registry 220FDW table has the following fields:
| Field | Type | Description |
|---|---|---|
| App Bundle ID | Guid | The bundle this entry belongs to. References Mobile App Bundle 220FDW.ID. Not editable -- set automatically based on the parent bundle. |
| Mobile Service Code | Code[50] | The unique key sent by the mobile client to trigger this service (for example, RECEIVE, PICK, ITEMSERVICE). Must not be blank. |
| Codeunit Id | Integer | The object ID of the AL codeunit that handles this service. The codeunit must implement IBCRPC220FDW. Uses a table relation to AllObjWithCaption filtered to codeunit objects, so you can use the lookup to browse available codeunits. |
| Handler Name | Code[250] | FlowField -- auto-populated with the codeunit's object caption from AllObjWithCaption. Read-only. |
| App Bundle Code | Code[20] | FlowField -- auto-populated with the bundle's code. Read-only. |
Primary Key
The primary key is a composite of App Bundle ID + Mobile Service Code. This means:
- A service code must be unique within a single bundle.
- Different bundles can map the same service code to different codeunits.
Adding a Service Entry
- Open Mobile App Bundles in Business Central.
- Select the bundle you want to configure (it must be in Dev or Test status).
- Navigate to Mobile Service Setup.
- Add a new line:
- Mobile Service Code -- enter the code your page JSON uses in the
"service"field (for example,ITEMSERVICE). - Codeunit Id -- enter the codeunit object ID or use the lookup to select it. The codeunit must implement
IBCRPC220FDW.
- Mobile Service Code -- enter the code your page JSON uses in the
- The Handler Name column auto-populates with the codeunit name.
Example Configuration
| Mobile Service Code | Codeunit Id | Handler Name |
|---|---|---|
ITEMSERVICE | 50100 | ItemService |
CUSTOMERSERVICE | 50101 | CustomerServiceFDW |
SALESORDERSERVICE | 50102 | SalesOrderService |
WAREHOUSESERVICE | 50103 | WarehouseService |
Mapping Service Names in Page JSON to Codeunits
In your mobile page JSON, every page that needs server-side data specifies a "service" property:
{
"pageID": "CUSTOMER-LIST",
"service": "CUSTOMERSERVICE",
"type": "list",
"title": "Customers",
...
}
At runtime, when this page triggers an RPC call, the request includes "service": "CUSTOMERSERVICE" and the bundle GUID. The registry uses these two values as a composite lookup key to find the matching Mobile Service Registry 220FDW record and retrieve the Codeunit Id.
The service code is case-insensitive because the field type is Code[50] (Business Central automatically uppercases Code fields).
Codeunit Requirements
The codeunit referenced in the service registry must satisfy two requirements:
1. Implement IBCRPC220FDW
The codeunit must implement the IBCRPC220FDW interface, which defines the RPC method:
codeunit 50101 CustomerServiceFDW implements IBCRPC220FDW
{
procedure RPC(State: Codeunit MobileRPCState220FDW) ResponseJson: JsonObject
begin
// Handle the RPC request and return a JSON response
end;
}
2. Subscribe to OnResolveService
The codeunit must include an event subscriber for the OnResolveService event on MobileRPCRegistry220FDW. This subscriber is how the runtime discovers your implementation:
[EventSubscriber(ObjectType::Codeunit, Codeunit::MobileRPCRegistry220FDW,
OnResolveService, '', false, false)]
local procedure HandleResolve(
CodeunitId: Integer;
var Service: Interface IBCRPC220FDW;
var IsServiceResolved: Boolean)
begin
if IsServiceResolved then
exit;
if CodeunitId = Codeunit::CustomerServiceFDW then begin
Service := this;
IsServiceResolved := true;
end;
end;
Key points:
- Always check
if IsServiceResolved then exit;first -- another subscriber may have already claimed this codeunit ID. - Compare
CodeunitIdagainst your own codeunit's object ID using theCodeunit::syntax. - Set both
ServiceandIsServiceResolvedwhen there is a match.
Bundle Scoping
Service registry entries are scoped to a bundle. This means:
- Different bundles can map
ITEMSERVICEto completely different codeunits. - Copying a bundle copies all its service registry entries to the new bundle.
- When a bundle is locked (Production or Archive status), its service registry entries cannot be added, modified, or deleted. The table's
OnInsert,OnModify, andOnDeletetriggers all callCheckBundleNotLocked.
Debugging Tips
"Service 'X' is not configured for bundle 'Y'"
This error means the Mobile Service Registry 220FDW table has no record matching the given service code and bundle ID.
Resolution:
- Open the bundle's Mobile Service Setup page.
- Verify that an entry exists for the service code used in your page JSON.
- Check for typos -- the service code in the JSON must exactly match the Mobile Service Code field (case does not matter since both are uppercased).
"No service implementation found for Codeunit ID X (Service: Y)"
The registry found the service entry and the codeunit ID, but the OnResolveService event fired and no subscriber claimed it.
Resolution:
- Confirm the codeunit exists and is published to the environment.
- Verify the codeunit has an
[EventSubscriber]forOnResolveService. - Check that the
CodeunitIdcomparison in the subscriber matches the actual codeunit object ID. - If you recently changed the codeunit ID, update the service registry entry to match.
"Invalid request: Missing 'bundle' in params" / "Missing 'service' in params"
The RPC request JSON is missing required fields. This typically indicates a client-side issue -- the page JSON may not have a "service" property, or the mobile app is not passing the bundle GUID correctly.
Using Request Logging for Service Debugging
Enable Request Logging on the Mobile Setup page to capture the full request and response JSON for every RPC call. In the Mobile Request Logs page, you can inspect:
- The Mobile Service Code column to confirm which service handled (or failed to handle) the request.
- The Request Json blob to see the exact payload the client sent.
- The Error Message and Error Call Stack fields for failed calls.
See Mobile Setup for details on enabling request logging.