Free lesson · GenAI Platform Engineering

శోధన మరియు ఫిల్టరింగ్‌తో సర్వీస్ కేటలాగ్ REST API నిర్మించండి

ప్లాట్‌ఫారమ్ వినియోగదారులకు సర్వీస్ కేటలాగ్‌ను అందుబాటులోకి తెచ్చే API లేయర్‌ను సృష్టించండి. శోధన, category ఆధారంగా ఫిల్టరింగ్, మరియు versioned కేటలాగ్ ప్రతిస్పందనలను అమలు చేయండి.

Course: AI Developer Platform Engineering · Chapter 1 · Internal Developer Platform Vision

Free to read — no subscription required.

పరిచయం

మీరు ఒక సర్వీస్ కేటలాగ్‌ను ప్రచురించి, దానిని క్వెరీ చేయడానికి వినియోగదారులకు ప్రోగ్రామాటిక్ మార్గం ఇవ్వకపోతే, టీమ్‌లు Git రిపోలో ముడి YAML చదవడం, Slack సందేశాల స్క్రీన్‌షాట్‌లు తీయడం, లేదా "మనం ఏ వెక్టర్ డేటాబేస్‌లను అందిస్తున్నాం?" అని టికెట్‌లో ప్లాట్‌ఫారమ్ టీమ్‌ను అడగడం వంటి పద్ధతులకు తిరిగి వెళ్తాయి. కేటలాగ్ డేటా ఉంది, కానీ అది కనుగొనదగినది కాదు—ఇంజనీర్లు "team-beta యాజమాన్యంలోని ప్రతి GPU-ఆధారిత మోడల్-సర్వింగ్ ఎంట్రీని, కొత్త వెర్షన్ మొదట చూపించు" అనే ప్రశ్నకు మనిషి జోక్యం లేకుండా సమాధానం పొందలేరు. API లేయర్ ఈ అంతరాన్ని పూరిస్తుంది—కేటలాగ్‌ను HTTP ద్వారా నిర్మాణాత్మక సెర్చ్, కేటగిరీ ఫిల్టరింగ్, పేజినేషన్ మరియు స్పష్టమైన రెస్పాన్స్ వెర్షన్‌తో బహిర్గతం చేస్తుంది, తద్వారా డెవలపర్ పోర్టల్‌లు, CLIలు మరియు CI పైప్‌లైన్‌లు అన్నీ ఒకే కాంట్రాక్ట్‌ను వినియోగించగలవు. ఈ పాఠం ముగిసేసరికి, వినియోగదారు ఇన్‌పుట్‌ను ధృవీకరించే క్వెరీ మరియు రెస్పాన్స్ స్కీమాలను నిర్వచించడం, కేటలాగ్ స్టోర్‌పై నడిచే పూర్తి-టెక్స్ట్ సెర్చ్ మరియు కేటగిరీ ఫిల్టర్‌ను అమలు చేయడం, మరియు ఇప్పటికే ఉన్న క్లయింట్‌లను విచ్ఛిన్నం చేయకుండా పేలోడ్ ఆకారాన్ని పరిణామం చెందించడానికి వీలు కల్పించే వెర్షన్డ్ ఎన్వలప్‌లో ఫలితాలను చుట్టడం మీకు సాధ్యమవుతుంది.

