We can define components in Swagger:
components:
schemas:
User:
properties:
id:
type: integer
name:
type: string
And use this component later:
responses:
'200':
description: The response
schema:
$ref: '#/components/schemas/User'
I want to use this in order to avoid duplicating content.
I try to use this syntax in API Platform:
components:
schemas:
Part:
description: Array of Part
type: array
items:
type: object
properties:
name:
type: string
App\Entity\Item:
collectionOperations:
post:
method: 'POST'
swagger_context:
parameters:
- name: body
description: Item data
in: body
schema:
type: object
properties:
name:
description: Part
type: string
required: true
part:
$ref: '#/components/schemas/Part'
It gives me an error:
Exception thrown when handling an exception (Symfony\Component\Config\Exception\FileLoaderLoadException: Resource "components" not found in . (which is being imported from "/app/config/routes/api_platform.yaml"). Make sure there is a loader supporting the "api_platform" type.)
It looks like the YAML loader doesn't recognize the components item.
How can I define and use references in API Platform? How can I define a reference and use it in several YAML files?
You cannot do that like this.
The components key belongs to the Swagger/OpenAPI format, not to the API Platform configuration (mapping) format. Both API Platform configuration files and Swagger definitions can be written in YAML, but they are not related.
So, as the error message describes, Swagger components cannot be injected in API Platform's configuration files directly, as you try to do.
API Platform's configuration does allow allows to inject some context in the generated Swagger file using the swagger_context key, but you cannot write random Swagger definitions (such as your component key) outside of this structure.
To do what you want to achieve the swagger_context key will not be enough (components must be injected at the root of the Swagger file, and it's not possible with swagger_context).
Instead of using this key, you'll have to create a decorator for the Swagger documentation generator, as explained in this documentation entry: https://api-platform.com/docs/core/swagger/#overriding-the-swagger-documentation
Decorator allows to access to the whole Swagger structure, and to modify it. So you'll be able to add your components structure.
It possible ... See How can I annotate my attribute which is Value Object in order that API Platform would generate its fields for swagger documentation?
In my exemple, I have the entity Checker, I created two groups :
* #ApiResource(
* attributes={
* "normalization_context"={"groups"={"read"}},
* "denormalization_context"={"groups"={"write"}},
* },
Then in the swagger_context responses :
* "responses" = {
* "201" = {
* "description" = "....",
* "schema" = {
* "type" = "object",
* "properties" = {
* "myresult" = {
* "$ref"="#/definitions/Checker-read"
* }
workflow.yaml:
framework:
workflows:
test_workflow:
type: 'workflow'
marking_store:
type: 'single_state'
arguments:
- 'currentPlace'
supports:
- App\Entity\Call
initial_place: draft
places:
- draft
- ok
- notok
transitions:
go:
from: draft
to: ok
reject:
from: draft
to: notok
My Controller:
public function twf(Registry $workflows){
$c = new Call();
$workflow = $workflows->get($c);
return $this->render('page/twf.html.twig',[
'cp' => $c->getCurrentPlace()
]);
}
It just shows nothing , but when applying the Go transition , it displays the 'ok' which is expected , I wonder why it's not taking the configured initial_place when the Call object is first initiated !
Any hints ?
I think it only sets the state to the initial after something triggers it. Requesting the workflow object is not enough.
Try calling getMarking, it should be set after that... you can see the set part here: https://github.com/symfony/workflow/blob/master/Workflow.php#L63
I'm trying to define a post endpoint using swagger, but it isn't allowing the requestBody parameter:
/names/{roster}:
get:
#...
post:
x-swagger-router-controller: names
description: Adds or removes name(s)
operationId: manageNames
parameters:
- name: roster
in: path
description: the roster to use
type: string
required: true
requestBody:
content:
'application/json':
schema:
$ref: '#/definitions/ManageNamesRequest'
when I run npm start, I get this:
API Errors:
#/paths/~1names~1{roster}/post: Additional properties not allowed: requestBody
1 error and 0 warnings
What's wrong with my spec?
You are probably mixing OpenAPI/Swagger 2.0 and OpenAPI 3.0 syntax. Your spec seems to be 2.0, but the requestBody keyword is a 3.0 feature. In 2.0, the request body is defined as a body parameter:
paths:
/names/{roster}:
post:
produces:
- application/json
...
parameters:
- ...
- in: body
name: body
required: true
schema:
$ref: '#/definitions/ManageNamesRequest'
More info: Describing Request Body
I have this WMS layer:
http://apps.ecmwf.int/wms/?token=public&version=1.3.0&request=GetMap&layers=composition_bbaod550
I want to add it to a leaflet map but it is not showing up.
Here is my code:
library("leaflet")
library("sp")
leaflet() %>% addTiles() %>% setView(0, 50, zoom = 1) %>%
addWMSTiles("http://apps.ecmwf.int/wms/?token=public&version=1.3.0&request=GetMap",
layers = "composition_bbaod550",
options = WMSTileOptions(format = "image/png", transparent = TRUE))
What am I doing wrong?
EDIT #1:
Here is what the network requests look like from the developer console
EDIT #2:
Here is my code with IvanSanchez's suggestions. As you can see the proposed approach did not fix the problem
library("leaflet")
library("sp")
leaflet() %>% addTiles() %>% setView(0, 50, zoom = 1) %>%
addWMSTiles("http://apps.ecmwf.int/wms/",
layers = "composition_bbaod550",
options = WMSTileOptions(token = "public",
srs = "EPSG:4326",
format = "image/png",
transparent = TRUE))
If we make a GetCapabilities request to the WMS service as below, we can see that the highest supported WMS version is 1.1.1. So your GetMap request for a version=1.3.0 WMS service will probably error.
http://apps.ecmwf.int/wms/?token=public&service=WMS&request=GetCapabilities&
When I looked at the response it appeared to have some errors and indeed when I checked in my XML editor, there are many errors (so many that the log is greater the character limit allowed in this answer).
WMS configuration errors:
System ID: http://apps.ecmwf.int/wms/?token=public&service=WMS&request=GetCapabilities
Main validation file: http://apps.ecmwf.int/wms/?token=public&service=WMS&request=GetCapabilities
Schema: http://schemas.opengis.net/wms/1.1.1/WMS_MS_Capabilities.dtd
Engine name: Xerces
Severity: error
Description: Attribute "xlink:execution" is not allowed to appear in element "OnlineResource".
Start location: 44:17
End location: 44:54
System ID: http://apps.ecmwf.int/wms/?token=public&service=WMS&request=GetCapabilities
Main validation file: http://apps.ecmwf.int/wms/?token=public&service=WMS&request=GetCapabilities
Schema: http://schemas.opengis.net/wms/1.1.1/WMS_MS_Capabilities.dtd
Engine name: Xerces
Severity: error
Description: Unexpected element "SRS". The content of the parent element type must match "(Name?,Title,Abstract?,KeywordList?,SRS*,LatLonBoundingBox?,BoundingBox*,Dimension*,Extent*,Attribution?,AuthorityURL*,Identifier*,MetadataURL*,DataURL*,FeatureListURL*,Style*,ScaleHint?,Layer*)".
Start location: 97:8
End location: 97:11
System ID: http://apps.ecmwf.int/wms/?token=public&service=WMS&request=GetCapabilities
Main validation file: http://apps.ecmwf.int/wms/?token=public&service=WMS&request=GetCapabilities
Schema: http://schemas.opengis.net/wms/1.1.1/WMS_MS_Capabilities.dtd
Engine name: Xerces
Severity: error
Description: Unexpected element "SRS". The content of the parent element type must match "(Name?,Title,Abstract?,KeywordList?,SRS*,LatLonBoundingBox?,BoundingBox*,Dimension*,Extent*,Attribution?,AuthorityURL*,Identifier*,MetadataURL*,DataURL*,FeatureListURL*,Style*,ScaleHint?,Layer*)".
Start location: 122:10
End location: 122:13
System ID: http://apps.ecmwf.int/wms/?token=public&service=WMS&request=GetCapabilities
Main validation file: http://apps.ecmwf.int/wms/?token=public&service=WMS&request=GetCapabilities
Schema: http://schemas.opengis.net/wms/1.1.1/WMS_MS_Capabilities.dtd
Engine name: Xerces
Severity: error
Description: Attribute "multipleValues" is not allowed to appear in element "Extent".
Start location: 137:60
End location: 137:78
System ID: http://apps.ecmwf.int/wms/?token=public&service=WMS&request=GetCapabilities
Main validation file: http://apps.ecmwf.int/wms/?token=public&service=WMS&request=GetCapabilities
Schema: http://schemas.opengis.net/wms/1.1.1/WMS_MS_Capabilities.dtd
Engine name: Xerces
Severity: error
Description: Unexpected element "SRS". The content of the parent element type must match "(Name?,Title,Abstract?,KeywordList?,SRS*,LatLonBoundingBox?,BoundingBox*,Dimension*,Extent*,Attribution?,AuthorityURL*,Identifier*,MetadataURL*,DataURL*,FeatureListURL*,Style*,ScaleHint?,Layer*)".
Start location: 273:10
End location: 273:13
System ID: http://apps.ecmwf.int/wms/?token=public&service=WMS&request=GetCapabilities
Main validation file: http://apps.ecmwf.int/wms/?token=public&service=WMS&request=GetCapabilities
Schema: http://schemas.opengis.net/wms/1.1.1/WMS_MS_Capabilities.dtd
Engine name: Xerces
Severity: error
Description: Attribute "multipleValues" is not allowed to appear in element "Extent".
Start location: 288:60
End location: 288:78
System ID: http://apps.ecmwf.int/wms/?token=public&service=WMS&request=GetCapabilities
Main validation file: http://apps.ecmwf.int/wms/?token=public&service=WMS&request=GetCapabilities
Schema: http://schemas.opengis.net/wms/1.1.1/WMS_MS_Capabilities.dtd
Engine name: Xerces
Severity: error
Description: Unexpected element "SRS". The content of the parent element type must match "(Name?,Title,Abstract?,KeywordList?,SRS*,LatLonBoundingBox?,BoundingBox*,Dimension*,Extent*,Attribution?,AuthorityURL*,Identifier*,MetadataURL*,DataURL*,FeatureListURL*,Style*,ScaleHint?,Layer*)".
Start location: 393:10
End location: 393:13
...
The SRS / LatLonBoundingBox / BoundingBox section should look something like below (structure, not content):
<SRS>CRS:84</SRS>
<SRS>EPSG:27700</SRS>
<SRS>EPSG:3034</SRS>
<SRS>EPSG:3413</SRS>
<SRS>EPSG:3857</SRS>
<SRS>EPSG:4258</SRS>
<SRS>EPSG:4326</SRS>
<SRS>EPSG:900913</SRS>
<LatLonBoundingBox minx="-10.8018" miny="49.5889" maxx="3.92104" maxy="61.1359" />
<BoundingBox SRS="CRS:84"
minx="-10.8018" miny="49.5889" maxx="3.92104" maxy="61.1359" />
<BoundingBox SRS="EPSG:27700"
minx="-235677" miny="-34616" maxx="827937" maxy="1.28234e+006" />
<BoundingBox SRS="EPSG:3034"
minx="2.5664e+006" miny="2.55843e+006" maxx="3.67848e+006" maxy="3.94271e+006" />
<BoundingBox SRS="EPSG:3413"
minx="1.79406e+006" miny="-3.77262e+006" maxx="3.43831e+006" maxy="-2.09742e+006" />
<BoundingBox SRS="EPSG:3857"
minx="-1.20245e+006" miny="6.37538e+006" maxx="436488" maxy="8.6571e+006" />
<BoundingBox SRS="EPSG:4258"
minx="-10.8018" miny="49.5889" maxx="3.92104" maxy="61.1359" />
<BoundingBox SRS="EPSG:4326"
minx="-10.8018" miny="49.5889" maxx="3.92104" maxy="61.1359" />
<BoundingBox SRS="EPSG:900913"
minx="-10.8018" miny="49.5889" maxx="3.92104" maxy="61.1359" />
So the service is definitely not configured correctly, and this is probably the root cause of any problems you are having.
Do not include the version nor the request parameters in the base WMS URL. These are added internally by Leaflet. Leaflet expects a base WMS URL, as explained in http://leafletjs.com/examples/wms/wms.html.
So instead of
addWMSTiles("http://apps.ecmwf.int/wms/?token=public&version=1.3.0&request=GetMap",
Do
addWMSTiles("http://apps.ecmwf.int/wms/?token=public&",
Also, quoting from the Leaflet WMS tutorial:
L.TileLayer.WMS has extra options, which can be found in Leaflet’s API documentation. Any option not described there will be passed to the WMS server in the getImage URLs.
So you can actually do
addWMSTiles("http://apps.ecmwf.int/wms/",
layers = "composition_bbaod550",
options = WMSTileOptions(token = "public", format = "image/png", transparent = TRUE))
If this fails, use the developer console in your web browser (press F12) and see the network requests. How do the requests to the WMS look like?
Edit:
After a tiny bit of debugging, it seems that the WMS server is responding with:
<!DOCTYPE ServiceExceptionReport SYSTEM "/static/frontend/contrib/exception_1_1_1.dtd">
<ServiceExceptionReport version="1.1.1">
<ServiceException code='InvalidSRS'><![CDATA[
Unsupported projection 'EPSG:3857'
]]>
</ServiceException>
</ServiceExceptionReport>
This means that the WMS server is not capable of outputting images which fit the default map projection for Leaflet.
If you want to use this WMS server, you'll have to check the list of supported map projections from its GetCapabilities document, and use Proj4Leaflet to make the map use a projection different than the default.
Do read:
http://leafletjs.com/examples/wms/wms.html#notes-to-gis-users-of-wms-services (Leaflet using a different map proj)
http://www.qgistutorials.com/en/docs/working_with_wms.html (How to see the capabilities of a WMS using QGIS)
https://github.com/rstudio/leaflet/blob/master/inst/examples/proj4Leaflet.R (examples of Leaflet for R with custom map projs)
I'm sorry there's no straightforward answer; you'll have to do a bit of work and learning about projections.
i followed this to learn how ODataController works, everything is OK but when i changed the request uri
from
"localhost:49292/odata/Employees" //result: 200
to
"localhost:49292/odata/employees" //result: 404
to say one word: "odata" or "Odata" and "Employee" are all ok, but lowercase "employee" return 404. any explanation about this. Moreover, the routes in asp.net mvc is not case-sensitive afaik.
how about including a Route attribute and direct it to lower case. for Upper case web api will take care about it
[Route("odata/employees")]
add this on the top of the controller
if odata is common for every action then you can include [RoutePrefix] attribute
You can manually do it using the ODataModelBuilder instead of the ODataConventionModelBuilder
e.g
var builder = new ODataModelBuilder();
builder.EntitySet<Order>("Employees");
builder.EntitySet<Order>("employees");
this will work but your metadata will show 2 entity sets:
{
#odata.context: "http://localhost:62881/$metadata",
value: [
{
name: "Employees",
kind: "EntitySet",
url: "Employees"
},
{
name: "employees",
kind: "EntitySet",
url: "employees"
}
]
}
lowercase "employee" return 404.
I hope you probably didn't have the typo like that.
AFAIK, there is a case limitation on filter and properties. (You can vote there https://aspnetwebstack.codeplex.com/workitem/366 ) but not sure about the controller name..
You can create the REST server using web api without having oData as well..