How to specify a "year" field in openapi v3 / swagger? - date

I want to define an API using openAPI v3. One of an object's properties will be a year. My current definition looks like this:
"fieldname": {
"type": "string",
"format": "date",
"pattern": "\d\d\d\d"
}
Is this a valid description? Or is there a predefined or better fitting description of such fields?
What is the most precise and semantically valuable, yet correct way to specify such properties?

Related

JSON Schema reference using an empty fragment

I am using OpenAPI specifications and have found reference tags that point to an empty string (empty fragment). Is this a correct reference? If yes, how is this reference to be interpreted? What does it point to, and what value is determined to be correct when the OpenAPI spec is validated?
I have examined the OpenAPI drafts as well as JSON Schema drafts but they do not mention how to handle this, nor do they have any examples or guidance on what constitutes correct behaviour.
Any help is appreciated.
Below is an example... note under the Amount/Amount there is a "$ref": ""
(this example is a portion of Balances specification in the UK Open Banking model)
:
:
"Amount": {
"type": "object",
"required": [
"Amount",
"Currency"
],
"description": "Amount of money of the cash balance.",
"properties": {
"Amount": {
"$ref": ""
},
"Currency": {
"$ref": "#/components/schemas/ActiveOrHistoricCurrencyCode_1"
}
}
}
:
:
The reason you don't find this spelled out in either spec is because both defer to RFC-3986 to define how URIs are resolved. That means URI resolution in JSON Schema and OpenAPI work exactly the same as HTML and therefore should be familiar to most web developers. The Understanding JSON Schema site has a section that explains how RFC-3986 URI resolution works in the context of JSON Schema.
In this case, the base URI is the location of the document. It might be on the file system: file:///path/to/myapi.openapi.json, or it might be on web http://example.com/myapi.openapi.json. The relative reference URI found in $ref is resolved against this base URI. Resolving an empty relative reference against the base URI results in a URI that is the same as the base URI.
That means that in your example, this $ref is referencing an OpenAPI document instead of a JSON Schema, which is not allowed in JSON Schema. A $ref in a JSON Schema can only reference a JSON Schema. This appears to be an error in the OpenAPI document you're working with.
However, that doesn't mean an empty $ref is always invalid. In a JSON Schema document (not embedded in an OpenAPI document) you could use this to define a recursive structure. Usually you'll see recursive references defined as "$ref": "#" instead of being empty, but there isn't any good reason to include the #. You should end up in the same place either way.

Specifying RESTful API Response Based on Query Parameter in openAPI

I am designing an openAPI specification for a project. The project is a REST API that provides information about hotels.
I want to either provide detailed information about the hotel, or a quick summary. My understanding of REST is that, since both of these relate to the same object in my data store, I should be using a query parameter to request the different data types.
So what I am looking for is a way to specify different API behaviors based on query parameters of a given request. Here is my current implementation. I am looking at an endpoint like this:
/hotels/{hotelId}?detail={detailLevel}
where {hotelId} is an integer and {detailLevel} is an optional string enum that can either be summary or robust.
If detail=robust, the response should look something like this:
{
"name": "Hilton Grand Vacations on the Las Vegas Strip"
"streetAddress": "2650 Las Vegas Blvd S",
"city": "Las Vegas",
"state": "NV",
"zipCode": 89109
"rating": 4.4,
"minimumPrice": 125,
"availableRooms": 10,
}
If detail=summary, the response should look something like this:
{
"name": "Hilton Grand Vacations on the Las Vegas Strip",
"rating": 4,
"zipCode": 89109,
"available": true
}
I don't want to have a specification that covers both of these responses, because I want to make it easy to validate any given response based on its URL parameter (for example, "available" should not be a field when detail=robust). So far, I have not been able to find a way to specify different return behaviors in openAPI based on query parameters.
Is there a way to specify behavior based on query parameters? Alternatively, should I change my API endpoint to something like /hotels/{hotelId}/{detailLevel}?
To my disappointment, I have learned that openAPI does not support to use of query parameters to differentiate endpoints with the same path.
I will be specifying my paths as /hotels/{hotelId}/{detailLevel} instead.

Schema.org Accommodation with price?

