Lost with AdminUsersFeature

Apologies, I’m trying to get my head around the AdminUsersFeature and I’m getting more lost by the minute!

I have added the feature and wanted to try it out via a HTTP call. I’m trying to call from an Angular app and I’m attempting to do a basic retrieval of a single user using AdminGetUser with an ID of 1, however I’m not entirely sure where I should be sending the GET request to?

Have I got the wrong end of the stick?

I’m not sure what’s being asked, the Admin User Services are just normal ServiceStack Services for managing Users that require an Admin User to access, which you can call using the Service Clients as normal, e.g:

var response = client.Get(new AdminGetUser { Id = userId });

If it helps, the AdminUsersFeatureTests.cs contains some tests that does this.

1 Like

Where can he find the URL used to call the service? Not everyone will call from C# or use the provided SS clients. Most probably use fetch or axios or something, and in the spirit of REST I honestly think the URLs etc. should be easier to find, too many examples are using the SS clients (w. DTO for req/res, but in practice many will build GET and POST requests w. request params and body).

I guess looking at the /metadata page is helpful. I could not find any Route attribute on the Auth DTOs i SS’s source code.

It had been a long day coding! You basically call the pre-defined route for this service. I worked this out by using the SS client and then checking the raw request.

The pre-defined routing is described here:

So in my case of using AdminGetUser, you would call /json/reply/AdminGetUser?id=X with your HTTP client.

Custom user-defined routes for built-in Services are typically defined on the Request DTO if it exists, unless they’re configurable in which case they’ll be configurable on the plugin which registers the Service, by convention we use ServiceRoutes collection.

In this case there is no custom user-defined route so the API is only accessible on the pre-defined Route as @ikaney mentions. e.g. for JSON endpoint its /json/reply/{RequestName} which is what all Service Clients (other than .NET which has access to the [Route] metadata attributes) would use.

When in doubt you can always find the route with Reverse Routing extension methods from an instance of the Request DTO, e.g:

var relativeUrl = requestDto.ToGetUrl();
var absoluteUrl = requestDto.ToAbsoluteUri();

Yes you could also visit the /metadata page to discover it, but if you know the pre-defined route convention you don’t need to.

Sorry for being overly critical, but since this is on the customer forum and not SO, I’m taking the liberty.

I do think it is cumbersome to have to use the client “sniff” the URLs being used, if using something else than the pre made client. That makes me think some doc is missing or hard to find. Kudos on the new doc site, that means this is in focus.

I must say the standard endpoint is very strange. /json/reply/something … it’s just so strange IMHO. At least for auth service the URL’s are more like /auth/Credentials if I remember correctly.

The pre-defined routes are a transparent detail that’s fundamental in enabling ServiceStack’s rich end-to-end typed ecosystem that’s natively supported in multiple languages. It’s one of the few frameworks in existence which lets you build an entire end-to-end API without code-gen, where you can use your DTOs as-is in client .NET projects, where you don’t need to spend additional dev effort to define an additional layer of user-defined routes which is both prone to human error forcing devs to manually craft URLs and lacks type safety for knowing when Routes change which potentially relegate issues into production runtime errors.

Basically, pre-defined routes are much better for maintaining automated machinery around APIs. You would define custom user-defined routes when you want to document APIs for public consumption.

The reason they don’t exist for the Admin Users APIs is because they’re not supposed to be client facing APIs that you would expose to your customers. Their primarily purpose is to enable ServiceStack Studio’s User Management UI: https://docs.servicestack.net/studio-users

Should they prove useful you can use them to enable your own automation around your System User Management. These are primarily back office functions that you should be using their end-to-end typed Service Clients for. If you want to invoke them from the command-line you can use the Post Command Utils which again are much simpler than relying on humans URL hacking & constructing exact HTTP Request each different HTTP API needs, instead to call any ServiceStack API you can just specify the API name and a Request Body defined using a JS object literal, the same consistent method is able to call any API. You can also use curl if you wish, where pre-defined routes would still be able to save you time from having to constantly consult API docs instead of being able to predetermine the pre-defined URL of each API.

Had the Admin User APIs been intended for public consumption they would’ve been annotated with user-defined routes, but as managing users is a common feature for systems to have, any routes we would have chosen would’ve had a strong chance of conflict. So we don’t define them since they’re unnecessary for what the APIs are needed for and instead prefix every Service with Admin* prefix convention so they’re clearly differentiated from your own APIs of similar function.

The only question I really have is, what’s your use-case that you would prefer to call these APIs using custom URL & generic HTTP Client instead of using the typed Service Clients?

Thanks for this thorough answer. It clears up a lot, such as that the mentioned APIs are actually meant for Studio only.

To answer your question about not using the SS client. I’m using axios and am happy with that. Most tutorials use it. So I’m using it. I had the impression the SS client was Typescript only, and I’m using JavaScript, untyped. Maybe it’s not a rational answer, and SS client is something I should check out, although one thing I like about REST APIs is that you can use whatever language/client library you want, and in some way that ensures loose coupling I think. Using SS on both ends kind of felt like using MS on both sides. It all works, but suddenly I know less about what’s going on.

Ok, so perhaps not very rational answer, but that’s the only answer I have. Used axios/fetch and liked it. It is also very easy to use Postman to check out the APIs when I know what the API wants (being able to hand craft URLs/params/post-body in Postman for example).

You don’t need to waste time answering this, I just felt your answer deserved an answer.

They should also be useful for being able to programmatically managing user accounts through back-office functions which by default are restricted to Admin Users only.

The @servicestack/client is built with TypeScript but can also easily be used from JavaScript and is how the Empty https://web.web-templates.io uses for its Hello World example which uses the embedded /js/servicestack-client.js in ServiceStack.dll saving the external dependency.

It’s even nicer in pure JavaScript npm projects which have the same syntax as TypeScript

import { JsonServiceClient } from '@servicestack/client'
import { Hello } from './dtos'

const client = new JsonServiceClient()

const response = await client.get(new Hello({ name }))

Right, which you can also do with all ServiceStack APIs as they return your pure (unaltered) serialized Response DTOs over HTTP which are more capable since all APIs can be populated with any combination of its Route /path/info, QueryString or FormData, including support for Complex Type Properties without any additional effort.

We certainly also recommend designing RESTful APIs by annotating all your public APIs with logical routes so they’re accessible from Pretty URL permalinks, even if they’re not used they provided additional documentation and context to describe what each API does, for the exact reasons you mention where it’s easier to navigate with API explorers like Postman, which we also do for all our public APIs, e.g. https://techstacks.io/swagger-ui/#/Posts

Right, you’re able to get by knowing less because all the complexity about how to call an API is encapsulated within its native typed end-to-end Service Clients in most popular languages, it’s a value-added area we heavily focus on because it’s what adds the most value to your System APIs since it requires the least effort for your API consumers to call which they can do natively from their preferred language.

So I agree it’s useful for all public APIs to also be annotated with user-defined routes, they’re not for the Admin User APIs because they’re not intended to be public, it’s also not where the best value of your APIs lie, but they’re still certainly useful & highly recommended for documenting public APIs.

1 Like