I am trying to configure a context path for an API in a way that best leverages the features of Spring Data Rest. The way the API is designed ensures a client can only ever see the records belonging to them and no other clients. As such, the base URL is similar to "/root/employer/{employerId}".
I am trying to set the context path in the main class with System.setProperty("server.servlet.context-path", "/root/employer/{employerId}"). Based on my limited understanding, however, since the context path is a String, this is being rendered in Postman as "/root/employer/%7BemployerId%7D" as opposed to the desired format, and is therefore not recognizing actual IDs when they are passed in.
Is there a known way to resolve this? Alternatively, is there a better approach to this dilemma altogether?
Related
We have a system that uses http POST with JSON as an RPC method.
It is an in house solution for internal components communication.
The requests and responses are described each by a Java bean (POJO).
My question is, how can I use swagger annotations to create nice documentation in the swagger standard?
I am not afraid from messing around with existing code, but I was wondering if anyone has some experience with something similar.
The goal is to use Swagger UI to display nice docs and give a playground for users to invoke the Apis.
Based on the comments above, it's impossible to describe this sort of API using Swagger. The Swagger specification is intended to REST-based APIs, where the URLs serve as a unique endpoints to describe an operation, and not the payloads.
By definition, Swagger considers a unique operation to be the combination of a URL and the HTTP method (there are requests to expand the definition to include the mime type as well, for example, but it is not currently available).
There is simply no way to describe a single endpoint that operates multiple requests types, each having its own output.
There may be a solution for what you request in the future, but it is not in the near future, not will it answer your requirements to the fullest.
To be clear - this is not an issue of messing around with code or anything. The specification itself doesn't support it.
There are 2 simple tweaks required to make a swagger file work for any generic hand-built RPC application.
The first tweak is to make the swagger endpoints appear to be unique. This is done by defining each endpoint with a unique name after a hash in the context. This works because your app will not process the url past the '#' and this allows swagger to consider the path to be "unique". In reality though this technique will allow every unique path defined in the swagger file to actually invoke the same endpoint.
paths:
/endpoint#myUniqueCommandA
...
/endpoint#myUniqueCommandB
...
The other tweak is needed to ensure the generated swagger clients will actually call the correct operation inside your RPC app. This is done by implementing a "defaulted single value" enum in each command's request object. The defined enum represents the corresponding attribute / value combo the api needs to pass to get dispatched to the right target action inside your application:
...
definitions:
MyUniqueCommandARequest:
type: object
properties:
rest_call:
type: string
enum:
- myUniqueCommandA
default: myUniqueCommandA
...
MyUniqueCommandBRequest:
type: object
properties:
rest_call:
type: string
enum:
- myUniqueCommandB
default: myUniqueCommandB
...
In the above example, the property "rest_call" is what my underlying system uses to dispatch the request to the right underlying operation.
The request object for myUniqueCommandA has its rest_call attribute defined as enum["myUniqueCommandA"]. The request object for myUniqueCommandB has its rest_call attribute defined as enum["myUniqueCommandB"].
Since these are defined as a single value enums that are also defaulted to that same value, the generated swagger classes that calls these apis will be wired to pass their correct routing value automatically.
I've used both Play1.x and Play2.x, but I didn't find how Play distributes its request to different actions in its source code.
e.g.
http://HOST:9000/Application/index
Play could find the controller Application, and then invoke its index method.
I thought Play works this way:
Get URI's first part Application and init Application using reflection.
Get the second part of URI, index, invoke index() of Application using reflection.
But I don't know where's the code exactly.
And, If it using a lot of reflection, how could it handle millions of request ? I think reflection is a lot of slower than direct method call(Or Play make some magic optimize ?).
Route file get compiled into target/scala-2.10/src_managed/main/routes_routing.scala file.
Even if reflection would be involved why should it be slow? File need to be reflected once at app startup.
The route file points each uri to a specific method.
For example:
GET /clients/:id controllers.Clients.show(id: Long)
If you don't care about routes type-safety incorporated in Play 2.x you can easily write custom resolver which will catch all unhandled routes with Dynamic parts spanning several / so using simple string operations + reflections you can access any controller/action combination you want...
Anyway consider if your app's security is worth of this sacrifice.
PS.: hard believing that samples are not required to this approach, in other case let me know, I'll write something in free time
I am creating a web application that incorporates REST-style services and I wanted some clarification as to the preferred (standard) method of how the POST requests should be accepted by my Java server side:
Method 1:
http://localhost:8080/services/processser/uid/{uidvalue}/eid/{eidvalue}
Method 2:
http://localhost:8080/services/processuser
{uid:"",eid:""} - this would be sent as JSON in the post body
Both methods would use the "application/json" content-type, but are there advantages, disadvantages to each method. One disadvantage to method 2, I can immediately think of is that the JSON data, would need to be mapped to a Java Object, thus creating a Java object any time any user access the "processuser" servlet api. Your input is much appreciated.
In this particular instance, the data would be used to query the database, to return a json response back to the client.
I think we need to go back a little from your question. Your path segment starts with:
/services/processuser
This is a mistake. The URI should identify a resource, not an operation. This may not be always possible, but it's something you should strive for.
In this case, you seem to identify your user with a uid and an eid (whatever those are). You could build paths such as a user is referred to by /user/<uid>/<eid>, /user/<uid>-<eid> (if you must /user/uid/<uid>/eid/<eid>); if eid is a specialization, and not on equal footing with uid, then /user/<uid>;eid=<eid> would be more appropriate.
You would create new users by posting to /user/ or /user/<uid>/<eid> if you knew the identifiers in advance, deleting users by using DELETE on /user/<uid>/<eid> and change state by using PUT on /user/<uid>/<eid>.
So to answer your question, you should use PUT on /user/<uid>/<eid> if "processuser" aims to change the state of the user with data you provide. Otherwise, the mapping to the REST model is not so clean, possibly the best option would be to define a resource /user/process/<uid>/<eid> and POST there with all the data, but a POST to /user/process with all the data would be more or less the same, since we're already in RPC-like camp.
For POST requests, Method 2 is usually preferred, although often the resource name will be pluralized, so that you actually post to:
http://localhost:8080/services/processusers
This is for creating new records, however.
It looks like you're really using what most RESTful services would use a GET request for (retrieving a record), in which case, Method 1 is preferred.
Edit:
I realize I didn't source my answer, so consider the standards set by Rails. You may or may not agree that it is a valid standard.
I'm currently facing an interesting problem in my OSGi application.
I'm implementing a configuration service that should retrieve the application's configuration from multiple sources (file, registry or network). The configuration service should read from the sources in a special order until he got a value for the configuration property.
First I thought of putting each source in a separate bundle, create a super interface for them and let them provide a declarative service. This would also help to modularize the registry which is required since it is not available on every OS. When the configuration service is asked for a property's value it queries for all source bundles according to the whiteboard pattern and reads the configuration until he got a non-null value. But it does it in a random order.
Does anyone have an idea how to implement a special order in traversing the bundles providing the configuration service?
Best regards
OSGi already has a concept of service ranking. When registering a service, you can provide a value for the property "service.ranking" (org.osgi.framework.Constants.SERVICE_RANKING).
I don't think that this property has any effect on the order in which BundleContext#getServiceReferences() returns available service references (at least the spec doesn't say anything about it) , but you could still use the property value to order the internal collection managed by your "super" config service.
However, to me it is generally a strange idea to let the service implementation itself determine its relative importance. I would rather split the problem in two parts.
A config service acting as a facacde for
a collection of config source providers
The second interface would include some characterization concept (e.g. an enum {file, registry, net}). I would then have the implementation of the first interface (the facade) perform the ordering based on the characteristic of each provider (as the first answer by Chris already suggests).
In general if you need a special order of traversing for a bunch of objects, you just define a (partial) order between your objects.
Then, you sort the objects you've got and go through that list.
So, for your problem, when a property's value is needed, you find all the sources, you sort them in a list and finally iterate though it.
I have a webapp that redirects to a particular URI: let's say /service/library. In another bundle, I have a jaxrs server that listens for /service in the URI, and defines some beans to handle the request. There are quite a few beans there already, and one of the classes is already implemented to handle requests for /service/library. I am trying to create a new class that also handles requests for /service/library, but with a different absolute URI path, for example: /service/library/mynewlibrary. My question is, is it possible to define the same #Path identifier in two classes, or must they be unique, in other words, will I need to use a URI like /service/mylibrary for my new class implementation instead of implementing a second class that also uses the same #Path identifier? I am pretty new to JAX-RS, so I hope my question makes sense!
Thanks!
It's possible to have two #Path annotations that match the URI. In your case, if servlet-mapping is service, you may have #Path("/library") and #Path("library/mynewlibrary").
When request arrives, the matching paths are sorted in descending order, so the second class should be called, when a request with /service/library/mynewlibrary arrives.
It's most certainly possible to have two methods with the same #Path annotation, e.g., if they're distinguished by other means (such as HTTP method or #Consumes annotation). The #Path on a class acts as a default/root for the #Paths on the class's methods. Moreover, it's not a problem at all if you've got one path that is “within” another; JAX-RS specifies that the most specific match possible is used. (I prefer to not do it that way, instead having the “outer” class return a reference to the “inner” class on a suitable partial match, so that every path has a traceable route to responsibility that definitely leads to a single class. That requires a fairly different way of arranging the #Path annotations though.)
But if you've ended up with two methods that can serve the same incoming request, you've got a clash and the JAX-RS implementation will be free to pick which one to use (in an implementation-dependent manner). That's probably not what you want, as computers tend to make bad decisions when given a free choice.
You can achieve your goal to have /service/library/mynewlibrary using below configuration.
In your existing class you have /service/library configured at class level so you can configure /service at class level in new class you are adding and then at method level configure /library/mynewlibrary.
This way it will not have same path for both classes and your goal is also achieved. I tried this and it works.