Documenting and Trying Out Matrix Type Parameters

1,132 views
Skip to first unread message

Ruslans Uralovs

unread,
Jun 9, 2014, 4:17:07 AM6/9/14
to swagger-sw...@googlegroups.com
Hi all,

Has anyone tried documenting and then "trying out" matrix type parameters with Swagger?

Documenting seems to be fine (apart from label not being in bold), however when "Trying out" the matrix type parameter is not substituted in expected place and instead is appended to the end of request URL - see image.
Am i missing something or is there a problem when trying out matrix type parameters in Swagger?



Here is how this is described in Java:

    /**
     * A list of class scores by standard.
     *
     * @return a list of student scores by standard as JSON
     */
    @SuppressWarnings("UnusedParameters") //method is intercepted by Camel and all parameters are used to set up request headers in Camel Exchange
    @GET
    @Path("/{sectionId}/ScoresByStandard;contextId={contextId}")
    @Produces(MediaType.APPLICATION_JSON)
    @ApiOperation(value = "Find class scores by standard",
            notes = "Returns JSON report",
            response = ClassByStandardReport.class)
    public final String classScoresByStandard(
            @PathParam("sectionId") @Pattern(regexp = UUID.REGEX) @ApiParam(value = "UUID of the class", required = true) final String sectionId,
            @PathParam("contextId") @ApiParam(value = "Calling platform id", allowableValues = "HMOF, TC", required = true) final String contextId,
            @QueryParam("startDate") @ApiParam(value = "Start date of Due date filter", required = true) final String startDate,
            @QueryParam("endDate") @ApiParam(value = "End date of Due date filter", required = true) final String endDate,
            @QueryParam("offset") @ApiParam(value = "Offset of first element in the result", required = true) final int offset,
            @QueryParam("limit") @ApiParam(value = "Offset of last element in the result", required = true) final int limit) {
        throw new MethodNotInterceptedException();
    }


Thanks,
Ruslan

Ron

unread,
Jun 9, 2014, 9:23:40 AM6/9/14
to swagger-sw...@googlegroups.com
Hi Ruslan,

I think you're defining the matrix parameters in the wrong way using JAX-RS. A quick google search led me here - http://www.mkyong.com/webservices/jax-rs/jax-rs-matrixparam-example/.
Right now, it's becoming some weird path parameter, and that may be mistranslated by Swagger.

I'm a bit surprised that it is not in bold though (marking it as required). Can you also share the Swagger json?




--
You received this message because you are subscribed to the Google Groups "Swagger" group.
To unsubscribe from this group and stop receiving emails from it, send an email to swagger-swaggers...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Ruslans Uralovs

unread,
Jun 9, 2014, 11:05:45 AM6/9/14
to swagger-sw...@googlegroups.com

Yes, Ron, you are absolutely right. 
That was my problem and it has nothing to do with Swagger.
Method parameter should be annotated with @MatrixParam instead of @PathParam.

Many thanks!
Ruslan

Ruslans Uralovs

unread,
Jun 9, 2014, 12:09:56 PM6/9/14
to swagger-sw...@googlegroups.com

Ron, i am back to this issue again. 

While Swagger's "Try it out" worked fine in appending matrix type parameter to the URL my jax-rs service failed in parsing it.
As i am learning about Matrix type parameters it seems to me that they should never appear in the Query part of the request url. Matrix parameters are associated with the Path path or the query.


What do you think?


Ron

unread,
Jun 9, 2014, 12:11:46 PM6/9/14
to swagger-sw...@googlegroups.com
Not entirely sure. Can you see the full request as it is generated using your browser dev tools?


Ruslans Uralovs

unread,
Jun 10, 2014, 6:48:52 AM6/10/14
to swagger-sw...@googlegroups.com

Here are some more interesting links on the topic, however i couldn't find a definitive Standard about the use of matrix parameters:

From Lunatec, creators of Playframework, here they call them "path parameters": http://blog.lunatech.com/2009/02/03/what-every-web-developer-must-know-about-url-encoding

In every document they are path parameters, never appearing in query part.

Here is the personal view of Tim Berners-Lee about matrix URIs (which is the closest thing to a defined Standard), and again they are path parameters, never in query part:

Not sure how this translates into Swagger implementation.
I think the Swagger should look for defined @MatrixParam in the @Path and substitute it there. 
And if matrix param is not defined in the @Path, then append to the end of the path just before the query starts. 

I also noticed a difference in the actual request depending on the position of @MatrixParam parameter in java method.

