REST API standard conventions for accessing resources - spring-boot

I am exposing a REST API for customers to create and manager orders in the below format
/api/v1/customers/{id}/orders [GET,POST] /api/v1/customers/{id}/orders/{id} [PUT, DELETE,GET]
Now, I have another set of entities by employees. Employees should also be able to access the [GET] API for checking orders. What should be the naming conventions for accessing the orders for customers?
Should the following convention recommended
/api/v1/employees?customer_id=34
/api/v1/employees/customers/orders
/api/v1/employees/customers/orders/{orderid}

Just use /api/v1/orders, /api/v1/orders?customer={customerId} and /api/v1/orders/{orderId} and check the authorization of the user for certain operations. As of the operation descriptions you need to respond with a hypermedia containinig the possible operations for the actual authorization and resource(s) as hyperlinks.

Related

when to use explicit relations - schema design

I am pondering about schema design with regard to explicit vs implicit relation when to...
for example:
in an imaginary schema with 2 custom types author and post, each with several properties, A post type can reference an author in 1 of 2 ways:
explicit: having an Autor type property
implicit: having a scalar value that indirectly points to the author
when designing a shema. what should be my compass in this kind of desicion making?
thanks in advance
There's absolutely no value to the client in only returning the ID of a related resource when you could just expose a field that would return the entire resource. Exposing only the ID will mean the client will have to make subsequent requests to your service to fetch the related resources, instead of being able to fetch the entire data graph in one request.
In the context of other services, like a REST API, it might make sense to only return the ID or URL of a related resource. This is because in those cases, the payload is of a fixed size, so returning every related resource by default can quickly and unnecessarily bloat a response. In GraphQL, however, request payloads are client-driven so this is not a concern -- the client will always get exactly what it asks for. If the client needs only the author's ID, they may still fetch just that field through the author field -- while allowing a more complete Author object to be fetched in other requests or by other clients.

How can I efficiently find out if a user is a member of a group using the Okta API?

I can view OKTA users in a group (/groups/{groupid}/users), and I can grab all groups belonging to a user (/users/{userid}/groups).
But both of those can return a lot of data and the latency is too high because of it. Can I specify which fields to return in the second call above?
How can I do a simple check if a user is a member of a group?
Okta Expression Language contains group functions such as isMemberOfGroup, but there is no examples or explanation of how to use that as part of an API call. I tried using it with the filter querystring, but no go.
Unfortunately you cannot as the Okta API does not currently offer an isMemberOfGroup method. You'll have to use either of the 2 APIs you mentioned in your question, whichever is the most efficient in your specific case.

JSON API REST endpoint with permissions-restricted fields

JSON API REST endpoint with permissions-restricted fields
I am working on a JSON API-compliant REST api. Some endpoints contain fields that should be restricted (read-only or not available) for certain users.
What is the best way to architect the api to allow that certain users have access to certain fields, while others do not? By "best", I mean:
Most compliant with REST standards, ideally JSON API standards
Most clarity in terms of preventing bugs and confusion on behalf of clients consuming the API
I am considering the following options, each with their set of concerns/ questions. I would be more than grateful for any other solutions!
Option 1: Return null on restricted fields for users without permissions
Different data values would be returned per-user. Is this strictly anti-REST?
Lack of distinction between null meaning "null value" and null meaning "You don't have access to this"
In REST/ JSON API architecture, is it okay for an endpoint to return different data per user, based on permissions? I have the impression that this would be contrary to the spirit of resource-based REST architecture, but I could not find anything specific to point to in any doc or standard (e.g. JSON API). Also applies to Option 2.
Is there any paradigm for adding some sort of "You don't have access" flag in the resource's metadata?
Option 2: Exclude restricted fields entirely for users without permissions
Different data values would be returned per-user. Is this strictly anti-REST?
Possibility of "undefined" errors in client, when trying to retrieve field value
Option 3: Move restricted field(s) onto another endpoint, available as an ?include='field_name' relation for those with permission
Example: /api/entity includes attribute field "cost" which is only available to Admin users. Admin users can request cost data via GET /api/entity?include=cost. For all users, "cost" is exposed as a relation in the resource object, with a "type" and "id".
This is the option I am leaning toward. The main con here is endpoint clutter. I have a lot of relations that would need to be made into separate endpoints, simply to support a permissions-quarantined data on an already-existing endpoint.
In the JSON API specs, I am having trouble determining if it's ok for an endpoint to exist as a relation only, e.g. can we have /api/entity/1/cost, but NOT have a top-level api endpoint, /api/cost. My assumption is that if a resource has a "type" (in this case, the relation type being 'cost'), it also has to live on a top-level endpoint.
In this scenario, the client could get a 401: Unauthorized error response if a non-admin user tries to GET /api/entity?include=cost or GET /api/cost/:id
Note: I have already built a separate permissions schema so that the client can determine which CRUD privileges the user has, per top-level endpoint, before making any requests. Permission sets are indexed by resource type.
Any help on the matter would be very much appreciated! And if anything needs to be clarified, feel free to ask.
I would definitely not use undefined or null to indicate fields that the user is not allowed to see. To me, that feels like a lie and represents that the data is really not there. They would have to really know your API in order to get a grasp of what is really going on.
I would recommend something more like your 3rd option, except I would make it a different endpoint altogether. So in your example, the endpoints would be:
/api/entity/1/cost
and for admins
/api/admin/entity/1/cost
or something like that.
This way your server code for the admin endpoint could just be focused on authenticating this admin user and getting them back all the fields that they have visibility on. If a non admin user tries to hit that route, reject them with an unauthorized status code.
I'm not saying that you should not implement the GET param to be able to specify fields as well. You can if you want to, but I don't think it just won't be necessary in this case.

