It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
Reusability and abstraction is killing me; I've clearly been doing a lot of client-side development. CoffeeScript, Backbone, and Marionette have helped. Still, building completely reusable, modular "templates" - from the server-side and up - has not been possible. Let me describe a problem from the top down, and then maybe you can help describe the best stack.
I want to build a login widget that can be versioned and reused across multiple applications using the same framework (this is a basic whimsical example, take it with a few grains of salt). One large application is a bad idea, and they're hosted separately anyways. All the separate applications use the same API, hosted elsewhere, and no JSONP is acceptable.
Client-side
A login form would be comprised of a Marionette ItemView, some jQuery functions to handle all the fancy-dancy interaction, a Backbone "Account" model which handles various aspects of POST, GET, DELETE, and some basic html with the View is bound to. Normally, I'd have to explicity set the urlRoot for the AJAX interaction (see below), but I'd just like to be able to say '/' + #attributes.email, as it wouldn't matter what the ROUTE was, as everything is bundled together.
class Account extends Backbone.Model
# Normal
create: () ->
#urlRoot = () ->
'/account/' + #attributes.email
#save()
# Ideal
create: () ->
#urlRoot = () ->
'/' + #attributes.email
#save()
Server-side
This is built in accordance with the client-side (hopefully in Scala), and instead of explicitly defining a ROUTE somewhere:
POST /account/:email controllers.Account.create(password: String) # Play 2.0 syntax
I'd simply be able to say:
#POST(/:email?password=[String]) # Made up syntax
create(email, password) = {
# Hit external API
val json = WS.url('https://someapi/v1/account').withQueryParams('email=' + email + '&password=' + password).get()
# Return some response
Ok(json)
}
The application framework would know this module, or template, as #account() perhaps, and If I wanted to build a home page with login capability, I'd simply do something like:
<html>
Oh hey cool stuffz, sign up or login please
<right column>
#account()
<end right column>
#social() <!-- perhaps another template -->
<html>
What I envision is the application layer abstracting the client-to-server calls from the modules into GUIDs, perhaps, so making that `create account' call would really be doing something like:
POST /35395235/:email account.create(password: String)
While I understand this doesn't necessarily exist, I've stumbled upon Lift, and it seems relatively promising, but still not quite abstracted as I had hoped. Thoughts?
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
Was arguing with someone about REST API Design.
I have the routes GET /customers and GET /customers/<c-id> where c-id is the id of a customer.
Now the question is about adding a route for projects.
GET /customers/<c-id>/projects gives all projects of a customer. That someone suggested now to add GET /customers/<c-id>/projects/<p-id> to get information about one specific project. I have a bad feeling about that. Since p-id is a unique id for all projects, the c-id is not needed in the request at all. GET /projects/<p-id> should just do. c-id also is an attribute of the returned project json (every project belongs to just one customer). So this is the main question here: is it consistent with good practice to have the in my opinion superfluous c-id in the request?
One argument from the other side was this example from a blog:
GET /cars/711/drivers/4
But as far a I understand this only applies as good practice if 4 is not a unique identifier, but rather an enumeration in the example (the fourth driver of this car).
Further information:
Actually GET /projects is not used at the moment. So I also thought about adding it and using GET /projects?customerid=<c-id> instead of GET /customers/<c-id>/projects. What do you think about that?
Also the application in question has a permissions layer. So someone who's not allowed to access a specific customer should not be allowed to access projects of this customer, even if he knows the project-id. It was argued that this restriction is better expressed in the GET /customers/<c-id>/projects/<p-id> route. (The permission is actually decided upon a user-id attribute which is a property of customer and project likewise.) Would this change your answer to the question?
So this is the main question here: is it consistent with good practice to have the in my opinion superfluous c-id in the request?
Sure, why not?
REST doesn't care what spellings you use for URI.
Where I think you are getting tangled up; there is no rule that says each entity in your domain model must have one and only one resource associated with it.
It is perfectly acceptable to have resources like
/customers/<c-id>/projects/<p-id>
/customers/<c-id>/projects/<local-index>
/projects/<p-id>
/9e7b964a-c87a-4184-84b1-24132aabab66
that all map to the same concept in your domain model, and therefore return the same representations, or redirect to each other, or whatever.
It was argued that this restriction is better expressed in the GET /customers//projects/ route. (The permission is actually decided upon a user-id attribute which is a property of customer and project likewise.) Would this change your answer to the question?
No, because identification and security are orthogonal concerns.
Actually GET /projects is not used at the moment. So I also thought about adding it and using GET /projects?customerid= instead of GET /customers//projects. What do you think about that?
Same as before
/customers/<c-id>/projects
/projects?customerid=<c-id>
/a685ee45-f366-462b-a47a-dff61f98dd1e
... are all perfectly reasonable choices.
One thing which you may want to consider is RFC 3986, which specifies the rules for computing a new identifier given a base and a relative reference. Dot segments can be a convenient shorthand for directing the client to another reference without needing to worry about which base identifier is currently in scope.
We are discussing here two approaches.
To Divide url as custId + projId *
Yes. I will prefer this approach as well as it will be easy to handle authorization mechanism as compared to another approach.
If this is also case that 3 different customers have same project Id then also this type of structure will be helpful.
To access directly using project Id.
In this approach you will have to retrieve custId first and then check for authorization.
GET /customers/<c-id>/projects/<p-id> looks like a better option:
it clearly communicates that every project is assigned to one customer
it is clear that only when the user has access to /customers/<c-id> he can call /customers/<c-id>/projects/*
the fact that <p-id> are globally unique is an implementation detail and does not have to be communicated in the REST API
If your goal is to design a RESTful API which stands the test of time, your clients shouldn't really care what your URLs look like.
(i.e. embracing HATEOS)
In fact you should insist on your clients not trying to construct URLs based on some form of URL template.
If a client needs to get the list of projects for a customer, your hypertext (i.e. the resource representation returned to the client) should include an URL + instructions on how to do so.
That is how HTML handles it: You get a form URL and various HTML tags that describe how to add parameters to the URL to find a specific resource.
That's why you can have a generic client application (the browser) to - for example - a bank. The browser doesn't care what an account is, it just knows how to retrieve resources.
Going full REST is extra work that is worthwhile if you have no control over who your clients (the software making requests to your service) are and you are looking to evolve your API for many years to come without forcing unnecessary changes to your clients.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
Based on the articles I read, GraphQL is more resource-efficient in terms of roundtrips and it can also do what REST can provide. What are the reasons why software architect & developers might decide to stay with REST over GraphQL given that the web application will just be started from scratch? Also given that this is a continuous project, will be consumed from web and mobile and openID connect is a requirement.
This is a rather broad question but I'll try answer speaking from my own experience.
REST provides access to a specific resource, e.g. a user or a product. The result from a request will likely be an assumption of what data you will want or use, i.e. it's probably everything about that resource regardless of whether you use all the data or not.
There is also the problem of N+1. As an example, take the user has and belongs to many relationships scenario; with a RESTful API you would make a request to the user, e.g. /users/:id then make a request to all their relationships, e.g. /users/:id/relationships, so that's two requests already. There could be an assumption of the relationships endpoint to include both the relationship (friend, family member, etc.) and the user in the resulting array, but if the API doesn't make that assumption, you're going to have to make a request to each user endpoint to get the data on each user in each relationship.
This example can go deeper too; what if you want all second tier relationships (friends of friends for instance)?
GraphQL solves this by allowing you to ask for specifically what you need. You can construct a query to return the data at depth:
query myQuery($userId: ID!) {
user(id: $userID) {
id
name
relationships {
id
type
user {
id
name
relationships {
id
type
user {
id
name
}
}
}
}
}
}
Fragments could clean this up a bit and there may be recursive issues, but you should get the idea; one request gets you all the nested data you need.
If you don't have much need for such nested or inter-connected result sets, GraphQL may not offer much in a trade between benefit and complexity.
However, one of the greatest benefits I have found with GraphQL is its extensibility and self-documentation.
In my opinion, it is – among other aspects – also a question of use cases:
If you have something like an app or other frontend with a connection that is slow and/or has high latency (typical example: a mobile app), GraphQL’s “roundtrip minimisation” can be a big plus. And it can be pretty handy to give the client-side control over the data structure, thus often reducing the number of required API endpoints.
If it’s rather data exchange between servers, the fact that RESTful APIs are strongly related to HTTP, has advantages such as the semantics of verbs (which GraphQL cannot offer, as you perform several operations with one GraphQL query) and status codes. Plus: you get all the HTTP caching functionality for free, which can be really important in heavily data-driven applications/services. In addition, REST is ubiquitous (although probably most APIs advertised as “RESTful” aren’t, often due to missing support for hypermedia).
There might be multiple reasons. This is very subjective I believe, but to me it's based on:
REST is the old and steady way. It is used by the most and provides an easy interface to API consumers. Because it's old (by no means a bad thing) most developers know of it and know how to consume it.
GraphQL is the new guy in town. It sure does save some performance (roundtrips and payload) for most systems, but does change the way we think of a backend. Instead of providing resource endpoints, it provides the graph of the data model and let the consumer decide what data to get.
As of the point of the "new guy", GraphQL is not as battle tested. It is new to most and there fore not adopted by others and the first-movers and startups, basically.
But again, this is a subjective question with a subjective answer. Currently I am using GraphQL for a startup to test it's durability and see if it can solve our needs. So far, it does by far. If you are to make a decision on wether to start a new project with REST or GraphQL you should be consider your needs and how much money/time you want to spend learning new vs. doing what you know and get to your goal faster.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
There has been a lot of hype over REST last few years, and I've tried to embrace the principle and understand it's benefits. Some things about REST still elude me, though. I'll try to be concise and to the point:
Can a web application be considered RESTful? What are the benefits of this? I can understand (to a point) advantages of RESTful service, which is to be used by many clients, but what is gained by using REST principles when developing application interface which is to be consumed by HTML/JS frontend?
REST mandates use of verbs which roughly map to CRUD operations and to which the server responds with representations which in turn put client in a new state. Does this imply that ALL actions on a resource must be done through modification/creation/deletion of that and possibly many other related resources? What about "atomicity" of such operations (i.e. transactions)?
REST compliant service is supposed to be self-descriptive (through HATEOAS principle), but the lack of metadata makes it impossible for a client to e.g. create a resource without knowing exactly what fields (and their types) are mandatory. This information must still be provided out-of-band. Is there something I'm missing here?
I could come up with more questions, but it will be enough for now if someone could clarify these points for me.
Some notes about your questions:
1) If your web application is a Single Page Application the simplest way to communicate with the server will be if it is a Rest service.
For a traditional web application I think is better that "controllers" communicate with a service layer using dependency injection.
3) Yes, of course the client needs to know the format of the data it is receiving. But AFAIK, Rest does not give any constrain about how this metadata has to be defined or transmitted.
The HATEOAS principle refers more to the discovering of related resources from a given one.
There exists different conventions to express that relations, see for example:
http://stateless.co/hal_specification.html
2) Every Rest action must be atomic. If you need a some kind of long operation, the usual is to create a resource that describes the operation. The state of the operation is retrieved from that resource, and you do whatever you want with the operation (i.e. Cancel it) interacting with that resource.
See an example of that here.
1.Usually REST architecture is designed when application is going to be used by different
by nature clients(external api consumers, mobile applications etc). In this case development costs will be paid back completely.
Developing truly REST application is not such a simple task to do. So,
if you know in advance that your application is to be used only by your client-side, probably,
you could consider 100% RESTfull approach as an overhead. But it does not mean
that you should not design your application well, you still could use some of REST principles in your application.
For example, stateless application simplifies scaling, REST-style URLs looks good for users and search engines, etc.
2.Yes, in truly REST all interactions should be expressed via standard verbs on resources.
But you could still create Transaction resource to wrap around your transaction.
See great discussion here: Transactions in REST?
3.As I understand nothing prevent you from providing metadata-information in HATEOAS-based response.
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
When I create a servlet application, I deploy the war file on the app server and hit the servlet url and provided there is a proper mapping, I will get to my page.
Now if it is a portlet application, just deploying the portlet on the portal server does not do the job. We also have to login to the portal, and basically 'add' the portlet by going to 'manage pages'. What exactly are we doing in this step? And why is this step necessary? We do not need to do this for a servlet application.
My other question is that in a portal server, there seems to be two kinds of admin consoles...one which resembles a standard WAS admin console. The other is where you Manage pages and do other kinds of stuff. Why do we have two kinds of consoles?
Is it just that the added functionality could not be designed into the standard WAS console because IBM wanted to reuse WAS console for Portal server?
The first thing you should probably understand is that portlets are not servlets. Even though, portlet containers may use servlets underneath portlets (which I'm not even explicitly sure about), the programming model is different and you will need to mindful of that when designing and implementing solutions with them.
Portlet applications can be directly referenced by the context root you defined when you installed it. However it's the portlet container that what will call your doView, processAction, etc methods and help maintain the state of the portlet and the navigation state of the user. Adding the portlet to a page let's Portal know where you want the portlet to be available in the page model.
You have two administration consoles because WebSphere Portal runs on top of WebSphere Application Server. That is the standard WAS admin console you're using there. You'll use it to administer your standard WAS stuff (servers, database connections, web services, etc). The Portal Admin console is there to administer portlet specific specific things, such as the page model, portlets, themes, etc.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I have been unable to make a definitive choice and was hoping that somebody (or a combination of a couple of people) could point out the differences between using RestSharp versus ServiceStack's client services (keeping in mind that I am already using ServiceStack for my service). Here is what I have so far (differences only). The list is fairly small as they are indeed very similar:
ServiceStack
Pros
Fluent Validation from my already created service POCO objects
One API for both client and service
Code reads better (i.e. Get<>(), Post<>())
Cons
Some of my strings must be written out (i.e. If I make a GET request with query parameters, I must create that string in my code)
I must create a different class for each Request/Response Type (JsonServiceClient, XmlServiceClient)
RestSharp
Pros
Just about everything can be a POCO (i.e. If I make a GET request with query parameters, I just add the parameters via code)
Switching between Request/Response types is simple (request.RequestFormat = DataFormat.Json/Xml)
Cons
Manual Validation (beyond that found in the Data Annotations)
Two APIs to learn (this is minor since they are both fairly simple)
Code is not as readable at a glance (barely) (i.e. request.Method = Get/Post.. and main call is Execute< T >())
I was leaning towards RestSharp since it tends more towards straight POCO use and very little string manipulation, however I think ServiceStack might be acceptable to gain the validation and code that is more easily read.
So, here are the questions:
Which do you prefer?
Why the one over the other?
I know this is not a totally subjective question, but at bare minimum I am looking for the answer to this question (which is subjective):
Are any of my findings incorrect and/or are there any that I missed?
As the project lead of ServiceStack I can list some features of the ServiceStack Service clients:
The ServiceStack Service Clients are opinionated in consuming ServiceStack web services and its conventions. i.e. They have built-in support for structured validation and error handling as well as all clients implement the same interface so you can have the same unit test to be used as an integration test on each of the JSON, JSV, XML, SOAP and even Protobuf service clients - allowing you to easily change the endpoint/format your service uses without code-changes.
Basically if you're consuming ServiceStack web services I'd recommend using the ServiceStack clients which will allow you to re-use your DTOs you defined your web services with, giving you a typed API end-to-end.
If you're consuming a 3rd Party API I would recommend RestSharp which is a more general purpose REST client that is well suited for the task. Also as ServiceStack just returns clean DTOs over the wire it would also be easily consumable from RestSharp, which if you prefer its API is also a good option.
UPDATE - Using ServiceStack's HTTP Client Utils
ServiceStack now provides an alternative option for consuming 3rd Party APIs with its HTTP Client Util extension methods that provides DRY, readable API's around common HttpWebRequest access patterns, e.g:
List<GithubRepo> repos = "https://api.github.com/users/{0}/repos".Fmt(user)
.GetJsonFromUrl()
.FromJson<List<GithubRepo>>();
Url extensions
var url ="http://api.twitter.com/statuses/user_timeline.json?screen_name={0}"
.Fmt(name);
if (sinceId != null)
url = url.AddQueryParam("since_id", sinceId);
if (maxId != null)
url = url.AddQueryParam("max_id", maxId);
var tweets = url.GetJsonFromUrl()
.FromJson<List<Tweet>>();
Alternative Content-Type
var csv = "http://example.org/users.csv"
.GetStringFromUrl(acceptContentType:"text/csv");
More examples available from the HTTP Utils wiki page.