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.
Related
Imagine I have a Razor Page or such like. Imagine the data used by that Razor Page is not used by any other page at all. So the data retrieval is very specific to this page only.
Is it bad practice to just grab the data directly using a database connection from within that Razor Page local to the only place that data is to be used?
If so, why should I abstract the data away into a separate API that isn't re-used anywhere? Why is it good practice?
It seems to me, that REST APIs are sometimes used unnecessarily and for no good reason. As if because every example video shows data retrieval from REST APIs. Correct me if I am wrong.
If your application is purely a server-side app, there is no justification for creating RESTful API that serves up JSON for it. Those kinds of APIs are usually created for "external" consumers, by which I mean third parties or the browser (via JavaScript). They are commonly implemented for client side apps - single page apps typically like React, Angular or Blazor where JSON is the data format of choice for the browser.
As to whether you should open database connections in your PageModel class, that's another question. For simple apps, why not? But for apps that need unit testing, it's not a good idea. You will be unable to execute unit test against the PageModel class without hitting the database.
As a habit, I tend to put the code that connects to a database in a series of separate classes, each one having an interface, and then inject them into the PageModel via dependency injection. That way I can mock the service represented by the interface for unit testing.
You might want to implement services that generate data as JSON within a Razor Pages app if you have some functionality that depends on Ajax requests for data. For those, you could use Web API controllers, minimal request handlers or even named handler methods that return JsonResult objects in the PageModel classes. With all of those, you might still want to put the code that actually calls the database in a separate class that is injected into the handler.
I am using making two http calls to Assyst REST api to fetch Priority value and closure action value like as follows.
> http://localhost:8989/assyst/assystGOLD/Priority?shortCode=%225%22&fields=name,shortCode&fmt=xml
> http://localhost:8989/assyst/assystGOLD/ActionType?shortCode=%22closure%22&fmt=xml
Now I want to merge these two url's to work in a single call. So I made below URL, but no luck.
http://localhost:8989/assyst/assystGOLD/ActionType?shortCode=%22closure%22&Priority?shortCode=%225%22&fields=name,shortCode&fmt=xml
Can anyone help me on this?
This isn't possible I'm afraid. The REST API only works with a single resource (Priority and Action Type in your example) in each request. You need to make two requests to get these two unrelated pieces of information.
Your example is using the legacy API's syntax. I recommend using the new REST API for new development - it is embedded within the main assyst Enterprise application and has much improved performance.
Paul
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.
I developed a REST API with Play 2.2.0. Some controllers expose GET methods, other expose POST methods with authentication etc...
I developed the client using Play as well but I have a problem. How can I avoid duplicating the model layer between both applications ?
In the server application, I have a Model Country(code, name).
In the client I am able to list countries and create new ones.
Currently, I have a class Country in both sides. When I get countries I deserialize them. The problem is that if I add a field in Country in the server, I have to maintain the client as well.
How can I share the Country entity between applications ?
PS : I don't want to create a dependency between the API and the client, as the client could have been developed with another language or framework
Thanks
This is not very specific to play framework but is more of a general question. You either create reusable representations of the data in your protocol (the actual data structures you send between your nodes) and get a tight coupling in representation and language. Many projects does it like this, since they know they will have the same platform throghout their architecture.
The other option is to duplicate all of or only the parts of parsing/generating that each part of the architecture needs, this way you get a looser coupling and can use any language in the different parts.
There are also some data protocols/tools that will have a representation in a protocol specific way and then can generate representations in various programming languages.
So as you see, it's all about pros and cons - neither solution is "the right way (tm)" to do this, you will have to think about your specific system/architecture and what pros are most valuable and what cons are most costly to you.
Well I suggest to send to the client a template of what they should display, on the client with js take advantage of js template frameworks, so you can tell to the client how can show them, dynamic... if they want to override them well... more job
We can call them Rest component oriented...
well suggestions :)
should works!
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.