RESTful design for accessing the same resource in different formats from different audiences - rest

Use case
I am building a webshop where people can register/sign in and can purchase (and afterwards manage) their SaaS licenses. For this purpose I created (among others) the following REST endpoints:
// Lists all licenses which are linked to this user
r.Get("/users/{userID}/licenses", api.LicenseSvc.HandleGetLicenses())
// List details (such as purchase date, seat information, ...) for a given licenseID
r.Get("/users/{userID}/licenses/{licenseID}", api.LicenseSvc.HandleGetLicense())
// Creates a new license for the signed in user
r.Post("/users/{userID}/licenses", api.LicenseSvc.HandleCreateLicense())
// Each license has a limited number of seats. The license manager can free up seats to make room for others
r.Delete("/users/{userID}/licenses/{licenseID}/seats/{seatID}", api.LicenseSvc.HandleDeleteSeat())
The above endpoints are only supposed to be used in the webshop/license management panel. At the same time the same service has to serve endpoints for the SaaS products which actually use the license(s) a user has created/purchased before. This SaaS product needs different endpoints such as:
An endpoint to check at startup whether a given license is valid at all
An endpoint which also gets the license by ID (see above), but it should only return a subset of the license resource (e. g. it shouldn't return the date when the license was purchased)
My question
Due to the fact that I am building one REST API which is consumed by two different "audiences" (on the one hand the license manager/customer and on the other hand the SaaS software) I feel like I am running into conflicts.
The authentication of both audiences is different, both audiences want to access the same kind of resource (e. g. a license) but the resource "format" (no customer sensitive data for the SaaS requester) should be different depending on the audience.
Should this be reflected via different REST URLs or should I handle all that logic inside of my route handlers?
Should I even create two different services serving these different audiences? Like one API for the userpanel/license management and one for the SaaS products!?

REST is not very well prepared for these multi-client scenarios. i have seen many REST apis where certain attributes of resources will only be filled under certain circumstances where i find that perfectly fine. however i have also seen many examples of multiple use cases bunched into single resource models where the swagger documentation with its limiting structure terribly fails to communicate the purpose of each field.
so: as long as the use cases do not differ too much, i would try to keep the count of endpoints low.
tip: have a look at GraphQL, it is much better equipped for handling such cases with querying only for certain sets or even only asking for certain fields, putting the client in control. however using GraphQL as the primary interface is still somewhat exotic and comes with quite substantial initial cost compared to the plentiful REST infrastructure available. still worth it.

Related

Keycloak users - is a good idea to differentiate users by their country?

I'm designing a fairly complex backend and now I have a doubt. Is a good idea in Keycloak to differentiate users in different keycloak groups by their country when I create them during a sign-in for example?
I was thinking that it could be useful to better manage users in the future.
What do you think?
There is no direct solution for such question. It clearly depends on your application. If in the future your application will provide services based on the country of each user it might be good idea as your application might get this information about the user directly from Keycloak.
If you are planning to do some researches about your users it also might be good idea as some statistics might be country related or you would like to get country related outputs (to relocate your cloud instances near to majority of your users etc..)
There might be faster database lookups with such additional information but I don't know if Keycloak currently provides functionality for this. On the other hand, if I will sign up to your service while I am chilling on my holidays on the other side of the world from where I usually live your record will be useless. Therefore this action could bring more issues to implementation of your application while you might not need it at all.
If you have no plans for such functionalities there is simply no reason to do such thing. Present web services tend to store more data then they actually need to. For example in majority of recent database leaks you can see LAST geological coordination's point stored with each user. While these might be unnecessary for precise advertisements targeting and unnecessary users screening, there is really no reason to store last geological coordination of each user. Such information might change with each user login and should be determined in "runtime". If services do not benefit from such data users are under threat for no reason.
You should determine what is needed by your application and what is not. You should never store or expose any additional information's about your users regardless how well your application is secured.

How to create IC Internal Usage entries from an external system in SAGE?

I'm building a business application to manage inventory requisitions. The application is a lightweight web interface used mainly by our internal employees to submit inventory requisitions. The requisitions will pass through a workflow of activities, mainly for validation and approval, and finally, an IC Internal Usage entry should be created in Sage by the application before the requestor can receive the items.
Surprisingly, the Sage web API provides endpoints to create and retrieve almost all types of IC transactions except Internal Usage. I can't understand the rationale behind that, yet I'm looking for a way to create (and post) Internal Usage entries externally from my application, and I'm not aware of any solution for this.

REST versus more complicated data requests

REST APIs work great for get-one, get-a-list etc.
But our frontend has a dashboard, and one part of the dashboard is a more complicated. It requires a query that aggregates/joins several different resources.
Returning the data is not a problem. But what of the taxonomy of the endpoint that returns this data? Since the data is not a resource, what should the URL look like?
For REST principles it does not matter much if data returned 'aggregates/joins several different resources'. It is implementation detail of underlying data store. The dashboard should not care how exactly that store is implemented, if it uses joins, multiple queries.
Whatever is displayed on dashboard (single item or list of items) still may be treated as resource.
Example: Imagine use case when dashboard shows aggregated user profile from multiple portals (Facebook, Linkedin, etc). You may still have REST resource /user/id for that, even if obtaining that single resource would require many complex operations.

How to design endpoints for data not considered as a resource in a REST API

User context:
An school administrator logs into a dashboard. The page displays a block of data at the top of the page:
Number of students who used the service over the past week
The aggregate feedback (positive, negative, neutral) left by the students over the past week in percentages.
Other aggregate data
Underneath is a bunch of charts and graphs representing usage of the service broken down by month, daily usage broken down by hour, etc.
My problem:
I'm trying to build an API following REST principals where endpoints should define a resource and HTTP verbs as the action to take on those resources. My problem is going about building endpoints for this more 'analytical' and aggregate data that doesn't really seem to fit anywhere in my resources. Ideally, each graph or chart could be one request to an endpoint, and the block of aggregate data at the top would also be its own request, rather than 3 requests (1 for each piece of data). Can someone guide me in the right direction on how to go about building the endpoints for these specific scenarios?
Thanks
Can someone guide me in the right direction on how to go about building the endpoints for these specific scenarios?
TL;DR: How would you build a web site to support those scenarios? Do that.
If you were using something like a document store, then you would take the URI, say /feedbackReports/lastWeek, and use that as a key, and pull from the document store a representation of that report, and return it to the client (along with various bits of metadata).
If you were using something like a file system, then you would take the URI, and construct some reference to a file, like /www_root/feedbackReports/lastWeek, and read the representation of that report from disk, and return it to the client (along with various bits of metadata).
Is you were using something like a relational database, then you would take the URI, and see that the "last week" report was being asked for, and from that you would inject a bunch of "-7 days" parameters into prepared statements, and run them, then reshape the data in memory into some representation of that report, and return it to the client (along with various bits of metadata).
I'm trying to build an API following REST principals where endpoints should define a resource and HTTP verbs as the action to take on those resources
The REST principle in question is that the API isolates the clients (and intermediary components) from all of the implementation details. The API is the mask that your application wears so that web integrations just work.
My problem is going about building endpoints for this more 'analytical' and aggregate data that doesn't really seem to fit anywhere in my resources.
So create more resources.
Note: these are integration resources; which is to say that they produce the representations that web clients need to interact with your domain.
Jim Webber, in 2008
URIs do NOT map onto domain objects - that violates encapsulation.
Work (ex: issuing commands to the domain model) is a side effect of
managing resources. In other words, the resources are part of the
anti-corruption layer. You should expect to have many many more
resources in your integration domain than you do business objects
in your business domain.

REST-API design - allow custom IDs

we are designing an API which can be used by marketplaces and onlineshops to create payments for their customers.
To reduce the work the marketplaces and shops have to do to implement our API, we want to give them the ability to use their own user- and contract-IDs rather than storing the IDs we create. It makes it easier for them as they dont have to change/extend their databases. Internally in our database we will still use our own technical IDs. So far we do not run any checks on the custom-IDs (i.e. uniqueness).
My question is, if it is a good idea in general to let the stores & marketplaces use their own IDs, or if it is bad practice. And if our approach makes sense, should we run checks on the IDs we receive by the stores & marketplaces (i.e. uniqueness of a user-ID related to the store)?
Example payload for creating a new user via POST /users/:
{
customUserId: "fancyshopuserid12345",
name: "John",
surName: "Doe"
}
Now the shop can run a GET-request /users/fancyshopuserid12345 to retrieve the new user via our API.
EDIT:
We go with both approaches now.
If he wants to use his own id he does it like in the example above, if he sets false as the value for customUserId we set our internal ID as value.
Personally i think that it's awesome feature!
And i don't see any problems here.
I also think that you don't have validate customers ids, just check that it don't have injection to your persistence layer and it'll be enough.
More over your don't violate any REST conventions - that's why i think it's nice idea...
Well, a cool (RESTful) approach would be to receive URIs instead of custom IDs. That would unfortunately mean that those partner systems would have to publish their own resources in order be able to link to them. This would also solve the unique-ness problem, since you would only have to check whether the URI exists.
If some shop systems are in fact build RESTfully, they may want to actually store a URI instead of id, to be able to navigate seamlessly through their own and your systems. They would only have to add your media-types to their clients, and that's it.
Other than that, sure you can store IDs of third-party systems. I know of a few trading systems that do exactly that, storing all sorts of third-party IDs, of backend systems, of transport layer ids, etc. It is at least not unheard of.