MarketSquare / roboswag

Apache License 2.0
26 stars 2 forks source link

Schema should be loaded from the file and not embedded #41

Open bhirsz opened 2 years ago

bhirsz commented 2 years ago

Currently we're embedding schemas in our endpoint definitions. It bloats Python files and make it harder to navigate through them. If several endpoints use the same schema, you need to modify it in multiple places.

We should use path to schema instead - we're already preserving schema json files.

bhirsz commented 2 years ago

It could also use helper methods. Instead of:

                try:
                    schema = {
                        "type": "object",
                        "required": ["name", "photoUrls"],
                        "properties": {
                            "id": {"type": "integer", "format": "int64"},
                            "category": {
                                "type": "object",
                                "properties": {
                                    "id": {"type": "integer", "format": "int64"},
                                    "name": {"type": "string"},
                                },
                                "xml": {"name": "Category"},
                            },
                            "name": {"type": "string", "example": "doggie"},
                            "photoUrls": {
                                "type": "array",
                                "xml": {"wrapped": True},
                                "items": {
                                    "type": "string",
                                    "xml": {"name": "photoUrl"},
                                },
                            },
                            "tags": {
                                "type": "array",
                                "xml": {"wrapped": True},
                                "items": {
                                    "type": "object",
                                    "properties": {
                                        "id": {"type": "integer", "format": "int64"},
                                        "name": {"type": "string"},
                                    },
                                    "xml": {"name": "Tag"},
                                },
                            },
                            "status": {
                                "type": "string",
                                "description": "pet status in the store",
                                "enum": ["available", "pending", "sold"],
                            },
                        },
                        "xml": {"name": "Pet"},
                    }
                    validate(instance=json.loads(response.text), schema=schema)
                except jsonschema.exceptions.ValidationError as err:
                    raise err

we could have:

def validate schema(response, path):
    try:
        validate(instance=json.loads(response.text), schema=schema)
    except jsonschema.exceptions.ValidationError as err:
        raise err

(...)
validate_schema(response, "schema-name.json")
bhirsz commented 2 years ago

The biggest difficulty is that schemas/ directory is populated from #definitions. But 1) there could be spec files without any definitions and all schemas embedded directly in endpoint description or 2) spec file could partly use definitions and partly embeds. The safest solution would be creating directory responses/ or similar and put resolved schemas there (but we could end up with many duplicated files).

I need to test it with various spec files to look for the best solution. For now I moved schema validation to separate class .

bhirsz commented 2 years ago

Referenced schema can be also used as part of other schema, ie array of Pets:

          schema:
            type: array
            items:
              $ref: '#/components/schemas/Pet'