కీలక పదజాలం

  • Catalog API: సర్వీస్ కేటలాగ్‌పై రీడ్ ఆపరేషన్‌లను—జాబితా చేయడం, సెర్చ్ చేయడం, ఫిల్టర్ చేయడం, మరియు వ్యక్తిగత ఎంట్రీలను పొందడం—ప్లాట్‌ఫారమ్ వినియోగదారులకు బహిర్గతం చేసే HTTP ఇంటర్‌ఫేస్.
  • Query Parameter Model: URL క్వెరీ స్ట్రింగ్ ఆర్గ్యుమెంట్‌లను టైప్ చేసిన ఫీల్డ్‌లకు బైండ్ చేసే ధృవీకరించబడిన స్కీమా (CatalogQuery), ఏదైనా స్టోర్ యాక్సెస్‌కు ముందే తప్పుగా రూపొందించిన అభ్యర్థనలను తిరస్కరిస్తుంది.
  • Response Envelope: ఫలిత ఐటెమ్‌లతో పాటు మొత్తం సంఖ్య, పేజినేషన్ కర్సర్, మరియు API వెర్షన్ వంటి మెటాడేటాను మోసుకెళ్లే ర్యాపర్ ఆబ్జెక్ట్ (CatalogListResponse).
  • API Versioning: ప్రతి రెస్పాన్స్‌లో స్పష్టమైన api_version ఫీల్డ్‌ను పొందుపరచడం, తద్వారా వినియోగదారులు నిశ్శబ్దంగా విచ్ఛిన్నం కావడానికి బదులు స్కీమా మార్పులను గుర్తించి వాటికి అనుగుణంగా మారగలరు.
  • Category Filter: ServiceCategoryకి సరిపోలే ఎంట్రీలకు ఫలితాలను పరిమితం చేసే సర్వర్-సైడ్ ప్రెడికేట్, సంఖ్యలు ఖచ్చితంగా ఉండేలా పేజినేషన్‌కు ముందు వర్తింపజేయబడుతుంది.

భావనలు

ఇప్పుడు మన దగ్గర బహిర్గతం చేయడానికి కేటలాగ్ డేటా మోడల్ ఉంది కాబట్టి, API లేయర్ ప్లాట్‌ఫారమ్ వినియోగదారులకు మరియు అంతర్లీన ఎంట్రీ స్టోర్‌కు మధ్య ఉంటుంది, వదులుగా-టైప్ చేసిన HTTP క్వెరీ స్ట్రింగ్‌లను ధృవీకరించబడిన, ఫిల్టర్ చేసిన, వెర్షన్డ్ రెస్పాన్స్‌లుగా అనువదిస్తుంది. ఒక అభ్యర్థన నాలుగు దశల ద్వారా ప్రవహిస్తుంది: ఇన్‌పుట్ బైండింగ్, ఫిల్టరింగ్, పేజినేషన్, మరియు ఎన్వలప్ నిర్మాణం. ప్రతి దశకు ఒకే బాధ్యత ఉంటుంది, మరియు వాటిని వేరుగా ఉంచడమే సెర్చ్ ఎండ్‌పాయింట్‌ను పరీక్షించదగినదిగా మరియు రెస్పాన్స్ ఆకారాన్ని పరిణామం చెందించదగినదిగా చేస్తుంది.

Loading diagram...

ఇన్‌పుట్ బైండింగ్ దశ ?q=qdrant&category=vector-db&limit=20&offset=0ను ఒక CatalogQuery ఇన్‌స్టాన్స్‌పై మ్యాప్ చేస్తుంది. టైప్ చేసిన మోడల్ ద్వారా బైండింగ్ చేయడం అంటే చెల్లని limit (ప్రతికూలమైనది, లేదా గరిష్ఠ పరిమితి కంటే ఎక్కువ) స్వయంచాలకంగా 422తో తిరస్కరించబడుతుంది—ఎండ్‌పాయింట్ బాడీ ఎప్పుడూ చెడు ఇన్‌పుట్‌పై నడవదు. ఫిల్టరింగ్ దశ రెండు స్వతంత్ర ప్రెడికేట్‌లను వర్తింపజేస్తుంది: q పదం కోసం ఎంట్రీ యొక్క name మరియు descriptionపై కేస్-ఇన్సెన్సిటివ్ సబ్‌స్ట్రింగ్ మ్యాచ్, మరియు category కోసం ఖచ్చితమైన service_type మ్యాచ్. రెండూ ఐచ్ఛికమే; ఏదైనా ఒకదాన్ని వదిలేస్తే లోపం రావడానికి బదులు ఫలిత సమితి విస్తృతమవుతుంది.

