Best practices for REST API that access multiple environments - rest

When writing a RESTful API that needs to access different environments such as a lab/test database and a production database, what's the best practices around setting up the API?
Should there be a #PathParam?:
/employee/{emp_id}/{environment}
/{environment}/employee/{emp_id}/
Should there be a #QueryParam?:
/employee/{emp_id}/?environment="test"
/employee/{emp_id}/?environment="prod"
Should there be a field in the payload?:
{"emp_id":"123","environment":"test"}
{"emp_id":"123","environment":"production"}

In fact I see two ways to handle this. The reason to use one or the other corresponds to what is the most convenient to implement in your RESTful application.
Using a path parameter
With this approach, it should be a path parameter at the very beginning of the resource path. So URL would be like this: /{environment}/employee/{emp_id}. Such approach is convenient if you have several applications deployed under different root paths. For example:
/test: application packaged with the configuration for the test environment
/prod: application packaged with the configuration for the production
In this case, applications for each environment are isolated.
Using a custom header
You could also a custom header to specify on which environment to route. Github uses something like that to select the version of the API to use. See this link: https://developer.github.com/v3/#current-version. It's not exactly the same thing but you could have something like that:
GET /employee/{emp_id}
x-env: test
A reverse proxy could handle this header and route the request to the right environment.
I'm not convinced by the approach within the payload since an field environment isn't actually a part of the representation for element resource employee. Regarding the query parameter approach, it's similar since such parameters apply to the request on the resource.
Hope it helps you,

Related

Are JAMstack conventions compatible with RESTful API design?

