Development Tip: Service Override

There is often a time when we need to slightly modify an upstream service such as one in mantle-usl, or another Moqui component. One handy trick for doing so is to do a service override. If you have a component that depends on the component that contains the service you need, then in your services directory, you can override the service by create a file with the same path as the upstream service that contains a service with the same name.

For example: I need to override the https://github.com/moqui/mantle-usl/blob/31788226680b4a51c37ea01d4654ecf1389717c9/service/mantle/party/PartyServices.xml#L287 service. So, in my component that has a component.xml that looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<component xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://moqui.org/xsd/moqui-conf-3.xsd" name="my-component" version="1.0.0">
    <depends-on name="mantle-usl"/>
</component>

I then create a file in my-component/service/mantle/party called PartyServices.xml that contains:

<?xml version="1.0" encoding="UTF-8"?>
<services xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://moqui.org/xsd/service-definition-3.xsd">

    <service verb="get" noun="PartyOrganizationInfo">
        <in-parameters><parameter name="partyId" default="ec.user.userAccount?.partyId"/></in-parameters>
        <out-parameters>
            <parameter name="activeOrgId"/>
            <parameter name="userOrgIds" type="List"><parameter name="userOrgId"/></parameter>
            <parameter name="filterOrgIds" type="List"><parameter name="userOrgId"/></parameter>
        </out-parameters>
        <actions>
            <log level="warn" message="Successfully overrided service!"/>
        </actions>
    </service>
</services>

I forgot how to do this, and had to look up how to do it, so I figured I would create a post. Hopefully this is useful!

4 Likes

Is this trick simply override the original service? Or sometimes we need not only to override it, but actually extend it. Is it possible to call the original service in this new overriding service? Maybe for this extending needs, we dont need this overriding trick, instead we just write a new service?

Iā€™m sure there are scenarios where doing this is needed / useful, maybe you want to alter the behavior of a RESTful end-point that many clients depend on for example.

When that is not case, I find the cleanest thing to do is just to create a new service that <implements .../> the overridden one, calls it, and adds whatever behavior needed.