goal is validate the response sent by different apis is valid, which is request in my api. question is how to validate json against RAML Datatype?

Viewed 29

My overall goal is to validate the response sent by different APIs and forwarded response as request to my API.

and using a discriminator to identify TYPE of object, validate against its raml data type.

Have doubt in How to validate JSON against RAML Datatype?

I found some info on parsing RAML datatype, in last comment here, https://help.mulesoft.com/s/question/0D52T00004mXXa4SAG/how-to-validate-json-object-using-a-raml-datatype

If can explain last comment in detail or some other alternative.

Attaching both RAML file using discriminator and flow.

#%RAML 1.0 Fragment
version: v1
title: My API With Types
types:
 Person:
  type: object
  discriminator: kind
  properties:
   name: string
   kind: string
 Employee:
  type: Person
  discriminatorValue: employee # override default
  properties:
   employeeId: number
 User:
  type: Person
  discriminatorValue: user # override default
  properties:
   userId: string
 /schema-val:
 post:
   #description: Retrieve a list of all the users
  body:
   application/json:
    type: Person
  responses:
   200:
    body:
    description: http status and message OK
    text/html: success      
   400:
    body:
    description: error message
    text/html: error

Flow xml-

<?xml version="1.0" encoding="UTF-8"?>
<mule
    xmlns:ee="http://www.mulesoft.org/schema/mule/ee/core"
    xmlns:http="http://www.mulesoft.org/schema/mule/http"
    xmlns="http://www.mulesoft.org/schema/mule/core"
    xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd
http://www.mulesoft.org/schema/mule/ee/core http://www.mulesoft.org/schema/mule/ee/core/current/mule-ee.xsd">
    <http:listener-config name="HTTP_Listener_config" doc:name="HTTP Listener config" doc:id="4f571302-95d5-4f0c-a320-e78b01823709" >
        <http:listener-connection host="0.0.0.0" port="8081" />
    </http:listener-config>
    <flow name="responsevalidationFlow" doc:id="88c44a1d-eff1-4f9d-b688-6933579553da" >
        <http:listener doc:name="Listener" doc:id="c8826a0f-fa70-4714-a751-2eb5a54d2f09" allowedMethods="POST" path="/schema-val" config-ref="HTTP_Listener_config"/>
        <set-payload value="#payload" doc:name="Set Payload" doc:id="794b25c3-301b-4082-a309-72adcc7ed25f" />
        <logger level="INFO" doc:name="Logger" doc:id="62cac08d-3fd2-491d-bbfd-2a1888635b87" message="#payload"/>
        <ee:transform doc:name="Transform Message" doc:id="83d88fcc-657b-42f6-987f-87578728abf2" >
            <ee:message >
                <ee:set-payload >
                    <![CDATA[%dw 2.0

output application/java
---
{
  name: payload.name,
  kind: payload.kind,
  employeeId: payload.employeeId,
  userId: payload.userId
}]]>
                </ee:set-payload>
            </ee:message>
        </ee:transform>
        <logger level="INFO" doc:name="Logger" doc:id="69fb1f31-6fc1-4904-bbb4-9c0f9cf35722" message="#payload"/>
        <set-variable value="#payload.kind" doc:name="Set Variable" doc:id="9958d86f-cd2e-4e9f-aa5c-a6efab3ed8ae" variableName="kind"/>
        <choice doc:name="Choice" doc:id="b186199b-0a0a-41ad-8353-d377054a9e33" >
            <when expression="#vars.kind=='employee'">
                <logger level="INFO" doc:name="Logger" doc:id="e75961d3-001c-421e-aaf4-1f04dd6a01a1" message='"in employee"'/>
            </when>
            <when expression="#vars.kind=='user'">
                <logger level="INFO" doc:name="Logger" doc:id="23ce14a9-94c1-4af3-b047-607dda35ce36" message='"in user"'/>
            </when>
            <otherwise >
                <logger level="INFO" doc:name="Logger" doc:id="aa5471ed-5944-4c72-8628-93b83cc0e31d" message='"in default"'/>
            </otherwise>
        </choice>
    </flow>
</mule>

Expected Output

When I hit http://localhost:8081/schema-val with below payloads

{ "name": "fred", "kind": "employee", "employeeId": "e123" }

{ "name": "barney", "kind": "user", "userId": "u999" }

Then the flow should throw error if employeeId is not a number maybe, that is invalid request.

2 Answers

Use the APIKit router. Studio can autogenerate the needed flows automatically from a RAML specification of the API. That RAML should reference your data type RAML. Validation is automatic.

APIKIT Router not validating discriminator RAML.Every request getting passed.

RAML

#%RAML 1.0

version: v1

title: My API With Types

