laminas / laminas-json-server

Laminas Json-Server is a JSON-RPC server implementation.
https://docs.laminas.dev/laminas-json-server/
BSD 3-Clause "New" or "Revised" License
17 stars 6 forks source link

Wrong return values in Service Mapping Description (SMD) #18

Open tbreuss opened 3 years ago

tbreuss commented 3 years ago

Bug Report

The Service Mapping Description (SMD) detects wrong return values under certain (unclear) circumstances.

Q A
PHP 7.4
laminas/laminas-json-server 3.3

Summary

The return value types are kind of multiplied (see below).

I have the following Dummy class, which describes return values via phpdoc as follows.

<?php

declare(strict_types=1);

/**
 * Dummy
 */
class Dummy
{
    /**
     * Method a
     *
     * @param int $x
     * @param float $y
     * @return array
     */
    public function a(int $x, float $y): array
    {
        return ['a'];
    }

    /**
     * Method b
     *
     * @param int|float $x
     * @param string $y
     * @param int|float $z
     * @return object
     */
    public function b($x, $y, $z = 0.0): object
    {
        return (object)['name' => 'b'];
    }

    /**
     * Method c
     *
     * @param int $x
     * @param int $y
     * @param int $z
     * @return array
     */
    public function c(int $x, int $y = 0, int $z = 0): array
    {
        return ['name' => 'c'];
    }

    /**
     * Method d
     *
     * @param int|float $x
     * @param float $y
     * @return array
     */
    public function d(int $x, float $y): array
    {
        return ['d'];
    }
}

The auto-generated Service Mapping Description (SMD) looks like follows.

{
    "transport": "POST",
    "envelope": "JSON-RPC-2.0",
    "contentType": "application\/json",
    "SMDVersion": "2.0",
    "services": {
        "dummy.a": {
            "envelope": "JSON-RPC-2.0",
            "transport": "POST",
            "name": "dummy.a",
            "parameters": [
                {
                    "type": "integer",
                    "name": "x",
                    "optional": false
                },
                {
                    "type": "float",
                    "name": "y",
                    "optional": false
                }
            ],
            "returns": "array"
        },
        "dummy.b": {
            "envelope": "JSON-RPC-2.0",
            "transport": "POST",
            "name": "dummy.b",
            "parameters": [
                {
                    "type": [
                        "integer",
                        "float"
                    ],
                    "name": "x",
                    "optional": false
                },
                {
                    "type": "string",
                    "name": "y",
                    "optional": false
                },
                {
                    "type": [
                        "integer",
                        "float"
                    ],
                    "name": "z",
                    "optional": true,
                    "default": 0
                }
            ],
            "returns": [
                "object",
                "object",
                "object",
                "object",
                "object",
                "object"
            ]
        },
        "dummy.c": {
            "envelope": "JSON-RPC-2.0",
            "transport": "POST",
            "name": "dummy.c",
            "parameters": [
                {
                    "type": "integer",
                    "name": "x",
                    "optional": false
                },
                {
                    "type": "integer",
                    "name": "y",
                    "optional": true,
                    "default": 0
                },
                {
                    "type": "integer",
                    "name": "z",
                    "optional": true,
                    "default": 0
                }
            ],
            "returns": [
                "array",
                "array",
                "array"
            ]
        },
        "dummy.d": {
            "envelope": "JSON-RPC-2.0",
            "transport": "POST",
            "name": "dummy.d",
            "parameters": [
                {
                    "type": [
                        "integer",
                        "float"
                    ],
                    "name": "x",
                    "optional": false
                },
                {
                    "type": "float",
                    "name": "y",
                    "optional": false
                }
            ],
            "returns": [
                "array",
                "array"
            ]
        }
    },
    "methods": {
        "dummy.a": {
            "envelope": "JSON-RPC-2.0",
            "transport": "POST",
            "name": "dummy.a",
            "parameters": [
                {
                    "type": "integer",
                    "name": "x",
                    "optional": false
                },
                {
                    "type": "float",
                    "name": "y",
                    "optional": false
                }
            ],
            "returns": "array"
        },
        "dummy.b": {
            "envelope": "JSON-RPC-2.0",
            "transport": "POST",
            "name": "dummy.b",
            "parameters": [
                {
                    "type": [
                        "integer",
                        "float"
                    ],
                    "name": "x",
                    "optional": false
                },
                {
                    "type": "string",
                    "name": "y",
                    "optional": false
                },
                {
                    "type": [
                        "integer",
                        "float"
                    ],
                    "name": "z",
                    "optional": true,
                    "default": 0
                }
            ],
            "returns": [
                "object",
                "object",
                "object",
                "object",
                "object",
                "object"
            ]
        },
        "dummy.c": {
            "envelope": "JSON-RPC-2.0",
            "transport": "POST",
            "name": "dummy.c",
            "parameters": [
                {
                    "type": "integer",
                    "name": "x",
                    "optional": false
                },
                {
                    "type": "integer",
                    "name": "y",
                    "optional": true,
                    "default": 0
                },
                {
                    "type": "integer",
                    "name": "z",
                    "optional": true,
                    "default": 0
                }
            ],
            "returns": [
                "array",
                "array",
                "array"
            ]
        },
        "dummy.d": {
            "envelope": "JSON-RPC-2.0",
            "transport": "POST",
            "name": "dummy.d",
            "parameters": [
                {
                    "type": [
                        "integer",
                        "float"
                    ],
                    "name": "x",
                    "optional": false
                },
                {
                    "type": "float",
                    "name": "y",
                    "optional": false
                }
            ],
            "returns": [
                "array",
                "array"
            ]
        }
    }
}

Current behavior

The return values seems to be multiplied. It looks like there is a relation to the params.

Method Return Conclusion
dummy.a array Ok
dummy.b array of 6 objects strange, why 6 objects?
dummy.c array of 3 arrays strange, why 3 arrays?
dummy.d array of 2 arrays strange, why 2 arrays?

How to reproduce

Expected behavior

The return values should not be multiplied.