For a simple example, let's say you create guestbook in your site and you plan to give external access for Create and Read functions via API. Update and Delete will not be included in the API since it should only be used internally.
What's a better practice?
Make the whole CRUD functions available via API and just restrict public access to Update and Delete. So you yourself will also use the API for all internal workings of the app.
Make internal CRUD functions without API for all internal workings, then create a separate API for Create and Read only. Basically this give you two ways to use Create and Read - one with API, one without.
Make internal Update and Delete functions without API for internal workings, then create API for Create and Read only. If you need to use Create and Read functions for internal workings, then you must use API.
I hope it's quite clear, what's generally the best practice?
I like the first option. It has a clear example of separation of concerns and using right tools in the right context.
By using CRUD approach for the API, you gain uniformity and integrity. It results in a more cohesive design, less code duplication and easier evolution down the road. The security aspect could be implemented either inside or outside of the application powering the API. For the outside option you could use 3-d party software or hardware solutions like firewalls, for example.
Related
A question for this already exists, but is more tech focused and doesnt have answers: Representing a request body on HATEOAS link
I like HATEOAS. I love using it in my frontend to check if I can perform some actions by checking if a link exists instead of having business logic.
But what I do not understand is how HATEOAS can truly be useful in other scenario's. What if you have an "AddItemToBasket" link which would need a request body with some properties in it. The frontend would still need to know what this request body looks like. But HATEOAS doesn't tell you this.
This means you still have a dependency on API knowledge. I think lots of applications solve this problem with generated API clients/graphql, but that makes HATEOAS a hard sell.
Why use HATEOAS if we can't use the URL and http method, because it doesn't offer the full picture.
REST builds on standards (uniform interface constraint) and currently there is no standard way to do this. There is a Hydra W3C WorkGroup writing a standard about how to describe Hypermedia APIs. They use RDF, standard vocabs like schema.org and you can write your API specific vocab they call documentation. As far as I understand their model you can give parameters in the documentation for operations represented by hyperlinks. You can use for example XSD to add constraints like numbers, etc. to the parameters. It takes a lot more effort than normally to write this kind of formal documentation and as far as I understand there are currently no general REST clients which could profit from these, so it does not make much sense currently to write such an API, but it is possible if you want to.
As of why to use HATEOAS, it makes your API flexible and backward compatible. For example if somebody does not have permission for an operation, you simply don't send a hyperlink for it in the response. You can always add new operations and the existing clients don't have to support them, they can just focus on what they already know and they won't break because something extra is added. They don't have to know about the URI structures and the methods, which can freely change if the only thing they depend on is the operation type and the parameters.
I'm in the middle of writing my first web app. Just wondering how the conventions are when it comes to REST API designs. Is it better to have it reflect my server side architecture or whatever seems to be easier to reason about?
I'm thinking of either doing:
/serviceProvider/product
or
/product/serviceProvider
My server side architecture are all separated into modules organized by service providers, however they all expose a product query API.
APIs ideally should be designed to make most sense for its consumer. There isn't really a good reason to reflect your "server architecture" at all. In fact, it's what's usually called a leaky abstraction or a leaky API and is considered bad practice, mainly because your application structure may change and then you have these possible scenarios:
you need to change your API, which is a non-trivial task when it's already being used by someone;
your API stops being reflective of your application structure which leads to inconsistencies;
exposing your application structure or database schema to the world may have security implications.
With these things in mind, you might as well design the API with focus on ease of use in the first place. The consumer of your API doesn't need to know or care about your application architecture.
I believe that keeping on the same architecture is important because you're forced to offer simple API and it will enforce you a simplified architecture on the server side.
That said, of course that you don't want to expose any server side method or even every server side property of the returned objects.
In Kaltura we also believe in flat (not nested) paths to simplify the API.
For more guidelines, see my blog: http://restafar.com/create-new-rest-server/
I really like all the boilerplate code Spring Data Rest writes for you, but I'd rather have just a 'regular?' REST server without all the HATEOAS stuff. The main reason is that I use Dojo Toolkit on the client side, and all of its widgets and stores are set up such that the json returned is just a straight array of items, without all the links and things like that. Does anyone know how to configure this with java config so that I get all the mvc code written for me, but without all the HATEOAS stuff?
After reading Oliver's comment (which I agree with) and you still want to remove HATEOAS from spring boot.
Add this above the declaration of the class containing your main method:
#SpringBootApplication(exclude = RepositoryRestMvcAutoConfiguration.class)
As pointed out by Zack in the comments, you also need to create a controller which exposes the required REST methods (findAll, save, findById, etc).
So you want REST without the things that make up REST? :) I think trying to alter (read: dumb down) a RESTful server to satisfy a poorly designed client library is a bad start to begin with. But here's the rationale for why hypermedia elements are necessary for this kind of tooling (besides the probably familiar general rationale).
Exposing domain objects to the web has always been seen critically by most of the REST community. Mostly for the reason that the boundaries of a domain object are not necessarily the boundaries you want to give your resources. However, frameworks providing scaffolding functionality (Rails, Grails etc.) have become hugely popular in the last couple of years. So Spring Data REST is trying to address that space but at the same time be a good citizen in terms of restfulness.
So if you start with a plain data model in the first place (objects without to many relationships), only want to read them, there's in fact no need for something like Spring Data REST. The Spring controller you need to write is roughly 10 lines of code on top of a Spring Data repository. When things get more challenging the story gets becomes more intersting:
How do you write a client without hard coding URIs (if it did, it wasn't particularly restful)?
How do you handle relationships between resources? How do you let clients create them, update them etc.?
How does the client discover which query resources are available? How does it find out about the parameters to pass etc.?
If your answers to these questions is: "My client doesn't need that / is not capable of doing that.", then Spring Data REST is probably the wrong library to begin with. What you're basically building is JSON over HTTP, but nothing really restful then. This is totally fine if it serves your purpose, but shoehorning a library with clear design constraints into something arbitrary different (albeit apparently similar) that effectively wants to ignore exactly these design aspects is the wrong approach in the first place.
I'm having a hard time wrapping my mind around something and would appreciate some reading material on this concept.
I'm writing an application that relies heavily on providing API calls via a URI scheme. example.com/company/user/123123. The aspects of taking a URI string and converting it to an action makes sense.
But where I get confused is taking that process and utilizing within the MVC structure. Do I build calls using models or a library? My goal is to be able to do something like $this->company->user(12311), so that I can have the API functionality available externally and internally.
Also how do I make this functionality accessible without exposing core code?
One of the biggest problems with the word API is that it does not make a distinction between when you are making local in process calls and when you are making remote calls. This is the essence of the RPC style, using the same programmatic model regardless of where the code to be executed exists.
REST is explicitly about doing distributed computing and is optimized for those scenarios. Trying to use a RESTful interface as a local API is likely to produce something that is highly inefficient.
I would suggest not trying to use the same API internally and externally and I would go further and say try not to think of REST as a way of building APIs. REST is an approach to building distributed systems that requires consideration of the system holistically.
To address your question more specifically, I use an MVC approach to exposing Resources in my system. The Model is the Resource and the View is the Representation. The key to building a RESTful system is to identify the links between your models. These links are rendered into the respresentations as embedded links. Also, consider that your models should be more like Presentation Models than domain models as a RESTful interface is more about exposing the usage scenarios of a system than it is about exposing a domain model.
We are developing a middleware SDK, both in C++ and Java to be used as a library/DLL by, for example, game developers, animation software developers, Avatar developers to enhance their products.
Having created a typical API using specific calls for specific functions I am considering simplifying the API by using a REST type API (GET, PUT, POST, DELETE) or CRUD type (CREATE, READ, UPDATE, DELETE) interface.
This would work in a similar way to a client-server type REST API where there are only 4 possible API calls but these can take flexible parameters.
This seems to have the benefit of making the API stable in that new calls are not being added and old calls are not being removed. So a consumer of this API need not worry about having to recompile and change their code to suit any updates to our middleware.
The overhead is that there is an extra layer of redirection in the middleware controller to route API calls and the developer needs to know what parameters are available for each REST call (supplied of course).
I have not so far seen this system used outside of web type client server applications so my question is this: Is this a feasible idea?
I am thinking in terms of its efficiency as well as if for example a game developer would find it easy to use.
Yes, this is a feasible idea. But I'm not sure the benefits would justify the costs. REST is best applied to a networked application scenario, oriented around requests and responses. While there are definite learning curve advantages to a uniform interface, those advantages can be present in almost any well-designed API which provides reasonably abstract procedures.
You also expressed concern for whether a game developer would find a RESTful API easy to use. I'd be dubious. I've implemented many RESTful web services, and helped many developers get up to speed both building them and using them, and the conceptual leap required to grasp REST can be substantial for someone who has been steeped in procedural APIs for years. I'd think that game developers in particular would be very strongly connected to procedural APIs, to the point that attempting to adopt a different paradigm, whatever its benefits, might prove extremely difficult.
Remember that REST is not specific to HTTP, and does not rely on just the 4 HTTP verbs. The verbs you have and can use depend on what protocol you're using.