types:

 Person:

  type: object

  discriminator: kind

  properties:

   name: string

   kind: string

 Employee:

  type: Person

  discriminatorValue: employee # override default

  properties:

   employeeId:

    required: true

    minLength: 3

    type: string

    

 User:

  type: Person

  discriminatorValue: user # override default

  properties:

   userId: string

/schema-val:

 post:

   #description: Retrieve a list of all the users  

  body:

   application/json:

    type: Person

  responses:

   200:

    body:

     application/text: 

      example: success     

   400:

    body:

     application/text: 

      example: error

Flow-

<?xml version="1.0" encoding="UTF-8"?>

 

<mule xmlns:apikit="http://www.mulesoft.org/schema/mule/mule-apikit" xmlns:ee="http://www.mulesoft.org/schema/mule/ee/core"

xmlns:http="http://www.mulesoft.org/schema/mule/http"

xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd

http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd

http://www.mulesoft.org/schema/mule/ee/core http://www.mulesoft.org/schema/mule/ee/core/current/mule-ee.xsd

http://www.mulesoft.org/schema/mule/mule-apikit http://www.mulesoft.org/schema/mule/mule-apikit/current/mule-apikit.xsd">

<http:listener-config name="HTTP_Listener_config" doc:name="HTTP Listener config" doc:id="4f571302-95d5-4f0c-a320-e78b01823709" >

<http:listener-connection host="0.0.0.0" port="8081" />

</http:listener-config>

<apikit:config outboundHeadersMapName="outboundHeadersMapName" httpStatusVarName="httpStatus" doc:name="Router" doc:id="03538ab3-9515-4a48-8b60-58f44d528072" name="Router1" api="api\discriminatorValue.raml" raml="api\discriminatorValue.raml" keepRamlBaseUri="true">

<apikit:flow-mappings >

<apikit:flow-mapping resource="/schema-val" action="post" content-type="application/json" flow-ref="responsevalidationFlow1" />

</apikit:flow-mappings>

</apikit:config>

<flow name="responsevalidationFlow" doc:id="88c44a1d-eff1-4f9d-b688-6933579553da" >

<http:listener doc:name="Listener" doc:id="c8826a0f-fa70-4714-a751-2eb5a54d2f09" allowedMethods="POST" path="/schema-val" config-ref="HTTP_Listener_config"/>

<set-payload value="#payload" doc:name="Set Payload" doc:id="794b25c3-301b-4082-a309-72adcc7ed25f" />

<apikit:router doc:name="APIkit Router" doc:id="ccf175a8-5ed1-441d-850a-ef94eb9d7af5" config-ref="Router1" />

<logger level="INFO" doc:name="Logger" doc:id="62cac08d-3fd2-491d-bbfd-2a1888635b87" message="#payload"/>

<logger level="INFO" doc:name="Logger" doc:id="69fb1f31-6fc1-4904-bbb4-9c0f9cf35722" message="#payload"/>

<set-variable value="#payload.kind" doc:name="Set Variable" doc:id="9958d86f-cd2e-4e9f-aa5c-a6efab3ed8ae" variableName="kind"/>

<choice doc:name="Choice" doc:id="b186199b-0a0a-41ad-8353-d377054a9e33" >

<when expression="#vars.kind=='employee'">

<logger level="INFO" doc:name="Logger" doc:id="e75961d3-001c-421e-aaf4-1f04dd6a01a1" message='"in employee"'/>

</when>

<when expression="#vars.kind=='user'">

<logger level="INFO" doc:name="Logger" doc:id="23ce14a9-94c1-4af3-b047-607dda35ce36" message='"in user"'/>

</when>

<otherwise >

<logger level="INFO" doc:name="Logger" doc:id="aa5471ed-5944-4c72-8628-93b83cc0e31d" message='"in default"'/>

</otherwise>

</choice>

</flow>

<flow name="responsevalidationFlow1" doc:id="0119d024-14b3-4aed-88ca-a1213726cb23" >

<logger level="INFO" doc:name="Logger" doc:id="ed02255f-9461-4703-b027-325c71342c49" message='#vars.httpStatus'/>

</flow>

</mule>

#%RAML 1.0

version: v1

title: My API With Types

types:

 Person:

  type: object

  discriminator: kind

  properties:

   name: string

   kind: string

 Employee:

  type: Person

  discriminatorValue: employee # override default

  properties:

   employeeId:

    required: true

    minLength: 3

    type: string

    

 User:

  type: Person

  discriminatorValue: user # override default

  properties:

   userId: string

/schema-val:

 post:

   #description: Retrieve a list of all the users  

  body:

   application/json:

    type: Employee

  responses:

   200:

    body:

     application/text: 

      example: success     

   400:

    body:

     application/text: 

      example: error

If change type to "Employee" in RAML it works like in above RAML.But we want generic.

{ "name": "fred", "kind": "employee", "employeeId": "e1" }

/employeeId expected minLength: 3, actual: 2

Related