Swagger, YAML: Request and Response object models are same except one field - enums

I'm defining swagger definitions for an API and I came across this use case.
The request and the response object model definitions look exactly the same.
However, there is one field in the object which returns more enum values during the get operation but restricts to minimal enum values for the put operation. Is it possible to reference different enum values for the same field conditionally thus avoiding duplicate definitions. I do not want to recreate the entire model definitions for request and response for the sake of overcoming this limitation.
Here is my example,
definitions:
EntryRequest:
properties:
entries:
$ref: '#/definitions/EntityResponse/properties/entries'
EntryResponse:
properties:
entries:
type: array
items:
$ref: '#/definitions/Entry'
Entry:
properties:
entryStatus:
type: string
enum:
- ENABLE
- DISABLE
- IN_PROGRESS
In the above, there are two things that I'm worried about.
1) For EntryRequest, the API accepts only ENABLE/DISABLE for PUT operation while the API returns all of them in the GET operation. I would like to create a reference to the entryStatus property conditionally. Is it possible?
2) Also, everything except the entryStatus is same for both the EntryRequest and EntryResponse object model. I do not want to duplicate that as well for the sake of representing the differention of entryStatus field.
Is there a way to do it?
EDIT:
As I learn more on this, I get a feeling that this is more an yaml related query. But I would like to have it here to see if anyone has faced a similar situation and how they have handled it. Or to see if I get any recommendations on how to handle this.
For tagging different enums to the same field, I think I can do like this,
RequestEntryStatus:
type: string
enum: &requestStatus
- ENABLE
- DISABLE
ResponseEntryStatus:
type: string
enum: &responseStatus
- ENABLE
- DISABLE
- IN_PROGRESS
Entry:
properties:
entryStatus: *requestStatus
But still this would enforce me to create duplicates of request and response objects with different mapping to the entryStatus field. I would like to know if there is a better way to handle this.

The request and the response object model definitions look exactly the same. However, there is one field in the object which returns more enum values during the get operation but restricts to minimal enum values for the put operation. Is it possible to reference different enum values for the same field conditionally thus avoiding duplicate definitions. I do not want to recreate the entire model definitions for request and response for the sake of overcoming this limitation.
No, it's not possible.
If you want to avoid duplication, you can use a single model with all the enum values, but document verbally in the description that certain values are only used in the responses but not the requests.

Related

when to use explicit relations - schema design

I am pondering about schema design with regard to explicit vs implicit relation when to...
for example:
in an imaginary schema with 2 custom types author and post, each with several properties, A post type can reference an author in 1 of 2 ways:
explicit: having an Autor type property
implicit: having a scalar value that indirectly points to the author
when designing a shema. what should be my compass in this kind of desicion making?
thanks in advance
There's absolutely no value to the client in only returning the ID of a related resource when you could just expose a field that would return the entire resource. Exposing only the ID will mean the client will have to make subsequent requests to your service to fetch the related resources, instead of being able to fetch the entire data graph in one request.
In the context of other services, like a REST API, it might make sense to only return the ID or URL of a related resource. This is because in those cases, the payload is of a fixed size, so returning every related resource by default can quickly and unnecessarily bloat a response. In GraphQL, however, request payloads are client-driven so this is not a concern -- the client will always get exactly what it asks for. If the client needs only the author's ID, they may still fetch just that field through the author field -- while allowing a more complete Author object to be fetched in other requests or by other clients.

How to support patch rest request with protobuf 3

We often have use cases where we only want to update a subset fields on a resource. So if we have a resource Person:
type Person struct {
Age int
Name string
Otherfield string
}
Say the calling client only wants to update the Age field. How would an endpoint be normally set up to handle this?
I believe this should be done with a PATCH request, with only the fields being set as part of the payload, ie:
{
Age: 21
}
However, this won't work with proto3 because as far as I know there are no null fields, only default values. This won't work in many cases where the default value is valid.
Looking at Google own protobuf files (e.g. here), they use FieldMask for partial update.
FieldMask object is passed along with the request, and has the form (in JSON):
{
mask: "Person.Age"
}
This allows the client to tell the server which fields they wish to update, without counting on the partial message itself to figure this out.
I think this adds unnecessary complexity on (each!) client, but we couldn't find any other way to achieve partial updates with proto3.
You can see full documentation of FieldMask here.
Note that it can also be used to filter out responses if the client doesn't need the entire object.

OData $filter substringof applied to a list of strings