చివరి రెండు దశల మధ్య క్రమం ముఖ్యం. total అన్ని ఎంట్రీల సంఖ్యను కాకుండా సరిపోలే ఎంట్రీల సంఖ్యను ప్రతిబింబించేలా పేజినేషన్‌కు ముందు ఫిల్టరింగ్ పూర్తి కావాలి. మీరు మొదట పేజినేట్ చేసి ఆ పేజీని ఫిల్టర్ చేస్తే, సెర్చ్ యొక్క రెండవ పేజీ మొదటి పేజీలో పడిన సరిపోలికలను నిశ్శబ్దంగా వదిలేస్తుంది, మరియు మొత్తం సంఖ్య అర్థరహితమవుతుంది. మొత్తం సమితిపై apply_filters నడపడం, ఫిల్టర్ చేసిన పొడవు నుండి total లెక్కించడం, ఆ తర్వాత మాత్రమే paginateతో స్లైస్ చేయడం పేజినేషన్ మెటాడేటాను నిజాయితీగా ఉంచుతుంది.

రెస్పాన్స్ ఎన్వలప్‌లోనే వెర్షనింగ్ నివసిస్తుంది. ఖాళీ JSON అరేను తిరిగి ఇవ్వడానికి బదులు, list_services api_version, items, total, limit, మరియు offsetలను మోసుకెళ్లే CatalogListResponseను తిరిగి ఇస్తుంది. వినియోగదారులు పేలోడ్ తమకు అర్థమవుతుందో లేదో నిర్ణయించడానికి api_versionను చదువుతారు. మీరు తర్వాత ఒక ఫీల్డ్‌ను జోడించినప్పుడు—ఉదాహరణకు deprecation_notice—api_version "v1"కి పిన్ చేసిన పాత క్లయింట్‌లు పనిచేస్తూనే ఉంటాయి, ఎందుకంటే ఒక వెర్షన్‌లోపల జోడింపు మార్పులు సురక్షితం, మరియు విచ్ఛిన్నకర మార్పు వెర్షన్‌ను పెంచుతుంది కాబట్టి క్లయింట్‌లు దానిపై శాఖలుగా విడిపోగలవు. ఇది కేటలాగ్ ఎంట్రీలకు మీరు వర్తింపజేసే అదే క్రమశిక్షణ, ట్రాన్స్‌పోర్ట్ లేయర్‌కు విస్తరించబడింది.

కోడ్ వాక్‌త్రూ

నాలుగు-దశల అభ్యర్థన ప్రవాహాన్ని సమీక్షించిన తర్వాత, కింది అమలు దానిని రెండు భాగాలుగా ఎన్‌కోడ్ చేస్తుంది: HTTP కాంట్రాక్ట్‌ను బైండ్ చేసి ధృవీకరించే అభ్యర్థన/రెస్పాన్స్ స్కీమాలు, మరియు సెర్చ్, ఫిల్టరింగ్, పేజినేషన్‌ను రెండు ఎండ్‌పాయింట్‌లలోకి వైర్ చేసే FastAPI రూటర్. మొదటి బ్లాక్ ServiceCategory, CatalogQuery ఇన్‌పుట్ మోడల్, ప్రతి-ఐటెమ్ CatalogItemResponse, మరియు వెర్షన్డ్ CatalogListResponse ఎన్వలప్‌ను నిర్వచిస్తుంది—ప్రతి ఫీల్డ్ నిర్బంధించబడింది కాబట్టి తప్పుగా రూపొందించిన అభ్యర్థనలు హ్యాండ్లర్ లోతుల్లో కాకుండా బైండింగ్ సమయంలోనే విఫలమవుతాయి.

