Coder Absolute
Coder Absolute

Reputation: 6367

Struggling to configure multiple routes

The /v1/Tenants/{TenantId} Route is working but /v1/Tenants/{TenantName} route is not working, am not sure what is wrong? Also, is this a proper way to design or have the filter criteria?

//Request DTO
[Route("/v1/Tenants/{TenantName}", "GET")]
public class TenantRequestByTenantName: IReturn<TenantResponse>
{
    public string TenantName { get; set; }
}

//Request DTO
[Route("/v1/Tenants/{TenantId}", "GET")]
public class TenantRequestById : IReturn<TenantResponse>
{
    public int? TenantId { get; set; }
}

//Response DTO
public class TenantResponse
{
    public ITenantEntity Result { get; set; }
    public ResponseStatus ResponseStatus { get; set; }
}

public class RestaurantService : Service
{
    public object Any(TenantRequestById request)
    {
        return this.GetTenant(request);
    }

    public object Any(TenantRequestByTenantName request)
    {
        return this.GetTenant(request);
    }

    private object GetTenant(object whereConditions)
    {
        return new TenantResponse
        {
            Result = new TenantManager().GetRow(whereConditions)
        };
    }
}

Upvotes: 1

Views: 74

Answers (1)

mythz
mythz

Reputation: 143399

The routes are ambiguous as both routes handle the same route, i.e:

/v1/Tenants/xxx

You either need to have separate routes, e.g:

[Route("/v1/tenants/{TenantId}")]
public class TenantRequestById { ... }

[Route("/v1/tenants/by-name/{TenantName}")]
public class TenantRequestByTenantName { ... }

Or you could have a single Service that handles both requests depending if it's an integer or not as done in TechStacks:

[Route("/technology/{Slug}")]
public class GetTechnology : IReturn<GetTechnologyResponse>
{
    public string Slug { get; set; }

    public long Id
    {
        set { this.Slug = value.ToString(); }
    }
}

The Id overload allows your typed clients to have the ideal API, e.g:

var response = client.Get(GetTechnology { Id = 1 });

var response = client.Get(GetTechnology { Slug = "servicestack" });

Then in your Service Implementation you can check whether Slug is an integer Id or not to select the appropriate query, e.g:

public object Get(GetTechnology request)
{
    int id;
    var tech = int.TryParse(request.Slug, out id)
        ? Db.SingleById<Technology>(id)
        : Db.Single<Technology>(x => x.Slug == request.Slug.ToLower());

    return new GetTechnologyResponse {
        Result = tech,
    };
}

Upvotes: 2

Related Questions