(1) Matrix parameter is last in the list of parameters:

    /**
     * A list of class scores by standard.
     *
     * @return a list of student scores by standard as JSON
     */
    @SuppressWarnings("UnusedParameters") //method is intercepted by Camel and all parameters are used to set up request headers in Camel Exchange
    @GET
    @Path("/{sectionId}/ScoresByStandard")
    @Produces(MediaType.APPLICATION_JSON)
    @ApiOperation(value = "Find class scores by standard",
            notes = "Returns JSON report",
            response = ClassByStandardReport.class)
    public final String classScoresByStandard(
            @PathParam("sectionId") @Pattern(regexp = UUID.REGEX) @ApiParam(value = "UUID of the class", required = true) final String sectionId,
            @QueryParam("startDate") @ApiParam(value = "Start date of Due date filter", required = true) final String startDate,
            @QueryParam("endDate") @ApiParam(value = "End date of Due date filter", required = true) final String endDate,
            @QueryParam("offset") @ApiParam(value = "Offset of first element in the result", required = true) final int offset,
            @QueryParam("limit") @ApiParam(value = "Offset of last element in the result", required = true) final int limit,
            @MatrixParam("contextId") @ApiParam(value = "Calling platform id", allowableValues = "HMOF, TC", required = true) final String contextId) {
        throw new MethodNotInterceptedException();
    }

Which corresponds to request:
Swagger makes it a query parameter: &;contextId=HMOF
Notice that name of parameter includes the semicolon ";contextId"
(2) Matrix parameter is second in the list:
/**
     * A list of class scores by standard.
     *
     * @return a list of student scores by standard as JSON
     */
    @SuppressWarnings("UnusedParameters") //method is intercepted by Camel and all parameters are used to set up request headers in Camel Exchange
    @GET
    @Path("/{sectionId}/ScoresByStandard")
    @Produces(MediaType.APPLICATION_JSON)
    @ApiOperation(value = "Find class scores by standard",
            notes = "Returns JSON report",
            response = ClassByStandardReport.class)
    public final String classScoresByStandard(
            @PathParam("sectionId") @Pattern(regexp = UUID.REGEX) @ApiParam(value = "UUID of the class", required = true) final String sectionId,
            @MatrixParam("contextId") @ApiParam(value = "Calling platform id", allowableValues = "HMOF, TC", required = true) final String contextId,
            @QueryParam("startDate") @ApiParam(value = "Start date of Due date filter", required = true) final String startDate,
            @QueryParam("endDate") @ApiParam(value = "End date of Due date filter", required = true) final String endDate,
            @QueryParam("offset") @ApiParam(value = "Offset of first element in the result", required = true) final int offset,
            @QueryParam("limit") @ApiParam(value = "Offset of last element in the result", required = true) final int limit) {
        throw new MethodNotInterceptedException();
    }

Corresponds to:
Swagger appends matrix type (as opposed to query type parameter in previous example) to the end, notice there is no & before parameter: ;contextId=HMOF
Jax-Rs parses this as query parameter "limit" having value of "20;contextId=HMOF".





Ron

unread,
Jun 10, 2014, 7:12:46 AM6/10/14
to swagger-sw...@googlegroups.com
I think there's a bit of confusion as to what Swagger does or doesn't do. Swagger is just the description language. I assume what you see here is the Swagger-UI behavior.

Can you share the Swagger json output? I'm curious to see what it ends up like (for both variations you presented).


Ruslans Uralovs

unread,
Jun 10, 2014, 9:19:29 AM6/10/14
to swagger-sw...@googlegroups.com

Yes, that's right, in the Swagger UI behaviour.
However when completing the form in Swagger UI for "Trying Out" Swagger constructs a request which is not in expected format.

Swagger json (is that what you are asking for?):

(1) When @MatrixParam is last in the list of java method parameters:
{"apiVersion":"1.0.0","swaggerVersion":"1.2","basePath":"http://localhost:8080/api/reporting","resourcePath":"/v1/sections","apis":[{"path":"/v1/sections/{sectionId}/ScoresByStandard","operations":[{"method":"GET","summary":"Find class scores by standard","notes":"Returns JSON report","type":"ClassByStandardReport","nickname":"classScoresByStandard","produces":["application/json"],"authorizations":{},"parameters":[{"name":"sectionId","description":"UUID of the class","required":true,"type":"string","paramType":"path","allowMultiple":false},{"name":"startDate","description":"Start date of Due date filter","required":true,"type":"string","paramType":"query","allowMultiple":false},{"name":"endDate","description":"End date of Due date filter","required":true,"type":"string","paramType":"query","allowMultiple":false},{"name":"offset","description":"Offset of first element in the result","required":true,"type":"integer","format":"int32","paramType":"query","allowMultiple":false},{"name":"limit","description":"Offset of last element in the result","required":true,"type":"integer","format":"int32","paramType":"query","allowMultiple":false},{"name":"contextId","description":"Calling platform id","required":true,"type":"string","paramType":"matrix","allowMultiple":false,"enum":["HMOF"," TC"]}]}]}],"models":{"LearningStandardItem":{"id":"LearningStandardItem","properties":{"organization":{"type":"string"},"statementCode":{"type":"string"},"statement":{"type":"string"}}},"ClassStandardAverage":{"id":"ClassStandardAverage","properties":{"standard":{"type":"string"},"average":{"type":"number","format":"double"}}},"AssessmentScoreSet":{"id":"AssessmentScoreSet","properties":{"studentRefId":{"type":"string"},"score":{"type":"number","format":"double"}}},"StudentStandardScoreList":{"id":"StudentStandardScoreList","properties":{"studentId":{"type":"string"},"standardScores":{"type":"array","items":{"$ref":"StudentStandardScore"}}}},"StudentStandardScore":{"id":"StudentStandardScore","properties":{"assessmentScoreSet":{"$ref":"AssessmentScoreSet"},"learningStandardItem":{"$ref":"LearningStandardItem"}}},"ClassByStandardReport":{"id":"ClassByStandardReport","properties":{"averages":{"type":"array","items":{"$ref":"ClassStandardAverage"}},"studentData":{"type":"array","items":{"$ref":"StudentStandardScoreList"}}}}}}