Code snippetpython
1from pydantic import BaseModel, Field 2from enum import Enum 3from typing import Optional 4 5CATALOG_API_VERSION = "v1" 6 7class ServiceCategory(str, Enum): 8 MODEL_SERVING = "model-serving" 9 TRAINING_JOB = "training-job" 10 VECTOR_DB = "vector-db" 11 FEATURE_STORE = "feature-store" 12 MONITORING = "monitoring" 13 14class CatalogQuery(BaseModel): 15 q: Optional[str] = Field(default=None, max_length=128) 16 category: Optional[ServiceCategory] = None 17 limit: int = Field(default=25, ge=1, le=100) 18 offset: int = Field(default=0, ge=0) 19 20class CatalogItemResponse(BaseModel): 21 service_id: str 22 name: str 23 service_type: ServiceCategory 24 version: str 25 owner_team: str 26 description: str 27 deprecated: bool 28 29class CatalogListResponse(BaseModel): 30 api_version: str = CATALOG_API_VERSION 31 total: int 32 limit: int 33 offset: int 34 items: list[CatalogItemResponse]
  • లైన్లు 6-12: ServiceCategory కేటలాగ్ యొక్క సర్వీస్-టైప్ వర్గీకరణలోని అదే kebab-case విలువలను తిరిగి ఉపయోగిస్తుంది, కాబట్టి నిజమైన కేటగిరీ కాని category క్వెరీ పారామీటర్ బైండింగ్ వద్దే తిరస్కరించబడుతుంది—హ్యాండ్లర్ లోపల దానిని చేతితో ధృవీకరించాల్సిన అవసరం లేదు.
  • లైన్లు 14-18: CatalogQuery limitను [1, 100]కి మరియు offsetను ≥ 0కి పరిమితం చేస్తుంది. limit=5000 అడిగే క్లయింట్‌కు 422 వస్తుంది, ఇది స్టోర్‌ను అపరిమిత స్కాన్‌ల నుండి రక్షిస్తుంది; రెండు సెర్చ్ ఫీల్డ్‌లు డిఫాల్ట్‌గా None ఉంటాయి కాబట్టి ఆర్గ్యుమెంట్-రహిత అభ్యర్థన అన్నింటి మొదటి పేజీని తిరిగి ఇస్తుంది.
  • లైన్లు 28-33: CatalogListResponse api_versionను డిఫాల్ట్‌గా CATALOG_API_VERSIONకి సెట్ చేస్తుంది, కాబట్టి ప్రతి రెస్పాన్స్ స్వీయ-వివరణాత్మకం; total items పక్కనే ఉంటుంది కాబట్టి వినియోగదారులు రెండవ కాల్ లేకుండానే ఎన్ని పేజీలు మిగిలి ఉన్నాయో లెక్కించగలరు.

రెండవ బ్లాక్ ఫిల్టరింగ్ మరియు పేజినేషన్ ప్యూర్ ఫంక్షన్‌లను మరియు రెండు ఎండ్‌పాయింట్‌లను అమలు చేస్తుంది. apply_filters పూర్తి ఎంట్రీ సమితిపై రెండు ప్రెడికేట్‌లను నడుపుతుంది; paginate ఫిల్టర్ చేసిన జాబితాను స్లైస్ చేస్తుంది; list_services వాటిని కలిపి ఎన్వలప్‌ను నిర్మిస్తుంది; get_service ఒకే-ఎంట్రీ లుకప్‌ను నిర్వహిస్తుంది మరియు service_id తెలియనిది అయినప్పుడు 404ను raise చేస్తుంది.

