I have an existing API which is not quite RESTful. I was trying to use Swagger to quickly put together a Mock Server so that I can test the App without relying on the server. As I started writing the yaml rules, I realized that for a subset of routes, the same endpoint is being used and the server parses the body json to determine exactly what the request is. Is there a way to model such a behavior using Swagger?
(Please don't comment on the API architecture, it already exists and in productions and I wasn't involved in the design)
Not possible to define multiple endpoints/behaviors that share the same URL.
The swagger.yml is assuming that you have a RESTful API. Swagger will define behavior and valid payloads for each route, and each route must have a unique path. You cannot represent multiple routes through the same URL with Swagger, unless you were to merge them all and represent them as a generic endpoint. This would require you to describe the behavior using documentation and you would lose many of the benefits of swagger (a pleasant UI and automatic validation). If you have distinct input payloads for each route, then all fields would need to be defined in the same payload and the documentation would describe which fields are required in each scenario.
If possible, consider defining multiple endpoints and then proxy the requests to the same backend single route.
Related
I have an existing site which I want to use APIM with and I have successfully mapped my APIs across to APIM. However, I have a swagger page which I just want to be available in the same domain as APIM. How can I do this? The swagger page is:
https://mysite.azurewebsites.net/api/swagger/index.html
I want this to come across as something like
https://myapidomain.com/swagger
My apis in APIM are of the form so I want the swagger to match the same domain
https://myapidomain.com/api/myfirstapi
This can be done with a few caveats depending on how complex your web page is:
Create an API with URL suffix of "swagger"
Optionally uncheck "Require subscription" from that API to make it anonymous
Create inner operation with URL template of "/" and GET method
Add policies to operation inbound:
<set-backend-service base-url="https://mysite.azurewebsites.net" />
<rewrite-uri template="/api/swagger/index.html" />
Test and adjust
That will take care of the page itself. There will be problems if page uses cookies or references external scripts/images via relative URIs. Cookies will be a problem because they'll come with domain set to "mysite.azurewebsites.net", so you need to take care of this in policies.
Resources with relative URLs are problem because browser will make additional requests to your APIM service with those URLs, so you'll need to create additional operations to cover those requests. Using * in operation template might help cover multiple resources.
I would like to customize how the TokenEndpoint works so that I can add additional parameters to to incoming /oauth/token rest call that I will capture and process.
Ok, to perhaps help explain what I want to do, here are some additional aspects to it.
Lets say, in the oauth/token request I want to add another request parameter entry. So instead of sending the oauth/token with grant_type=client_credentials (for example), I want to add grant_type=client_credentials&extraInfo=xxxx.
So my my token endpoint that I have running at request mapping /oauth/token instead of the builtin one (TokenEndpoint), I do everything that the original does PLUS, I parse the extraInfo=xxx and set it as a key/value in the additional info section of the token.
Later in my backend, I extract this extra info and use it to provide some functionality that I need. Various clients will use this extraInfo parameter to send some specific type of information that I was to be aware of.
So basically, ow do I substitute my own token endpoint in place of the regular one? Is this in token services and if so which specific part?
I figured out an alternative to what i want to do without any of the messiness of trying to create and hook in my custom Token Endpoint.
I put an aspect around (#Around ...) the TokenEndpoint and captured the incoming parameters and resultant token, etc. I then used the spring session framework to put in a structure that I can access (created from what came in) and now I can get at it in my resultant code.
This does what I want without needing to do something more complex.
I would like to create a route in my MVC application that will allow using hashtags in urls. If I would go to www.mydomain.com/#tag1 a specific controller for tag1 must take care of that request. If I would go to www.mydomain.com/#tag2, a different controller for tag2 must take care of that request.
Is this possible in MVC4?
use www.mydomain.com/ht#hashtag || then have ht defined as a forwarding or delegating controller that finds the correct controller to invoke
Is this even possible in MVC ?
This is not an issue with MVC. URL fragments (URLs with a hashtag #) are left up to the author of the browser to interpret. Many browsers do not pass this information back to the server, so relying on them for routing is not reliable across browsers.
So, in short yes this is possible with MVC (by customizing routing), but unless you can limit the browsers that your clients use to those that pass the fragment information to the server side it isn't practical.
RFC 2396 section 4.1:
When a URI reference is used to perform a retrieval action on the
identified resource, the optional fragment identifier, separated from
the URI by a crosshatch ("#") character, consists of additional
reference information to be interpreted by the user agent after the
retrieval action has been successfully completed. As such, it is not
part of a URI, but is often used in conjunction with a URI.
(emphasis added)
Typically, the usage of URL fragments is limited to the client side because that is the only place that all major browsers support them.
I am attempting to construct a web app in which the back end is a complete RESTful web service. I.e. the models (business logic) would be completely accessible via HTTP. For example:
GET /api/users/
GET /api/users/1
POST /api/users
PUT /api/users/1
DELETE /api/users/1
Whats the proper way to provide more methods that aren't CRUD (verbs/actions)? Is this considered more of a RPC-api domain? How would one properly design the RPC api to run on top of the RESTful api?
For example, how would I elegantly implement a forgot password method for a user.
POST (?) /api/users/1/forgot
The application (Controllers/View) would then use a https requests (HMVC like) to access the models and methods. What would be the best for authentication? OAuth, Basic Auth over HTTPs?
Although this is "best practice" for scalability later on, am I over engineering this task? Is it best to just follow the typical MVC model and provide a very basic API?
This question has been mostly inspired by ASP.NET's MVC 4 (WebAPI) and a NodeJS module https://github.com/marak/webservice.js
Thanks in advance
I recently started learning REST, and when developing a new web service I think you're doing the right thing to consider it.
You are correct in your assumptions about the custom verbs. REST acknowledges that some actions need to be handled in a different way, and custom verbs don't violate the requirements. You should use POST when communicating with the server, but the verbs are normally written in imperative. Instead of forgot, I'd probably use remind or something similar. I.e., you should give instructions on what to do, rather than describe what happened without clearly indicating what you expect as a result.
Furthermore, the preferred way to construct the service is to include api into the domain name, and drop it from the path. I'd write your particular example like this:
POST /users/1/remind HTTP/1.1
Host: api.myservice.example.com
Session handling in REST is a bit tricky. The cleanest way of doing it would probably be to authenticate with username and password on every single request, using Basic access authentication. However, I believe that it's rarely done like that. You should read this question (and its accepted answer): OAuth's tokens and sessions in REST
EDIT: I'd also drop the trailing forward slash in the GET request in your example. If the service is truly RESTful, then the resource is not supposed to be accessibly from both /users/ and /users. A particular resource should have one and only one URL pointing to it. A URL with a trailing slash is actually distinct from one without. REST promotes dropping it, and a RESTful web service should not accept both (which in the case of GET means responding with 200 OK), although it may redirect from one to the other. Otherwise, it might lead to confusion about the proper URL, duplicate caching, weeping and gnashing of teeth. :)
EDIT 2: In RESTful Web Services by Richardson & Ruby you're discouraged from putting the new verb in the path. Instead, you could append something like ?_method=remind. It's up to you which one you choose, but please remember that you're not supposed to handle these requests with GET, regardless of what you choose. A GET must not change the resource, and should not cause side effects if the user browses back and forth in the history. Otherwise, you might end up resending the password several times. Use POST instead.
I want to make sure I have correctly understood the (draft) spec, which states:
The redirection endpoint URI MUST be an absolute URI as defined by
[RFC3986] section 4.3. The endpoint URI MAY include an
"application/x-www-form-urlencoded" formatted
([W3C.REC-html401-19991224]) query component ([RFC3986] section 3.4),
which MUST be retained when adding additional query parameters. The
endpoint URI MUST NOT include a fragment component.
Reason I ask is that neither Google or Facebook appear to preserve any querystrings.
Re-reading the spec it appears that the quoted section of the spec applies not to the OAuth server's handling of URIs but the OAuth client's handling of the original endpoint URI it is given.
In other words it's saying that if I say that my OAuth endpoint which you have to use when redirecting to my server for an OAuth authorization is:
http://example.com/oauth.php?endpoint=token
Then when the client is adding the ?response_type=code&client_id=...&state=...&redirect_uri=... to the URI it is not permitted to discard the "?endpoint=token" in the original endpoint uri and MUST use the URI:
http://example.com/oauth.php?endpoint=token&response_type=code&client_id=...&state=...&redirect_uri=...
So, at least as far as that part of the spec goes there's nothing there saying that Facebook, Google, etc... have to preserve any unknown query arguments besides the 'state' one.
Technically you might be able to use the &state= parameter to pass along custom data in say JSON format. Though that may or may not work. IIRC I noticed that Meetup's implementation of OAuth 2 appears to mangle the state when you use special characters. Something that I believe is against spec.