How to search for users by ID and customData in Stormpath

I'm thinking about using Stormpath with it's Java API as a user storage.
Looks good, except that I can't search for users.
For example, I get this error:
Exception in thread "main" com.stormpath.sdk.resource.ResourceException: HTTP 400, Stormpath 2105 (http://docs.stormpath.com/errors/2105): Account ID is not a supported query property.
when I execute this query:
HashMap<String, Object> queryParams = Maps.newHashMap();
queryParams.put("ID", "4mPXXXXXXXXXX");
searchResult = application.getAccounts(queryParams);
Searching for a user by e-mail however works. I get the same error when I try to search a user by a login-token I stored in the customData property.
It looks like what I want to do is not possible as it looks like the only properties you can query are e-mail and username. But why would they provide this functionality if it didn't work. What am I missing?
There is an impedance mismatch between common relational database behaviors and those in a REST API. Querying by id, while common in relational databases, is not idiomatic behavior for REST APIs (or most HTTP-based web sites). The URL (href) is the canonical 'pointer' to a resource on the web. In other words, in REST APIs, the canonical identifier is the href. Any token inside an href (any internal 'id', special characters, whatever) should be opaque to REST clients and ignored by clients entirely. URLs are king in HTTP and REST.
That being the case, the Stormpath SDK tries to be true to RESTful best practices, so you can obtain any Stormpath resource by using the client.getResource method, which accepts an href and the type of object you expect that href to represent:
String href = "https://api.stormpath.com/v1/accounts/" + id;
Account account = client.getResource(href, Account.class);
That said, there's nothing wrong with wanting this to be more conveniently represented in the client API, for example, client.getAccount(String id) if you want to keep the notion of IDs. If so, please open a new feature request and we'll be very happy to consider it.
As for queryable Account properties, those are documented here. Stormpath will soon make data in Custom Data searchable as well. While Stormpath feature timelines are never announced, it is the company's highest engineering priority and it should be out soon.
One workaround that is helpful for some people is to store data they want to search in Account Fields that you don't use in your applications. For example, you could use the 'middle name' field to store, say, favorite color. This would only be temporary until custom data search is available. HTH!

RESTful api for dynamic showform on top of spring mvc

I want to build a typical mvc app for CRUD of simple items, the api s should be RESTful. The catch here is, that i have a large pallete of items that needs to be initialized. On the server side those items are defined as java beans and the corresponding create form for the item is dynamically created from the field information(data type, validation constraints etc) harvested from the bean.
I am new to REST and just read up about how the urls should be nouns defining the resource and action specified by HTTP verb. In that perspective how to model something like
.../client/showForm?type=xyz from non RESTful way to RESTful one ?? My intention here is to tell the server to dynamically construct and send back a CREATE form for client of type xyz. The obvious problem with url i mentioned above is that it specifies action in the url which, from what i have read, makes it non RESTful.
When I think of REST, I think of resources. I think of data. In other words, I don't think of REST as being something that I would typically use to retrieve a form, which is a user interface component.
REST is an architectural style that is used to identify a resource on a server using a uniform resource identifier, or URI. Additionally, actions performed on those resources identified by the URI are determined based on the specific HTTP Method used in the request: GET, POST, PUT, DELETE, etc.
Thus, let's say you have a Client object. That client object might have the following properties:
Name
Location
AccountNumber
If I wanted to retrieve the data for a single client, I might use the following URI:
GET /client/xyz/ # xyx is the accountnumber used to identify the client.
I would use a GET method, since REST describes GET as being the method to use when retrieving data from the server.
The data could theoretically be returned in HTML, since REST is not a standard but more like a series of flexible guidelines; however, to really decouple my data from my user interface, I would choose to use something platform independent like JSON or XML to represent the data.
Next, when adding a client to the collection on the server, I would use the /client/ URI pattern, but I would use the HTTP Method POST, which is used when adding a resource to a collection on the server.
# Pass the data as JSON to the server and tell the server to add the client to the
# collection
POST /client/ {"accountnumber":"abc" , "Name" : "Jones" , "Location" : "Florida"}
If I were to modify an existing record on the server or replace it, I would most likely use the HTTP Method PUT, since REST guidelines say that PUT should be used if repeating the same operation repeatedly would not change the state of the server.
# Replace the client abc with a new resource
PUT /client/abc/ {"accountnumber":"abc" , "Name" : "Bob Jones" , "Location" : "Florida"}
The general idea behind REST is that it is used to identify a resource and then take action on that resource based on what HTTP Method is used.
If you insist on coupling your data with your view, one way accomplish this and retrieve the actual form, with the client data, could be to represent the form as a resource itself:
GET /client/abc/htmlform/
This URL would of course return your client data for client abc, but in an HTML form that would be rendered by the browser.
While my style of coding utilizes data transports such as JSON or XML to abstract and separate my data from my view, you could very well transport that data as HTML. However, the advantage of using JSON or XML is that your RESTful API becomes platform independent. If you ever expand your API to where other developers wish to consume it, they can do so, regardless of what specific platform or programming language they are using. In other words, the API could be used my PHP, Java, C#, Python, Ruby, or Perl developers.
In other words, any language or platform that can make HTTP requests and can send GET, POST, PUT, DELETE requests can be used to extend or build upon your API. This is the true advantage of REST.
For more information on setting up your controllers to use REST with Spring MVC, see this question. Additionally, check out the Spring MVC Documentation for more information.
Also, if you haven't checked out the Wikipedia article on REST, I strongly encourage you to do so. Finally, another good, classic read on REST is How I Explained REST To My Wife. Enjoy.

Resources