Code snippetpython
1from fastapi import APIRouter, Depends, HTTPException 2 3router = APIRouter(prefix="/catalog", tags=["catalog"]) 4 5def apply_filters(entries: list, query: CatalogQuery) -> list: 6 results = entries 7 if query.category is not None: 8 results = [e for e in results if e.service_type == query.category] 9 if query.q: 10 term = query.q.lower() 11 results = [ 12 e for e in results 13 if term in e.name.lower() or term in e.description.lower() 14 ] 15 return results 16 17def paginate(entries: list, limit: int, offset: int) -> list: 18 return entries[offset : offset + limit] 19 20@router.get("", response_model=CatalogListResponse) 21def list_services(query: CatalogQuery = Depends(), store=Depends(get_catalog_store)): 22 matched = apply_filters(store.all_entries(), query) 23 page = paginate(matched, query.limit, query.offset) 24 return CatalogListResponse( 25 total=len(matched), 26 limit=query.limit, 27 offset=query.offset, 28 items=[CatalogItemResponse(**e.model_dump()) for e in page], 29 ) 30 31@router.get("/{service_id}", response_model=CatalogItemResponse) 32def get_service(service_id: str, store=Depends(get_catalog_store)): 33 entry = store.get(service_id) 34 if entry is None: 35 raise HTTPException(status_code=404, detail=f"unknown service_id: {service_id}") 36 return CatalogItemResponse(**entry.model_dump())
  • లైన్లు 5-15: apply_filters మొదట కేటగిరీ ప్రెడికేట్‌ను (చౌకైన ఖచ్చితమైన మ్యాచ్) ఆపై సబ్‌స్ట్రింగ్ సెర్చ్‌ను వర్తింపజేస్తుంది, రెండూ is not None / truthiness ద్వారా రక్షించబడతాయి కాబట్టి వదిలివేసిన పారామీటర్ ఏమీ లేనిదిగా ఫిల్టర్ చేయకుండా ఫలితాలను విస్తృతం చేసే నో-ఆప్ అవుతుంది.
  • లైన్లు 22-30: list_services మొత్తం సమితిపై matchedను లెక్కిస్తుంది, స్లైస్ చేయడానికి ముందే len(matched) నుండి totalను పొందుతుంది, ఆపై పేజినేట్ చేస్తుంది—ఎన్వలప్ యొక్క total ముడి కేటలాగ్ పరిమాణాన్ని కాకుండా సరిపోలికలను లెక్కిస్తుందని హామీ ఇస్తుంది.
  • లైన్లు 33-38: get_service ఒకే ఎంట్రీని తిరిగి ఇస్తుంది లేదా 404తో HTTPExceptionను raise చేస్తుంది; None తిరిగి ఇస్తే FastAPI null బాడీని సీరియలైజ్ చేస్తుంది, కాబట్టి స్పష్టమైన raise మాత్రమే వినియోగదారులకు చర్య తీసుకోదగిన లోపాన్ని ఇస్తుంది.

GET /catalog?category=vector-db&q=qdrant&limit=5 జారీ చేసి ధృవీకరించండి—రెస్పాన్స్‌లో api_version: "v1", పేరు లేదా వివరణలో "qdrant" ఉన్న సరిపోలే vector-db ఎంట్రీల సంఖ్యకు సమానమైన total, మరియు గరిష్ఠంగా ఐదు items ఉండాలి; ఆ తర్వాత GET /catalog/does-not-exist unknown service_id వివరంతో 404ను తిరిగి ఇవ్వాలి.

విభాగ అనువర్తనం

చేయవలసినవి మరియు చేయకూడనివి

పైన క్వెరీ స్కీమా, ఫిల్టర్-ఆపై-పేజినేట్ పైప్‌లైన్, మరియు వెర్షన్డ్ ఎన్వలప్‌ను పరిశీలించిన తర్వాత, కింది ఆదేశాలు API-కాంట్రాక్ట్ మరియు సెర్చ్-ఖచ్చితత్వ నమూనాలను మీ స్వంత కేటలాగ్ ఎండ్‌పాయింట్‌లను నిర్మించేటప్పుడు నేరుగా వర్తింపజేయగల నియమాలుగా సంగ్రహిస్తాయి.

