Skip to main content

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:

RPC Dispatch
Mobile Client
Sends RPC request — service: "MYSERVICE", bundle: "<guid>"
|v
MobileRPCRegistry220FDW
Queries Service Registry table — filters by service code + bundle ID
Reads Codeunit Id from the matching record
Fires OnResolveService(CU Id) — your subscriber sets the Service interface
Calls ServiceHandler.RPC(State)
|v
Your AL Codeunit (implements IBCRPC220FDW)
Handles the request, returns response JsonObject
|v
Mobile Client
Receives RPC response

Step by step:

  1. The mobile client sends a JSON-RPC request containing "service": "MYSERVICE" and "bundle": "<guid>" in the params.
  2. MobileRPCRegistry220FDW reads the service code and bundle ID from the request.
  3. It queries the Mobile Service Registry 220FDW table, filtering by App Bundle ID and Mobile Service Code.
  4. If a matching record is found, it reads the Codeunit Id field.
  5. The registry fires the OnResolveService integration event, passing the codeunit ID.
  6. Your event subscriber checks whether the codeunit ID matches, and if so, sets the Service interface parameter to its own instance and sets IsServiceResolved to true.
  7. 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:

FieldTypeDescription
App Bundle IDGuidThe bundle this entry belongs to. References Mobile App Bundle 220FDW.ID. Not editable -- set automatically based on the parent bundle.
Mobile Service CodeCode[50]The unique key sent by the mobile client to trigger this service (for example, RECEIVE, PICK, ITEMSERVICE). Must not be blank.
Codeunit IdIntegerThe 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 NameCode[250]FlowField -- auto-populated with the codeunit's object caption from AllObjWithCaption. Read-only.
App Bundle CodeCode[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

  1. Open Mobile App Bundles in Business Central.
  2. Select the bundle you want to configure (it must be in Dev or Test status).
  3. Navigate to Mobile Service Setup.
  4. 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.
  5. The Handler Name column auto-populates with the codeunit name.

Example Configuration

Mobile Service CodeCodeunit IdHandler Name
ITEMSERVICE50100ItemService
CUSTOMERSERVICE50101CustomerServiceFDW
SALESORDERSERVICE50102SalesOrderService
WAREHOUSESERVICE50103WarehouseService

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 CodeunitId against your own codeunit's object ID using the Codeunit:: syntax.
  • Set both Service and IsServiceResolved when there is a match.

Bundle Scoping

Service registry entries are scoped to a bundle. This means:

  • Different bundles can map ITEMSERVICE to 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, and OnDelete triggers all call CheckBundleNotLocked.

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:

  1. Open the bundle's Mobile Service Setup page.
  2. Verify that an entry exists for the service code used in your page JSON.
  3. 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:

  1. Confirm the codeunit exists and is published to the environment.
  2. Verify the codeunit has an [EventSubscriber] for OnResolveService.
  3. Check that the CodeunitId comparison in the subscriber matches the actual codeunit object ID.
  4. 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.