It appears most of the WebAPI examples are returning some models (either domain models or particular view models).
When using domain models, we actually request more data than needed in the view from ajax calls, and then build our view models using JavaScript (assuming we are building a web app).
I tried using different view models for each page (view), which allow me to reduce the network footprint and return only the fields in need. But in the ApiController I would have too many GET methods. And it is impossible for us to predict the future need and build an API returning all kinds of view models.
I would like to mimic the Facebook Graph API and build a uri like:
http://... api/games/333?fields=id, name, price, imageUrl
And our user should be able to update the record with only these few fields.
A detailed description can be found in a google code blog entry: Making APIs Faster: Introducing Partial Response and Partial Update.
Some other posts here suggest this is beyond the current ability of ASP.NET WebAPI. Will ServiceStack or some other package help us achieve the goal?
Try this project: https://github.com/AnthonyCarl/ServiceStack.PartialResponse for the partial response side of the question
ServiceStack.PartialResponse.ServiceModel
Google Style Partial
Responses for ServiceStack.Net. Currently only the following Content
types are supported:
application/json
application/jsv
text/html
application/xml is NOT currently supported.
I wanted to implement this as a ServiceStack IPlugin, but I was unable
to figure out how to get the access I needed to the response DTO for
my approach. Currently, this is implemented as an IRequestContext
extension.
Providing Field Selectors
Field Selectors can be passed using the header or query string. By
default field selectors are combined form both. Duplicate field
selectors are reduced. The field selector is applied to all entries in
a list if the selector refers to a list.
There are a couple of options to implementing partial updates in ServiceStack. See this question about implementing PATCH requests for an approach that uses a request DTO with nullable values, and the PopulateWithNonDefaultValues and similar extension methods in ServiceStack, to take a PATCH-style request where the client can send any subset of fields in the request body. If a given field is not present in the request body, then that property of your domain object will not be updated.
If you really need to use a query string to specify the subset of fields that should be updated, then you can still use the approach described above, but add some code that first nulls out any values in the incoming request DTO object that are not named in the query string. Then you can again use PopulateWithNonDefaultValues to copy the remaining values to the domain object.
Also, to comment on another part of your post that is closely related to the recommendations I just gave:
When using domain models, we actually request more data than needed in the view from ajax calls...
Here is where a message-based design is helpful: model your request/response messages as separate DTO classes, instead of reusing and exposing your internal domain model objects. Among over benefits, you'll eliminate the problem of exposing unnecessary fields in your request/response models. Message-based design is one of the core concepts that drives ServiceStack's implementation. You could, though, achieve similar results with Web API or MVC. I highly recommend reading this article that discusses how this design works in ServiceStack.
You can use OData Protocol,look this example.
It's can use key:$select,$expand,$filter for search,select some fileds.
Most important,the ASP.NET WEB API has a SDK for support this.
Related
I've seen a lot of REST implementation examples.
According to them, create endpoint has several options for response body:
no body at all;
id of the created entity;
created entity JSON.
For example, we have a table with data and create a form on the same page on UI.
And we don't want to reload the full page after creating a new entity.
In this case, we have to call our API two times to correctly update our data:
POST to create an entity;
GET to get a list of entities.
We can't just add a new entity JSON from the response body for a list on UI e.g. if we have pagination/sorting on the server-side.
Based on this information, I have a question. Could a creating/updating endpoint return a resulted list immediately? Or does it violate some best practices? And why?
We can't avoid a second call to a database, but we can avoid a second request to an API.
Could a creating/updating endpoint return a resulted list immediately?
Yes
does it violate some best practices?
No
And why
Because REST is the architectural style of the world wide web.
You GET a web page. It includes a form. You fill in the fields and submit the form. What do you get back...?
Another web page.
When you are creating a machine to machine interface, the same basic ideas hold. There are just a few simple changes
You probably don't want to use media types that are designed for describing displays for human beings, instead preferring something more compact
You want stable semantics, because machines aren't as adaptable as humans when it comes to interpreting implicit schema.
I don't have Gateway available in my landscape and I want to use the ABAP REST library to expose web services: SAP Library - REST Programming Tutorial
With a very simple example, I successfully created a class to read a single domain list of values, the GET call is quite simple:
http://mydomain/domainvalues/XFELD
And the GET implementation is in my class ZCL_REST_DOMAIN_VALUES extending from CL_REST_RESOURCE implementing IF_REST_RESOURCE~GET method.
Now I want to make it possible to read or query multiple domains. I'm not an expert in REST but I've seen two options searching around, one using the same URI as the single entity and one with special URI for queries.
http://mydomain/domainvalues?Id=XFELD,WERKS_D
http://mydomain/query/domainvalues?Id=XFELD,WERKS_D
In the backend, should I use the second approach and create a class only for this call named for instance ZCL_REST_DOMAIN_VALUES_QUERY implementing the GET method again?
Or maybe should I use POST method to send the list of IDs to fetch in the body?
SAP's own in-house guidelines recommend to shape OData and plain REST services alike, to avoid confusion and facilitate switching between the two:
http://mydomain/domainvalues?$filter=Id in ('XFELD', 'WERKS_D')
Both would be served by the same REST endpoint handler class, although of course you are free to create separate methods or delegates for the cases.
Remember to sanitize (= whitelist/blacklist/escape) the query parameters before handing them over to some lower level to prevent SQL injection attacks, as #SandraRossi correctly pointed out below.
Background
I am developing my first webapi2 rest interface for some products/batches/packs etc. I read this excellent page on how to make a good rest api and i'm stuck on a few concepts and my googling skills have failed me.
I would like to give the developer the option to embed or sideload sub resources to prevent repeated api hits for child/sub-resource data (i.e return all packs with a batch). I would also like them to be able to specify which fields they would like to return.
I'm used to a normal MVC/WebApi style of creating a Method and its own or shared ViewModel and sending down that in its entirety. If I need to send less data I create a slimmer ViewModel.
Question
What return type do I put on the rest endpoint, is it just a JObject that I construct manually depending on what fields they've requested (and the developer has to rely on the documentation to figure out what it could return)?
Or do I create a fat view model and somehow mark the fields as optional with the ability for the JSON/XML converter to omit these fields if the value is null etc (but then how do I side-load sub-resources...)?
Thanks, Pete
I have decided to use OData v4 so that I can allow the client-app to decide on what and how to consume the data i'm exposing. It doesn't support sideloading (that i've discovered so far) but it allows me to embed, filter and slim down any models easily.
One of the goals of the REST API architecture is decoupling of the client and the server.
One of the questions I have run across in planning a REST API is: "how does the client know what is a valid payload for POST methods?"
Somehow the API needs to communicate to the UI what a valid payload for a given resource’s POST method. Otherwise here we are back at depending on out-of-band knowledge being necessary to work with an API and we are tightly coupled again.
So I’ve had this idea that the API response for a GET on a resource would provide a specification for constructing a valid payload for the POST method on that resource. This would include field names, data type, max length, etc.
This guy has a similar idea.
What's the correct way to handle this? Are most people just relying on out-of-band information? What are people doing in the real world with this problem?
EDIT
Something I have come up with to solve this problem is illustrated in the following sequence diagram:
The client and the api service are separate. The client knows:
Entry point
How to navigate the API via the hypermedia.
Here's what happens:
Someone (user) requests the registration page from the client
The client requests the entry point from the API and receives all hypermedia links with appropriate meta data on how to traverse them legally.
Client constructs the registration form based on the meta data associated with the registration hypermedia POST method.
User fills in the form and submits.
Client POSTs to the API with the correct data and all is well.
No magic /meta resouces, no need to use a method for the meta data. Everything is provided by the API.
Thoughts?
Most people are relying on out-of-band information. This is usually ok, though, because most clients aren't being built dynamically, but statically. They rely on known parts of the API rather than being HATEOAS-driven.
If you are developing or want to support a metadata-driven client, then yes, you're going to need to come up with a schema for providing that information. The implementation you linked to seems reasonable after a quick skim. Note that you've only moved the problem, though. Clients still need to know how to interpret the information in the metadata responses.
Your are right, the client should understand the semantics of the links in the response, and choose the right one from them to achieve its goal. The client is coupled to the semantics the API provides about this and not to the API itself. So for example a client should not retrieve information from the URI structure, since it is tightly coupled to the actual API.
I know of 2 current solution types about this:
by HAL+JSON you use IANA link relations to describe what the link does, and vendor specific MIME types to describe the schema of the fields
by JSON-LD (or any other RDF format) with Hydra vocab you send back RDF metadata according to the operation the link calls. This meta-data can contain the validation details of the fields (xsd vocab) and the semantics of the fields (microdata, microformats, etc...). This information is completely decoupled from the API implementation, so it might be a better option than using vendor specific MIME types, but Hydra is still under development and HAL is much simpler.
However your solution is valid as well, I think you should check both of these, since they are already standard solutions, and the uniform interface / self-descripting message constraint of REST encourages the usage of existing standards instead of custom solutions. But it is up to you if you want to create an own standard.
I think you are asking about, Rest API meta data handling. Unlike SOAP, Rest APIs doesn't use meta data normally, but sometimes it can be pretty useful, once your api size gets bigger.
I think you should look into swagger. It is the most elegant you can find out for rest apis. I have being using it for sometime and with the annotation support it is being rather easy to work with. It also has many examples found on github. Other advantage is, it contains nice configurable ui.
Apart from that you can find other ways of doing it like WADL and WSDL 2.0. Even-though I haven't being using them, you can read more about them here.
With RFC 6861, you can link to your form with create-form and edit-form Link Relations, instead of the client constructing the form by itself. The corresponding form should have the necessary schema to construct the POST request.
I am trying to implement HATEOS based REST service for hotel booking but have this confusion:
1) How does apart from WADL, the client comes to know about possible operations and their corresponding URI. Should I put all possible operations and URI as response when the client hits the root of REST service?
2) When the client gets a list of all accommodation options in an area, I am returning a list of all hotels in the area he asked about. The response contains:
<accommodation>
<hotel info="http://welco.me/hotel/xxxxxx" price="5000"/>
<hotel info="http://welco.me/hotel/yyyyyyy" price="3000"/>
</accommodation>
But the query I have here is how the client is going to know about other related possible operations like getting the list in sorted order of price?
In answer to your first question, there are a couple of specs for documents that allow clients to discover RESTful APIs.
Swagger
JSON Home
Google use their own Discovery Service, however unlike Swagger and JSON Home, unfortunately I don't think there are open sourced libraries that help you use expose it for your own APIs.
For Your second questions again, I would tend towards clients/developers discovering parameters such as sorting from the Swagger/JSON Home document. However if it is a super strong/important relationship you could also return it in the responses as linked data:
In HAL you can provide a links object with links to related resources.
In JSON-LD you can add a field with a value of the related API url. You may then add an #content to add information describes what that relationship means.
You should use link hints. An older way of doing this, the OPTIONS method, has some longstanding caveats.
Include links that use a custom link relation something like http://welco.me/#sort-by-price where you define the URI to mean whatever you want it to. You should provide some developer documentation at that URI but the client app will never dereference it, it merely uses the URI as an opaque string for equality comparisons.