{"id":4288,"date":"2024-12-17T11:02:22","date_gmt":"2024-12-17T11:02:22","guid":{"rendered":"https:\/\/www.rcvtechnologies.com\/blog\/?p=4288"},"modified":"2024-12-17T11:07:06","modified_gmt":"2024-12-17T11:07:06","slug":"why-use-repository-pattern-in-laravel","status":"publish","type":"post","link":"https:\/\/www.rcvtechnologies.com\/blog\/why-use-repository-pattern-in-laravel\/","title":{"rendered":"Why use Repository Pattern in Laravel"},"content":{"rendered":"<p><b>Detailed Use Case: E-Commerce Platform with Complex Data Requirements<\/b><\/p>\n<p><b>Scenario: Multi-Vendor Marketplace System<\/b><\/p>\n<p><b>Initial Context<\/b><\/p>\n<p><span style=\"font-weight: 400;\">Imagine an e-commerce platform with the following complex requirements:<\/span><\/p>\n<p><span style=\"font-weight: 400;\">&#8211; Multiple data sources (internal database, external vendor APIs)<\/span><\/p>\n<p><span style=\"font-weight: 400;\">&#8211; Complex querying across different models<\/span><\/p>\n<p><span style=\"font-weight: 400;\">&#8211; Need for extensive caching<\/span><\/p>\n<p><span style=\"font-weight: 400;\">&#8211; Requirement for advanced filtering and search<\/span><\/p>\n<p><span style=\"font-weight: 400;\">&#8211; Performance optimization<\/span><\/p>\n<p><span style=\"font-weight: 400;\">&#8211; Decoupled architecture for scalability<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><b>Practical Implementation<\/b><\/p>\n<ol>\n<li><b> Product Repository with Multiple Data Sources<\/b><\/li>\n<\/ol>\n<div class=\"dm-code-snippet dark default  dm-normal-version\" style=\"background-color:#abb8c3;\" snippet-height=\"\">\n\t\t\t<div class=\"control-language\">\n                <div class=\"dm-buttons\">\n                    <div class=\"dm-buttons-left\">\n                        <div class=\"dm-button-snippet red-button\"><\/div>\n                        <div class=\"dm-button-snippet orange-button\"><\/div>\n                        <div class=\"dm-button-snippet green-button\"><\/div>\n                    <\/div>\n                    <div class=\"dm-buttons-right\">\n                        <a id=\"dm-copy-raw-code\">\n                        <span class=\"dm-copy-text\">Copy Code<\/span>\n                        <span class=\"dm-copy-confirmed\" style=\"display:none\">Copied<\/span>\n                        <span class=\"dm-error-message\" style=\"display:none\">Use a different Browser<\/span><\/a>\n                    <\/div>\n                <\/div>\n                <pre class=\"no-line-numbers\"><code id=\"dm-code-raw\" class=\"no-wrap language-php\"><\/p>\n<pre class=\"dm-pre-admin-side\">namespace App\\Repositories;\r\n\r\nuse App\\Models\\Product;\r\n\r\nuse App\\Interfaces\\ProductRepositoryInterface;\r\n\r\nuse Illuminate\\Support\\Facades\\Cache;\r\n\r\nuse App\\Services\\ExternalVendorService;\r\n\r\n\r\n\r\n\r\nclass ProductRepository implements ProductRepositoryInterface\r\n\r\n{\r\n\r\n\u00a0\u00a0\u00a0\u00a0protected $model;\r\n\r\n\u00a0\u00a0\u00a0\u00a0protected $externalVendorService;\r\n\r\n\r\n\r\n\r\n\u00a0\u00a0\u00a0\u00a0public function __construct(Product $product, ExternalVendorService $externalVendorService)\r\n\r\n\u00a0\u00a0\u00a0\u00a0{\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0$this-&gt;model = $product;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0$this-&gt;externalVendorService = $externalVendorService;\r\n\r\n\u00a0\u00a0\u00a0\u00a0}\r\n\r\n\r\n\r\n\r\n\u00a0\u00a0\u00a0\u00a0\/\/ Complex method demonstrating multiple concerns\r\n\r\n\u00a0\u00a0\u00a0\u00a0public function getFilteredProducts(array $filters)\r\n\r\n\u00a0\u00a0\u00a0\u00a0{\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ Caching strategy\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0$cacheKey = $this-&gt;generateCacheKey($filters);\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return Cache::remember($cacheKey, now()-&gt;addHours(2), function () use ($filters) {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0$query = $this-&gt;model-&gt;newQuery();\r\n\r\n\r\n\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ Dynamic filtering with multiple conditions\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0$query-&gt;when($filters['category'] ?? null, function ($q, $category) {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return $q-&gt;where('category_id', $category);\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0})\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0-&gt;when($filters['price_min'] ?? null, function ($q, $minPrice) {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return $q-&gt;where('price', '&gt;=', $minPrice);\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0})\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0-&gt;when($filters['price_max'] ?? null, function ($q, $maxPrice) {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return $q-&gt;where('price', '&lt;=', $maxPrice);\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0})\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0-&gt;when($filters['vendor'] ?? null, function ($q, $vendor) {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return $q-&gt;where('vendor_id', $vendor);\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0});\r\n\r\n\r\n\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ Complex join with vendor information\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0$query-&gt;with(['vendor', 'reviews'])\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0-&gt;withCount('reviews')\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0-&gt;orderBy('rating', 'desc');\r\n\r\n\r\n\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ Paginate with custom per page\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return $query-&gt;paginate($filters['per_page'] ?? 15);\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0});\r\n\r\n\u00a0\u00a0\u00a0\u00a0}\r\n\r\n\r\n\r\n\r\n\u00a0\u00a0\u00a0\u00a0\/\/ Method to fetch products from external vendor\r\n\r\n\u00a0\u00a0\u00a0\u00a0public function getExternalVendorProducts($vendorId)\r\n\r\n\u00a0\u00a0\u00a0\u00a0{\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ Fetch products from external API\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0$externalProducts = $this-&gt;externalVendorService-&gt;getProducts($vendorId);\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ Transform and normalize external data\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return $this-&gt;transformExternalProducts($externalProducts);\r\n\r\n\u00a0\u00a0\u00a0\u00a0}\r\n\r\n\r\n\r\n\r\n\u00a0\u00a0\u00a0\u00a0\/\/ Advanced search method\r\n\r\n\u00a0\u00a0\u00a0\u00a0public function searchProducts($searchTerm, array $options = [])\r\n\r\n\u00a0\u00a0\u00a0\u00a0{\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return $this-&gt;model-&gt;search($searchTerm)\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0-&gt;when($options['category'] ?? null, function ($query, $category) {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return $query-&gt;where('category_id', $category);\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0})\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0-&gt;when($options['vendor'] ?? null, function ($query, $vendor) {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return $query-&gt;where('vendor_id', $vendor);\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0})\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0-&gt;paginate($options['per_page'] ?? 15);\r\n\r\n\u00a0\u00a0\u00a0\u00a0}\r\n\r\n\r\n\r\n\r\n\u00a0\u00a0\u00a0\u00a0\/\/ Complex aggregation method\r\n\r\n\u00a0\u00a0\u00a0\u00a0public function getVendorProductPerformance($vendorId)\r\n\r\n\u00a0\u00a0\u00a0\u00a0{\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return $this-&gt;model-&gt;where('vendor_id', $vendorId)\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0-&gt;select([\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0DB::raw('AVG(rating) as average_rating'),\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0DB::raw('COUNT(*) as total_products'),\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0DB::raw('SUM(total_sales) as cumulative_sales')\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0])\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0-&gt;first();\r\n\r\n\u00a0\u00a0\u00a0\u00a0}\r\n\r\n\r\n\r\n\r\n\u00a0\u00a0\u00a0\u00a0\/\/ Private helper method for cache key generation\r\n\r\n\u00a0\u00a0\u00a0\u00a0private function generateCacheKey(array $filters)\r\n\r\n\u00a0\u00a0\u00a0\u00a0{\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return 'products:' . md5(json_encode($filters));\r\n\r\n\u00a0\u00a0\u00a0\u00a0}\r\n\r\n}<\/pre>\n<p><\/code><\/pre>\n\t\t\t<\/div>\n        <\/div>\n<p><b>Why Repository Pattern is Necessary Here<\/b><\/p>\n<ol>\n<li><b> Separation of Concerns<\/b><\/li>\n<\/ol>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0&#8211; Isolates complex database logic from controllers<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0&#8211; Centralizes query logic in one place<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0&#8211; Makes code more maintainable and readable<\/span><\/p>\n<ol start=\"2\">\n<li><b> Flexibility in Data Sources<\/b><\/li>\n<\/ol>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0&#8211; Can easily switch between local database and external APIs<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0&#8211; Provides a consistent interface for data retrieval<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0&#8211; Allows seamless integration of multiple data sources<\/span><\/p>\n<ol start=\"3\">\n<li><b> Caching Strategy<\/b><\/li>\n<\/ol>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0&#8211; Implements sophisticated caching mechanism<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0&#8211; Reduces database load<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0&#8211; Improves application performance<\/span><\/p>\n<ol start=\"4\">\n<li><b> Complex Filtering and Search<\/b><\/li>\n<\/ol>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0&#8211; Provides advanced filtering capabilities<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0&#8211; Supports dynamic query building<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0&#8211; Enables complex search across multiple criteria<\/span><\/p>\n<p>&nbsp;<\/p>\n<ol start=\"5\">\n<li><b> Testability<\/b><\/li>\n<\/ol>\n<p><span style=\"font-weight: 400;\">\u00a0 <div class=\"dm-code-snippet dark default  dm-normal-version\" style=\"background-color:#abb8c3;\" snippet-height=\"\">\n\t\t\t<div class=\"control-language\">\n                <div class=\"dm-buttons\">\n                    <div class=\"dm-buttons-left\">\n                        <div class=\"dm-button-snippet red-button\"><\/div>\n                        <div class=\"dm-button-snippet orange-button\"><\/div>\n                        <div class=\"dm-button-snippet green-button\"><\/div>\n                    <\/div>\n                    <div class=\"dm-buttons-right\">\n                        <a id=\"dm-copy-raw-code\">\n                        <span class=\"dm-copy-text\">Copy Code<\/span>\n                        <span class=\"dm-copy-confirmed\" style=\"display:none\">Copied<\/span>\n                        <span class=\"dm-error-message\" style=\"display:none\">Use a different Browser<\/span><\/a>\n                    <\/div>\n                <\/div>\n                <pre class=\"no-line-numbers\"><code id=\"dm-code-raw\" class=\"no-wrap language-php\"><\/span><\/p>\n<pre class=\"dm-pre-admin-side\">\/\/ Easy to mock for unit testing\r\n\r\n\u00a0\u00a0\u00a0public function testProductRetrieval()\r\n\r\n\u00a0\u00a0\u00a0{\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0$mockRepo = Mockery::mock(ProductRepository::class);\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0$mockRepo-&gt;shouldReceive('getFilteredProducts')\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0-&gt;once()\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0-&gt;andReturn(collect([]));\r\n\r\n\r\n\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ Test controller or service logic\r\n\r\n\u00a0\u00a0\u00a0}<\/pre>\n<p><span style=\"font-weight: 400;\"><\/code><\/pre>\n\t\t\t<\/div>\n        <\/div><\/span><\/p>\n<p>&nbsp;<\/p>\n<p><b>Additional Benefits in This Scenario<\/b><\/p>\n<p><b>&#8211; Performance Optimization<\/b><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0&#8211; Centralized query optimization<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0&#8211; Consistent caching strategy<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0&#8211; Reduced database hits<\/span><\/p>\n<p><b>&#8211; Scalability<\/b><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0&#8211; Easy to modify data retrieval logic<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0&#8211; Supports future extensions<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0&#8211; Decoupled from direct Eloquent usage<\/span><\/p>\n<p><b>When This Approach Shines<\/b><\/p>\n<p><span style=\"font-weight: 400;\">\ud83d\udc49 Large, complex applications<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\ud83d\udc49 Multiple data sources<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\ud83d\udc49 Advanced querying requirements<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\ud83d\udc49 Performance-critical systems<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\ud83d\udc49 Microservices architectures<\/span><\/p>\n<p><b>Potential Drawbacks (Mitigated)<\/b><\/p>\n<ol>\n<li><b>Complexity<\/b><span style=\"font-weight: 400;\">: Managed through clean, well-structured implementation<\/span><\/li>\n<li><b>Performance Overhead<\/b><span style=\"font-weight: 400;\">: Minimized through efficient caching<\/span><\/li>\n<li><b>Abstraction<\/b><span style=\"font-weight: 400;\">: Provides tangible benefits in complex scenarios<\/span><\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<p><b>Key Takeaway<\/b><\/p>\n<p><span style=\"font-weight: 400;\">The Repository pattern is not about blind abstraction but strategic decoupling. In scenarios with complex data interactions, it provides significant architectural advantages that outweigh its minor performance implications.<\/span><\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Detailed Use Case: E-Commerce Platform with Complex Data Requirements Scenario: Multi-Vendor Marketplace System Initial Context Imagine an e-commerce platform with the following complex requirements: &#8211; Multiple data sources (internal database, external vendor APIs) &#8211; Complex querying across different models &#8211; Need for extensive caching &#8211; Requirement for advanced filtering and search &#8211; Performance optimization &#8211; [&hellip;]<\/p>\n","protected":false},"author":17,"featured_media":4292,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"footnotes":""},"categories":[332],"tags":[],"class_list":["post-4288","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-laravel"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.rcvtechnologies.com\/blog\/wp-json\/wp\/v2\/posts\/4288","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.rcvtechnologies.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.rcvtechnologies.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.rcvtechnologies.com\/blog\/wp-json\/wp\/v2\/users\/17"}],"replies":[{"embeddable":true,"href":"https:\/\/www.rcvtechnologies.com\/blog\/wp-json\/wp\/v2\/comments?post=4288"}],"version-history":[{"count":4,"href":"https:\/\/www.rcvtechnologies.com\/blog\/wp-json\/wp\/v2\/posts\/4288\/revisions"}],"predecessor-version":[{"id":4293,"href":"https:\/\/www.rcvtechnologies.com\/blog\/wp-json\/wp\/v2\/posts\/4288\/revisions\/4293"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.rcvtechnologies.com\/blog\/wp-json\/wp\/v2\/media\/4292"}],"wp:attachment":[{"href":"https:\/\/www.rcvtechnologies.com\/blog\/wp-json\/wp\/v2\/media?parent=4288"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.rcvtechnologies.com\/blog\/wp-json\/wp\/v2\/categories?post=4288"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.rcvtechnologies.com\/blog\/wp-json\/wp\/v2\/tags?post=4288"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}