I've been building a lot of quick prototypes on Netlify lately. I love the service for its ease of setup and deployment. But I keep running into this conflict between their JAMstacky conventions around API endpoints and my own background in RESTful API design.
To be more specific, say I am building a basic CRUD API in which I can create, fetch one, fetch all, and update some resource type . Let's say a User. If I were designing those endpoints from a RESTful perspective, it would look like this:
POST /users -> Create a user
GET /users -> Fetch all users
GET /users/{id} -> Fetch one user
PUT /users/{id} -> Update a user
Now, if I were setting this up on AWS, perhaps with the serverless framework, each of those endpoints would be their own lambda. But Netlify offers no such configuration options. Which is mostly nice. I hate configuration. But it is difficult to achieve these endpoints at all with Netlify.
Specifically in this case, Netlify automatically creates endpoints which match filenames. So if you have a file named users.js, that creates a /users endpoint. The problem is, that file will be used for every possible permutation of /users. Every HTTP method. Every subroute. They all go to this one lambda. So in order to achieve a RESTful API design, I have to put everything in a single lambda and essentially make it a router. Which seems to defeat the whole idea of serverless.
So usually when you read Netlify examples, which claim to follow JAMstack patterns (something I'm not super familiar with), they do not use RESTful endpoints. Instead they tend to do something like this:
POST /create-user -> Create a user
GET /fetch-users -> Fetch all users
GET /fetch-user?id={id} -> Fetch one user
POST /update-user -> Update a user
So this is in some ways a Netlify question, and in some way a larger question about JAMstack patterns. Is there something inherent about JAMstack that makes it incompatible with REST? Are there different conventions which tend to replace REST for Netflify/JAMstack projects?
"Is there something inherent about JAMstack that makes it incompatible with REST?"
I would say no as it's not related. You aren't building an API with the Jamstack. You are using a service (Netlify) which supports serverless functions that operate alongside the rest of your site. Remember that the Netlify serverless functions are just one option. You could set up your own AWS setup and support the mechanism you want, and still use it in conjunction with the rest of your Jamstack site. I like Netlify's serverless stuff, but it's not going to work for 100% of the use cases out there.
I guess my tl;dr is - Netlify tried to make serverless simple for folks building Jamstack sites, but it won't cover every use case. When it doesn't, you can still use your own solutions along with your site.

REST API URI design pattern: Non-hierarchical path?

At work we're discussing how to structure our upcoming APIs. As of now, we're about to launch an API containing different user information endpoints, and though we'd publish it under an URI like this: api.mycompany.com/userinfo. Examples of endpoints:
api.mycompany.com/userinfo/users
api.mycompany.com/userinfo/users/{id}
api.mycompany.com/userinfo/api-docs <-- Swagger document for this particular API will be located here
This type of setup would allow us to have server1.mycompany.com host the API, and use our load balancer / proxy to forward traffic to api.mycompany.com/userinfo to server1.mycompany.com. For our next API running on server2.mycompany.com, we'll simply have our load balancer / proxy forward traffic from api.company.com/transportation to server2.mycompany.com, like this:
api.mycompany.com/transportation/cars
api.mycompany.com/transportation/cars/{id}
api.mycompany.com/transportation/api-docs <-- Swagger document for this particular API will be located here
By using "userinfo" and "transportation" in the URI, we'll have a simple way to reference our different APIs as a whole, and a simple way to publish the Swagger UI along side the actual API.
My concern with these URIs is that they're not hierarchical, but more like a way to group endpoints together. Nor is "userinfo" a resource, so compared to the REST API examples one typically comes across online, using elements such as "userinfo" and "transportation" in the path may not be according to best practices.
Does this design break any REST API design patterns? If so, how would you suggest us publishing our different APIs under a single fqdn (api.mycompany.com)? Or are there reasons not to use a single fqdn for all of our APIs?
Any input will be greatly appreciated.
REST doesn't care what spellings you use for your URI
My concern with these URIs is that they're not hierarchical, but more like a way to group endpoints together. Nor is "userinfo" a resource
Identifiers being "hierarchical" doesn't (necessarily) promise anything about a hierarchy of resources. The fact that there is a resource identified by /userinfo/users does not imply that there is also a resource identified by /userinfo. Think Key/Value store, not File System.
A Rails developer might recognize /userinfo and /transportation as namespaces.
If so, how would you suggest us publishing our different APIs under a single fqdn (api.mycompany.com)? Or are there reasons not to use a single fqdn for all of our APIs?
In a 2014 interview, Fielding offered this answer about versioning:
It is always possible for some unexpected reason to come along that requires a completely different API, especially when the semantics of the interface change or security issues require the abandonment of previously deployed software. My point was that there is no need to anticipate such world-breaking changes with a version ID. We have the hostname for that. What you are creating is not a new version of the API, but a new system with a new brand.
If you squint at that, it might imply that different API should be on different (logical) hosts.
Does this design break any REST API design patterns?
Nope. There are no "REST API design patterns". And REST doesn't say anything about what URLs should look like. REST says to treat them as opaque. There's an argument that web API URLs should be "hackable", that is, easily understandable and modifiable by a human. I'd argue that your URL structure is hackable. I'm not aware of any persuasive argument that URLs must be hierarchical in nature.

Datasnap method name [duplicate]

I've written a REST server in Delphi XE (using the wizard) and I want to change the URLs a bit so that instead of having
http://192.168.1.84:8080/datasnap/rest/TServerMethods1/GetListings
I get something that looks more like http://192.168.1.84:8080/GetListings
Is there a nice easy of doing this?
The naming convention is (Delphi XE3):
http://my.site.com/datasnap/rest/URIClassName/URIMethodName[/inputParameter]
You can easily change the "datasnap" and "rest" part of the URL in the TDSHTTPWebDispatcher component properties. You can change the Class Name and Method Name of the URL by simply changing the name of your class and method. However, you still have to have 4 components to the URL, so for example it could be:
http://my.site.com/api/v1/People/Listing
See here:
http://docwiki.embarcadero.com/RADStudio/XE3/en/REST#Customizing_the_URL_for_REST_requests
You could put IIS or Apache in between to accomplish this, and indeed rewrite the URL to point to your service the way you like.
That provides some more advantages anyway (security and scalability mostly). For example, you can create a fail-safe setup with double servers, or you can create multiple machines with your service, and have your web server do the load balancing for example.
You'll get extra logging capabilities, and if you easily want to serve other web content it's easy to have a full fledged web server anyway.
URL rewriting is usually done in the web server configuration, in Apache using entries in the .htaccess file

Portal URL from Portlet

Is it possible to get the Portal base URL (like http://www.thisismyportal.com) from a Portlet using Portlet 2.0 API?
Right now I'm planning to manually build it concatenating PorletRequest.getServerName(), PortletRequest.getServerPort() and PortletRequest.getContextPath(); but it seems kind of clumsy (and there's no PortletRequest.getProtocol())
While it is clumsy, it is the safest way to construct the URL; and while there is no PortletRequest.getProtocol() method, you can conclude the protocol using the PortletRequest.isSecure() method.
I would advise against using an external configuration for the base URL, for a couple of reasons.
First, it would be yet another configuration item for you to maintain across environments (test, integration, production and so forth). There's very little justification to hold, in configuration, something that is fully reproducible using the current request.
Second, under certain circumstances, it might be impossible to designate a particular URL as a "base URL" for the portal. An example would be the case in which the portal server is associated with multiple hosts, or multiple host aliases.
We had those configuration properties in Resource Environment Provider for the purpose of generating external URLs for sending them in emails. It was specific solution and it wasn't a problem for us as we had other properties stored there as well so we knew it will be available at runtime. I don't know if that suits your needs. It depends on your scenario.
Also, we used https only during login, so we always generated http URLs.
Hope this helps.

REST: Way to map URLs to services/files?

In your humble opinion: what would be a best practice aproach to map REST URLs to services/files within one's architecture (let's assume MVC pattern here)?
In addition to Darrel's answer:
Make use of the hierarchical nature of HTTP URIs; think of every path segment as drilling down into the overall space of managed items (e.g. orders, customers). If at some point you need to 'index' into a collection along multiple dimensions (e.g. query) then use query string parameters:
/service/products/cars/japanese-cars/toyota/corola/&priceMin=2000&priceMax=5000
Note that (as darrel said) the structure should be opaque to the client. That means that the client needs to discover the parameters at run time (that is what forms or URI templates are for). Of course client and server need shared knowledge about the meaning of e.g. priceMin. That knowledge should be in some design time specification, for example the specification of a link relation. Maybe look at http://www.opensearch.org for detailed use case.
Also interesting is the host part of the URIs. If you might at some stage need to move parts of your services to another machine, design your URIs so that the relevant information is in the domain part. Then you can use simple DNS to route requests to different machines.
HTH,
Jan
The best way to map URLs to resources is dependent on what web framework you use to provide the REST service. Pick whatever url structure is easiest to manage with the tools you have.
The url structure should be completely opaque to the clients of your service so they should not care what they look like.
The most important thing in my opinion is that when you are looking at an URL it should be relatively easy to guess which controller on the server is going to respond to that URL. That will make development and debugging much easier.