I'm attempting to add a schema for an Accommodation, but I can't seem to find a way to reference the 'offer' or 'price' to this schema. Im using JSON-LD to format this schema.
I have also tried room/hotelRoom as an alternative. I also tried using the additionalType value to allow me to use product based options such as offers, but this didn't work.
JSON-LD:
{
"#context": "http://schema.org",
"#type": "Accommodation",
"additionalType": "Product",
"name": "example",
"offers": {
"#type": "Offer",
"name": "1 Night",
"priceSpecification": {
"#type": "PriceSpecification",
"price": 1,
"minPrice": 1,
"maxPrice": 2,
"priceCurrency": "GBP"
}
}
}
Google Structured Data Testing Tool:
The property offers is not recognized by Google for an object of type Accommodation.
How am I meant to add a price to a specific accommodation/room in my schema?
Schema.org intends¹ that authors use MTEs² in this case. That, however, does of course not necessarily mean that all consumers fully support this (yet).
So instead of:
"#type": "Accommodation",
you would use:
"#type": ["Accommodation", "Product"],
(additionalType": "Product", is not needed anymore, so could be removed)
While Google’s Structured Data Testing Tool only displays one type (seems to be always the first value in the array), it reports no errors when using this.
¹ The accommodation documentation does not yet reflect this (the changes are currently part of the draft for the next version), and the topic gets discussed here:
Remove Accommodation from all of the Offer-related schema and use MTEs instead
Hotel examples and documentation must be updated for MTE pattern
² MTE: Multi-Typed Entity.

Best practice for passing large parameter data to a REST call

I have a REST Service that allows user to pass in a list of Properties they want returned from the call, eg:
/Item/123/Properties/Name,Id,Description,Type
There are hundreds of Property names that can be passed in, which then causes the issue that the number of chars supported between segments (eg: /IamASegment/) is 260 without changes to the registry etc.
So my question is when I need to support the user passing in large amounts of data like this, what is the best method, should it be passed in via the header?
A proper REST solution would be to create a form on the previous page/state and submit that form via POST, which in turn would generate a redirected GET to the actual parameterized resource. The parameter in this case could be some number for example that represents a bit-field for the requested fields.
Something like this:
GET /items
{"form": {
"Id": { "type": "number" },
"Name" : { "type": "checkbox" },
"Description" : { "type": "checkbox" },
...
}
POST /items
{"Name": "true", "Description": "true", ... }
Redirects to:
GET /items/123?fields=110110111
Of course you would have to define the proper media-types for the forms, requests, responses, etc.

SharePoint 2013 - Associating Site Columns With Content Types Using the REST API

I'm trying to use the REST API to programatically create site columns and content types. Everything works fine until I try to associate my site columns with my content types.
By this point in my code the site columns and content types already exist...
I am sending a POST to the following URL...
http://mydevmachine/sites/claimsreports/_api/web/ContentTypes('0x01003E9D5AD94A5DCD46876B7BFFCEA9B60C')/FieldLinks
Here is the information I am sending in the request body...
{
"__metadata": {
"type": "SP.FieldLink"
},
"Id": "9400d057-ba2c-4ab4-9ce0-671b858fd849",
"Name": "BusinessCategory",
"Hidden": false,
"Required": false
}
Here is the error I get back in response...
{"error":{"code":"-2147467261, System.ArgumentNullException","message":{"lang":"en-US","value":"Value cannot be null.\r\nParameter name: parameters"}}}
I have tried several other options without success. For example, I have tried using "__metadata" : { "type": "SP.FieldLinkCreationInformation"} but everything I try with this __metadata type result in this error...
{"error":{"code":"-1, Microsoft.SharePoint.Client.InvalidClientQueryException","message":{"lang":"en-US","value":"A type named 'SP.FieldLinkCreationInformation' could not be resolved by the model. When a model is available, each type name must resolve to a valid type."}}}
It sounds like SharePoint is telling me that this "type" is invalid. It seems like this should be possible with SharePoint 2013 since the documentation seems to imply that its possible...
documentation
If anyone has any ideas I would be greatful for the suggestions. Thanks!
Based on the documentation, I would try that:
Endpoint (note the /add at the end):
http://mydevmachine/sites/claimsreports/_api/web/ContentTypes('0x01003E9D5AD94A5DCD46876B7BFFCEA9B60C')/FieldLinks/add
Body (wrap your properties in a parameters property):
{"parameters":
{
"__metadata": {"type": "SP.FieldLink"},
"Id": "9400d057-ba2c-4ab4-9ce0-671b858fd849",
"Name": "BusinessCategory",
"Hidden": false,
"Required": false
}
}