Validation#
Very often besides dumb method parameters validation you need to implement more “deep” validation and provide
comprehensive errors description to your clients. Fortunately pjrpc has builtin parameter validation based on
pydantic library which uses python type annotation based validation.
Look at the following example. All you need to annotate method parameters (or describe more complex type if necessary),
that’s it. pjrpc will be validating method parameters and returning informative errors to clients:
import enum
import uuid
import pydantic
from aiohttp import web
import pjrpc.server
from pjrpc.server.integration import aiohttp
from pjrpc.server.validators import pydantic as validators
methods = pjrpc.server.MethodRegistry(
validator_factory=validators.PydanticValidatorFactory(exclude=aiohttp.is_aiohttp_request),
)
class ContactType(enum.Enum):
PHONE = 'phone'
EMAIL = 'email'
class Contact(pydantic.BaseModel):
type: ContactType
value: str
class User(pydantic.BaseModel):
name: str
surname: str
age: int
contacts: list[Contact]
class UserOut(User):
id: uuid.UUID
@methods.add(pass_context='request')
async def add_user(request: web.Request, user: User) -> UserOut:
user_id = uuid.uuid4()
request.app['users'][user_id] = user
return UserOut(id=user_id, **user.model_dump())
class JSONEncoder(pjrpc.server.JSONEncoder):
def default(self, o):
if isinstance(o, uuid.UUID):
return o.hex
if isinstance(o, enum.Enum):
return o.value
if isinstance(o, pydantic.BaseModel):
return o.model_dump()
return super().default(o)
jsonrpc_app = aiohttp.Application('/api/v1', json_encoder=JSONEncoder)
jsonrpc_app.add_methods(methods)
jsonrpc_app.http_app['users'] = {}
if __name__ == "__main__":
web.run_app(jsonrpc_app.http_app, host='localhost', port=8080)
In case you like any other validation library/framework it can be easily integrated in pjrpc library.