(2) When @MatrixParam is second in the list of java method parameters:
{"apiVersion":"1.0.0","swaggerVersion":"1.2","basePath":"http://localhost:8080/api/reporting","resourcePath":"/v1/sections","apis":[{"path":"/v1/sections/{sectionId}/ScoresByStandard","operations":[{"method":"GET","summary":"Find class scores by standard","notes":"Returns JSON report","type":"ClassByStandardReport","nickname":"classScoresByStandard","produces":["application/json"],"authorizations":{},"parameters":[{"name":"sectionId","description":"UUID of the class","required":true,"type":"string","paramType":"path","allowMultiple":false},{"name":"contextId","description":"Calling platform id","required":true,"type":"string","paramType":"matrix","allowMultiple":false,"enum":["HMOF"," TC"]},{"name":"startDate","description":"Start date of Due date filter","required":true,"type":"string","paramType":"query","allowMultiple":false},{"name":"endDate","description":"End date of Due date filter","required":true,"type":"string","paramType":"query","allowMultiple":false},{"name":"offset","description":"Offset of first element in the result","required":true,"type":"integer","format":"int32","paramType":"query","allowMultiple":false},{"name":"limit","description":"Offset of last element in the result","required":true,"type":"integer","format":"int32","paramType":"query","allowMultiple":false}]}]}],"models":{"LearningStandardItem":{"id":"LearningStandardItem","properties":{"organization":{"type":"string"},"statementCode":{"type":"string"},"statement":{"type":"string"}}},"ClassStandardAverage":{"id":"ClassStandardAverage","properties":{"standard":{"type":"string"},"average":{"type":"number","format":"double"}}},"AssessmentScoreSet":{"id":"AssessmentScoreSet","properties":{"studentRefId":{"type":"string"},"score":{"type":"number","format":"double"}}},"StudentStandardScoreList":{"id":"StudentStandardScoreList","properties":{"studentId":{"type":"string"},"standardScores":{"type":"array","items":{"$ref":"StudentStandardScore"}}}},"StudentStandardScore":{"id":"StudentStandardScore","properties":{"assessmentScoreSet":{"$ref":"AssessmentScoreSet"},"learningStandardItem":{"$ref":"LearningStandardItem"}}},"ClassByStandardReport":{"id":"ClassByStandardReport","properties":{"averages":{"type":"array","items":{"$ref":"ClassStandardAverage"}},"studentData":{"type":"array","items":{"$ref":"StudentStandardScoreList"}}}}}}


I don't get as far as getting a response for "Trying out" because requests are not in expected format.


Ron

unread,
Jun 11, 2014, 4:25:38 AM6/11/14
to swagger-sw...@googlegroups.com
Ruslan,

It looks like you've hit an undocumented partially implemented feature.
I've checked the other Swagger projects, and it seems there's no support for matrix parameters.
Even while rewriting the current specification, I didn't include it as I never encountered it.

Granted, Swagger JAX-RS does parse @MatrixParam into 'matrix' type parameters, but that type is not used in any of the other projects.

What I'd suggest you do for now, is open an issue on swagger-spec requesting support for matrix parameters. This would be a good time to do it as we're working on the Swagger 2.0 specification right now.

I'll also pass it along to Tony. He may have some insight I'm not aware of.

BR,
Ron


Ruslans Uralovs

unread,
Jun 11, 2014, 9:17:09 AM6/11/14
to swagger-sw...@googlegroups.com

Many thanks for your help Ron.

Here is the link to swagger-spec issue:

Thanks again
Ruslan
Reply all
Reply to author
Forward
0 new messages