I have an ASP.NET Web API Controller that exposes an IQueryable(Of String) - which is a list of descriptions. These fields can be in the order of tens of thousands, thus I use $top and $skip to only get a chunk of it - that works fine.
Now I am trying to filter these results, through the OData substringof('mydesc',Property) filter. As you can see, it requires for me to pass in a Property name on which to filter. However, since I'm returning a list of strings, I don't actually have any properties to filter on.
This causes the server to return errors like
No property or field 'tostring' exists in type 'String' - when called with $filter=substringof('asd',tostring).
If I change the call to $filter=substringof('asd',''), no errors are thrown, but no results either.
My question is, can I somehow format the $filter operator to find substrings within my list of strings, without looking for a property/field, or am I going to have to declare a class with a single property, just to enable filtering?
Things have changed since the last time I answered this. OData V3 has support for querying collection of primitives using '$it'. Asp.net Web API supports this syntax as well. For example, in your controller you can return IQueryable<string> and send a request like
$filter=substring('mydesc', $it) or
$filter=length($it) ge 5
etc. You can also expose collections of other primitives like IQueryable etc.
unfortunately declaring a class with a single property seems to be the only solution that I can think of. OData $filter doesn't have any support for something like the this parameter in C#
another less obvious approach is to expose a computed concatenated value representing the list, substringof could then be used to query the list as a single property value

Drupal6: Load a field, like one would load a node?

Is there a field_load() function equivalent to node_load()? I want to get information about the type of a field and other validation constraints without going to the database myself.
Better yet, is there any function that will validate it for me, like is_valid_for_field(field_name, input), that would take a field name and a potential input and return a boolean indicating whether or not the potential input is valid (within min/max, etc) for the specified field?
There is the content_fields() function, which will get you the meta data for a field. In terms of validation, IIRC, you can call content_field() with the operation set to validate, and the relevant data. However, by calling node_save with your completed node, the cck module will take care of all the relevant validation hooks for the entire node structure, so you may be better off taking that route.

GET vs POST in AJAX?

Why are there GET and POST requests in AJAX as it does not affect page URL anyway? What difference does it make by passing sensitive data over GET in AJAX as the data is not getting reflected to page URL?
You should use the proper HTTP verb according to what you require from your web service.
When dealing with a Collection URI like: http://example.com/resources/
GET: List the members of the collection, complete with their member URIs for further navigation. For example, list all the cars for sale.
PUT: Meaning defined as "replace the entire collection with another collection".
POST: Create a new entry in the collection where the ID is assigned automatically by the collection. The ID created is usually included as part of the data returned by this operation.
DELETE: Meaning defined as "delete the entire collection".
When dealing with a Member URI like: http://example.com/resources/7HOU57Y
GET: Retrieve a representation of the addressed member of the collection expressed in an appropriate MIME type.
PUT: Update the addressed member of the collection or create it with the specified ID.
POST: Treats the addressed member as a collection in its own right and creates a new subordinate of it.
DELETE: Delete the addressed member of the collection.
Source: Wikipedia
Well, as for GET, you still have the url length limitation. Other than that, it is quite conceivable that the server treats POST and GET requests differently; thus the need to be able to specify what request you're doing.
Another difference between GET and POST is the way caching is handled in browsers. POST response is never cached. GET may or may not be cached based on the caching rules specified in your response headers.
Two primary reasons for having them:
GET requests have some pretty restrictive limitations on size; POST are typically capable of containing much more information.
The backend may be expecting GET or POST, depending on how it's designed. We need the flexibility of doing a GET if the backend expects one, or a POST if that's what it's expecting.
It's simply down to respecting the rules of the http protocol.
Get - calls must be idempotent. This means that if you call it multiple times you will get the same result. It is not intended to change the underlying data. You might use this for a search box etc.
Post - calls are NOT idempotent. It is allowed to make a change to the underlying data, so might be used in a create method. If you call it multiple times you will create multiple entries.
You normally send parameters to the AJAX script, it returns data based on these parameters. It works just like a form that has method="get" or method="post". When using the GET method, the parameters are passed in the query string. When using POST method, the parameters are sent in the post body.
Generally, if your parameters have very few characters and do not contain sensitive information then you send them via GET method. Sensitive data (e.g. password) or long text (e.g. an 8000 character long bio of a person) are better sent via POST method.
Thanks..
I mainly use the GET method with Ajax and I haven't got any problems until now except the following:
Internet Explorer (unlike Firefox and Google Chrome) cache GET calling if using the same GET values.
So, using some interval with Ajax GET can show the same results unless you change URL with irrelevant random number usage for each Ajax GET.
Others have covered the main points (context/idempotency, and size), but i'll add another: encryption. If you are using SSL and want to encrypt your input args, you need to use POST.
When we use the GET method in Ajax, only the content of the value of the field is sent, not the format in which the content is. For example, content in the text area is just added in the URL in case of the GET method (without a new line character). That is not the case in the POST method.

Resources