చేయవలసినవి

  1. క్వెరీ స్ట్రింగ్‌లను Depends()తో CatalogQuery మోడల్ ద్వారా బైండ్ చేయండి — Field నిర్బంధాలు ([1, 100]లో limit, offset ≥ 0, ServiceCategoryగా category) list_services నడవడానికి ముందే తప్పుగా రూపొందించిన అభ్యర్థనలను 422తో తిరస్కరిస్తాయి, కాబట్టి ఏ హ్యాండ్లర్ కోడ్ కూడా అపరిమిత లిమిట్ లేదా తెలియని కేటగిరీ స్ట్రింగ్‌పై ఎప్పుడూ అమలు కాదు.
  2. పూర్తి ఎంట్రీ సమితిపై apply_filters నడిపి, paginate కాల్ చేయడానికి ముందు len(matched) నుండి totalను పొందండి — ఫిల్టర్ చేసిన-కానీ-స్లైస్ చేయని జాబితాపై సంఖ్యను లెక్కించడం CatalogListResponse.total ఫీల్డ్‌ను నిజాయితీగా ఉంచుతుంది, కాబట్టి వినియోగదారులు సరిపోలికలను నిశ్శబ్దంగా కోల్పోకుండా సెర్చ్ ఫలితాల పేజీల గుండా వెళ్లగలరు.
  3. ప్రతి రెస్పాన్స్‌పై CATALOG_API_VERSION నుండి api_version ముద్ర వేయండి — స్వీయ-వివరణాత్మక ఎన్వలప్ పోర్టల్‌లు మరియు CI క్లయింట్‌లు వెర్షన్‌పై శాఖలుగా విడిపోవడానికి వీలు కల్పిస్తుంది మరియు విచ్ఛిన్నకర పేలోడ్ మార్పులకు వెర్షన్ పెంపును రిజర్వ్ చేస్తూ "v1"లోపల జోడింపుగా ఫీల్డ్‌లను చేర్చడానికి మీకు అనుమతిస్తుంది.

చేయకూడనివి

  1. ఫిల్టరింగ్‌కు ముందు పేజినేట్ చేయవద్దు — మొదట store.all_entries()ను స్లైస్ చేసి ఆపై ఆ పేజీపై apply_filters నడపడం totalను అర్థరహితం చేస్తుంది మరియు ప్రస్తుత విండో వెలుపల పడే సరిపోలికలను వదిలేస్తుంది; పైప్‌లైన్ క్రమం (apply_filters → paginate) సరైన సంఖ్యలను మరియు పూర్తి ఫలిత సమితులను హామీ ఇస్తుంది.
  2. list_services నుండి ఖాళీ జాబితాను తిరిగి ఇవ్వవద్దు — CatalogListResponse ఎన్వలప్‌ను వదిలేయడం api_version, total, మరియు offsetలను తొలగిస్తుంది, వినియోగదారులకు స్కీమా మార్పులను గుర్తించడానికి లేదా పేజినేషన్‌ను నడపడానికి మార్గం లేకుండా చేస్తుంది—ఇది సరిగ్గా API పూరించాల్సిన కనుగొనదగిన అంతరమే.
  3. లేని service_id కోసం get_service నుండి return None చేయవద్దు — null బాడీ nullతో 200గా సీరియలైజ్ అవుతుంది, లోపాన్ని దాచిపెడుతుంది; HTTPException(status_code=404, ...)ను raise చేయడం వినియోగదారులకు చర్య తీసుకోదగిన, సరిగ్గా కోడ్ చేసిన వైఫల్యాన్ని ఇస్తుంది, దానిపై వారు శాఖలుగా విడిపోగలరు.

3 hands-on labs come with this lesson — real code, in a cloud IDE. Create a free account to run them. No card.

Free account · no card · straight to the labs

Or get the full path — from

Listen to this lesson

Audio overviews of this lesson's labs and its chapter, from GenBodha Bytes.

More free lessons in AI Developer Platform Engineering

All free lessons in GenAI Platform Engineering →