Murphy4
Murphy4

Reputation: 1531

How to override IdentityUserAppService in abp.io without duplicating endpoints?

I am using abp.io 4.4 (https://docs.abp.io/en/abp/latest) and want to write my own class to replace the IdentityUser AppService with an extended child, exactly as described in the abp.io docs.

When I do, all the original endpoints exist, even though I am trying to replace them with my new app service. How do I prevent the /api/identity endpoints from being generated?

I am not interested in just removing them from swagger, I am hoping to fix this at the sourfce if it is possible.

Details of issue:

Before coding anything beyond the default downloaded backend application, when swagger loads, I can see my list of endpoints as expected:

GET
​/api​/identity​/users​/{id}

PUT
​/api​/identity​/users​/{id}

DELETE
​/api​/identity​/users​/{id}

GET
​/api​/identity​/users

POST
​/api​/identity​/users

GET
​/api​/identity​/users​/{id}​/roles

PUT
​/api​/identity​/users​/{id}​/roles

GET
​/api​/identity​/users​/assignable-roles

GET
​/api​/identity​/users​/by-username​/{userName}

GET
​/api​/identity​/users​/by-email​/{email}

Once I add the new file UserAppService.cs as described in the docs:

    /// <summary>
    /// Extension of the IdentityUserAppService.
    /// </summary>
    /// <seealso cref="IdentityUserAppService" />
    [Dependency(ReplaceServices = true)]
    [ExposeServices(typeof(IIdentityUserAppService), typeof(IdentityUserAppService), typeof(UserAppService))]

    public class UserAppService : IdentityUserAppService
    {
        public UserAppService(
            IdentityUserManager userManager,
            IIdentityUserRepository userRepository,
            IIdentityRoleRepository roleRepository,
            IOptions<IdentityOptions> identityOptions)
            : base(
                  userManager,
                  userRepository,
                  roleRepository,
                  identityOptions)
        {
        }

        public async Task<List<IdentityUserDto>> GetEntireCollectionAsync() => this.ObjectMapper.Map<List<Volo.Abp.Identity.IdentityUser>, List<IdentityUserDto>>(await this.UserRepository.GetListAsync());
    }

The swagger endpoints under User are now:

GET
​/api​/identity​/users​/{id}

PUT
​/api​/identity​/users​/{id}

DELETE
​/api​/identity​/users​/{id}

GET
​/api​/identity​/users

POST
​/api​/identity​/users

GET
​/api​/identity​/users​/{id}​/roles

PUT
​/api​/identity​/users​/{id}​/roles

GET
​/api​/identity​/users​/assignable-roles

GET
​/api​/identity​/users​/by-username​/{userName}

GET
​/api​/identity​/users​/by-email​/{email}

GET
​/api​/app​/user​/entire-collection

GET
​/api​/app​/user​/{id}

PUT
​/api​/app​/user​/{id}

DELETE
​/api​/app​/user​/{id}

GET
​/api​/app​/user

POST
​/api​/app​/user

GET
​/api​/app​/user​/{id}​/roles

PUT
​/api​/app​/user​/{id}​/roles

GET
​/api​/app​/user​/assignable-roles

POST
​/api​/app​/user​/find-by-username

POST
​/api​/app​/user​/find-by-email

Is there something wrong with my decorators, or is this expected behavior? Is there a way around it?

Upvotes: 0

Views: 1492

Answers (1)

Obaida Alhassan
Obaida Alhassan

Reputation: 601

I encountered a similar issue with extending TenantAppService and tried multiple things but non of them worked, I ended up adding the attribute [RemoteService(IsEnabled = false)] for the extended AppService, and inherited from the class I want to extend 'for my case TenantAppService` and it worked.

RemoteServiceAttributeDoc

Code:

[RemoteService(IsEnabled = false)]
[Dependency(ReplaceServices = true)]
[ExposeServices(typeof(ITenantAppService), typeof(Volo.Abp.TenantManagement.TenantAppService))]
public class TenantAppService : Volo.Abp.TenantManagement.TenantAppService
{
    public TenantAppService(ITenantRepository tenantRepository, ITenantManager tenantManager, IDataSeeder dataSeeder, IDistributedEventBus distributedEventBus)
        : base(tenantRepository, tenantManager, dataSeeder, distributedEventBus)
    {
    }

    public override Task UpdateDefaultConnectionStringAsync(Guid id, string defaultConnectionString)
    {
        var str = defaultConnectionString;
        return base.UpdateDefaultConnectionStringAsync(id, defaultConnectionString);
    }
}

Before disabling remote service swagger:

Tenant


GET
/api/multi-tenancy/tenants/{id}


PUT
/api/multi-tenancy/tenants/{id}


DELETE
/api/multi-tenancy/tenants/{id}


GET
/api/multi-tenancy/tenants


POST
/api/multi-tenancy/tenants


GET
/api/multi-tenancy/tenants/{id}/default-connection-string


PUT
/api/multi-tenancy/tenants/{id}/default-connection-string


DELETE
/api/multi-tenancy/tenants/{id}/default-connection-string


GET
/api/app/tenant/{id}


PUT
/api/app/tenant/{id}


DELETE
/api/app/tenant/{id}


GET
/api/app/tenant


POST
/api/app/tenant


GET
/api/app/tenant/{id}/default-connection-string


PUT
/api/app/tenant/{id}/default-connection-string


DELETE
/api/app/tenant/{id}/default-connection-string

After disabling remote service swagger:

Tenant


GET
/api/multi-tenancy/tenants/{id}


PUT
/api/multi-tenancy/tenants/{id}


DELETE
/api/multi-tenancy/tenants/{id}


GET
/api/multi-tenancy/tenants


POST
/api/multi-tenancy/tenants


GET
/api/multi-tenancy/tenants/{id}/default-connection-string


PUT
/api/multi-tenancy/tenants/{id}/default-connection-string


DELETE
/api/multi-tenancy/tenants/{id}/default-connection-string

Upvotes: 1

Related Questions