[{"data":1,"prerenderedAt":796},["ShallowReactive",2],{"post-\u002Fphp-graphql-development-advanced-techniques-for-optimizing-your-apis":3},{"page":4,"translation":653,"nav":667,"related":780,"random":789},{"id":5,"title":6,"body":7,"categories":651,"category":653,"date":654,"description":655,"draft":656,"extension":657,"image":658,"kind":653,"lang":659,"meta":660,"navigation":99,"path":661,"readingTime":115,"seo":662,"slug":663,"stem":663,"tags":664,"translationKey":653,"type":652,"updated":653,"__hash__":666},"posts\u002Fphp-graphql-development-advanced-techniques-for-optimizing-your-apis.md","PHP GraphQL Development: Advanced Techniques for Optimizing Your APIs",{"type":8,"value":9,"toc":640},"minimark",[10,61,64,71,77,328,347,350,353,358,365,378,381,492,494,498,501,504,551,553,557,562,565,569,572,576,581,585,588,592,595,630,636],[11,12,13,21],"blockquote",{},[14,15,16,17],"p",{},"💡 ",[18,19,20],"strong",{},"Quick Summary (TL;DR):",[22,23,24,31],"ul",{},[25,26,27,30],"li",{},[18,28,29],{},"Core Concept:"," GraphQL offers clients the power to ask for exactly what they need, but in PHP, unoptimized resolvers can easily trigger the notorious N+1 database query problem.",[25,32,33,36],{},[18,34,35],{},"Key Optimization Techniques:",[22,37,38,49,55],{},[25,39,40,43,44,48],{},[18,41,42],{},"Batching & Deferred Resolvers:"," Solve N+1 issues using webonyx\u002Fgraphql-php's built-in ",[45,46,47],"code",{},"GraphQL\\Deferred"," class.",[25,50,51,54],{},[18,52,53],{},"Query Complexity Analysis:"," Set limit rules using query depth and complexity limiters to prevent DDoS-like deeply nested queries.",[25,56,57,60],{},[18,58,59],{},"Caching:"," Cache the compiled schema and use Redis\u002FMemcached for caching resolver results.",[14,62,63],{},"GraphQL is a query language for APIs that allows clients to request only the data they need, making it an efficient and flexible alternative to traditional RESTful APIs. In this article, we will explore how to implement and optimize GraphQL APIs in PHP, using code examples to illustrate key concepts.",[14,65,66,67,70],{},"To get started, you will need to install a GraphQL server library for PHP, such as ",[45,68,69],{},"webonyx\u002Fgraphql-php",". This library provides a set of tools for building GraphQL servers in PHP, including a schema language for defining the types and fields of your API, and a runtime for executing queries against that schema.",[14,72,73,74,76],{},"Here is a simple example of a GraphQL server implemented using ",[45,75,69],{},":",[78,79,84],"pre",{"className":80,"code":81,"language":82,"meta":83,"style":83},"language-php shiki shiki-themes github-light github-dark","require_once __DIR__ . '\u002Fvendor\u002Fautoload.php';\n\nuse GraphQL\\Type\\Definition\\ObjectType;\nuse GraphQL\\Type\\Definition\\Type;\nuse GraphQL\\GraphQL;\nuse GraphQL\\Type\\Schema;\n\n$queryType = new ObjectType([\n    'name' => 'Query',\n    'fields' => [\n        'hello' => [\n            'type' => Type::string(),\n            'resolve' => function () {\n                return 'Hello, world!';\n            }\n        ]\n    ]\n]);\n\n$schema = new Schema([\n    'query' => $queryType\n]);\n\n$rawInput = file_get_contents('php:\u002F\u002Finput');\n$input = json_decode($rawInput, true);\n$query = $input['query'] ?? null;\n$variableValues = $input['variables'] ?? null;\n\ntry {\n    $result = GraphQL::executeQuery($schema, $query, null, null, $variableValues);\n    $output = $result->toArray();\n} catch (\\Exception $e) {\n    $output = [\n        'error' => [\n            'message' => $e->getMessage()\n        ]\n    ];\n}\n\nheader('Content-Type: application\u002Fjson');\necho json_encode($output);\n","php","",[45,85,86,94,101,107,113,119,125,130,136,142,148,154,160,166,172,178,184,190,196,201,207,213,218,223,229,235,241,247,252,258,264,270,276,282,288,294,299,305,311,316,322],{"__ignoreMap":83},[87,88,91],"span",{"class":89,"line":90},"line",1,[87,92,93],{},"require_once __DIR__ . '\u002Fvendor\u002Fautoload.php';\n",[87,95,97],{"class":89,"line":96},2,[87,98,100],{"emptyLinePlaceholder":99},true,"\n",[87,102,104],{"class":89,"line":103},3,[87,105,106],{},"use GraphQL\\Type\\Definition\\ObjectType;\n",[87,108,110],{"class":89,"line":109},4,[87,111,112],{},"use GraphQL\\Type\\Definition\\Type;\n",[87,114,116],{"class":89,"line":115},5,[87,117,118],{},"use GraphQL\\GraphQL;\n",[87,120,122],{"class":89,"line":121},6,[87,123,124],{},"use GraphQL\\Type\\Schema;\n",[87,126,128],{"class":89,"line":127},7,[87,129,100],{"emptyLinePlaceholder":99},[87,131,133],{"class":89,"line":132},8,[87,134,135],{},"$queryType = new ObjectType([\n",[87,137,139],{"class":89,"line":138},9,[87,140,141],{},"    'name' => 'Query',\n",[87,143,145],{"class":89,"line":144},10,[87,146,147],{},"    'fields' => [\n",[87,149,151],{"class":89,"line":150},11,[87,152,153],{},"        'hello' => [\n",[87,155,157],{"class":89,"line":156},12,[87,158,159],{},"            'type' => Type::string(),\n",[87,161,163],{"class":89,"line":162},13,[87,164,165],{},"            'resolve' => function () {\n",[87,167,169],{"class":89,"line":168},14,[87,170,171],{},"                return 'Hello, world!';\n",[87,173,175],{"class":89,"line":174},15,[87,176,177],{},"            }\n",[87,179,181],{"class":89,"line":180},16,[87,182,183],{},"        ]\n",[87,185,187],{"class":89,"line":186},17,[87,188,189],{},"    ]\n",[87,191,193],{"class":89,"line":192},18,[87,194,195],{},"]);\n",[87,197,199],{"class":89,"line":198},19,[87,200,100],{"emptyLinePlaceholder":99},[87,202,204],{"class":89,"line":203},20,[87,205,206],{},"$schema = new Schema([\n",[87,208,210],{"class":89,"line":209},21,[87,211,212],{},"    'query' => $queryType\n",[87,214,216],{"class":89,"line":215},22,[87,217,195],{},[87,219,221],{"class":89,"line":220},23,[87,222,100],{"emptyLinePlaceholder":99},[87,224,226],{"class":89,"line":225},24,[87,227,228],{},"$rawInput = file_get_contents('php:\u002F\u002Finput');\n",[87,230,232],{"class":89,"line":231},25,[87,233,234],{},"$input = json_decode($rawInput, true);\n",[87,236,238],{"class":89,"line":237},26,[87,239,240],{},"$query = $input['query'] ?? null;\n",[87,242,244],{"class":89,"line":243},27,[87,245,246],{},"$variableValues = $input['variables'] ?? null;\n",[87,248,250],{"class":89,"line":249},28,[87,251,100],{"emptyLinePlaceholder":99},[87,253,255],{"class":89,"line":254},29,[87,256,257],{},"try {\n",[87,259,261],{"class":89,"line":260},30,[87,262,263],{},"    $result = GraphQL::executeQuery($schema, $query, null, null, $variableValues);\n",[87,265,267],{"class":89,"line":266},31,[87,268,269],{},"    $output = $result->toArray();\n",[87,271,273],{"class":89,"line":272},32,[87,274,275],{},"} catch (\\Exception $e) {\n",[87,277,279],{"class":89,"line":278},33,[87,280,281],{},"    $output = [\n",[87,283,285],{"class":89,"line":284},34,[87,286,287],{},"        'error' => [\n",[87,289,291],{"class":89,"line":290},35,[87,292,293],{},"            'message' => $e->getMessage()\n",[87,295,297],{"class":89,"line":296},36,[87,298,183],{},[87,300,302],{"class":89,"line":301},37,[87,303,304],{},"    ];\n",[87,306,308],{"class":89,"line":307},38,[87,309,310],{},"}\n",[87,312,314],{"class":89,"line":313},39,[87,315,100],{"emptyLinePlaceholder":99},[87,317,319],{"class":89,"line":318},40,[87,320,321],{},"header('Content-Type: application\u002Fjson');\n",[87,323,325],{"class":89,"line":324},41,[87,326,327],{},"echo json_encode($output);\n",[14,329,330,331,334,335,338,339,342,343,346],{},"In this example, we define a simple ",[45,332,333],{},"Query"," type with a single field ",[45,336,337],{},"hello",", which returns the string \"Hello, world!\" when queried. We then create a new ",[45,340,341],{},"Schema"," object that uses this query type as its root, and pass it to the ",[45,344,345],{},"GraphQL::executeQuery"," function along with the incoming query and variable values. The result of the query is then returned as a JSON encoded object.",[14,348,349],{},"Once you've got your GraphQL API up and running, you can optimize its performance by using caching and batching techniques. One technique is to use a caching layer like Redis or Memcached to store the results of frequently executed queries. This can significantly improve the performance of your API, especially under heavy load. Another technique is to use batching to process multiple queries in a single request, reducing the overhead of multiple round-trips to the server.",[351,352],"hr",{},[354,355,357],"h2",{"id":356},"solving-the-n1-query-problem-with-deferred-resolvers","Solving the N+1 Query Problem with Deferred Resolvers",[14,359,360,361,364],{},"One of the most common performance bottlenecks in GraphQL APIs is the ",[18,362,363],{},"N+1 query problem",". For example, if you fetch a list of 100 posts and resolve the author for each post individually, you might end up executing 1 database query to fetch the posts, and then 100 separate queries to fetch each author.",[14,366,367,368,370,371,374,375,377],{},"The ",[45,369,69],{}," library provides a built-in mechanism called ",[18,372,373],{},"Deferred Resolvers"," (using ",[45,376,47],{},") to batch these database queries. Instead of fetching the author immediately, the resolver returns a promise-like deferred object. Once all fields are visited, the library runs the deferred batch execution.",[14,379,380],{},"Here is how you implement it:",[78,382,384],{"className":80,"code":383,"language":82,"meta":83,"style":83},"use GraphQL\\Type\\Definition\\ObjectType;\nuse GraphQL\\Type\\Definition\\Type;\nuse GraphQL\\Deferred;\n\n$postType = new ObjectType([\n    'name' => 'Post',\n    'fields' => [\n        'title' => Type::string(),\n        'author' => [\n            'type' => $userType,\n            'resolve' => function ($post) {\n                \u002F\u002F Buffer the author ID for batch loading\n                UserBuffer::add($post['author_id']);\n\n                \u002F\u002F Defer the resolution until all author IDs are buffered\n                return new Deferred(function () use ($post) {\n                    UserBuffer::loadBuffered(); \u002F\u002F Fetches all buffered IDs in ONE query\n                    return UserBuffer::get($post['author_id']);\n                });\n            }\n        ]\n    ]\n]);\n",[45,385,386,390,394,399,403,408,413,417,422,427,432,437,442,447,451,456,461,466,471,476,480,484,488],{"__ignoreMap":83},[87,387,388],{"class":89,"line":90},[87,389,106],{},[87,391,392],{"class":89,"line":96},[87,393,112],{},[87,395,396],{"class":89,"line":103},[87,397,398],{},"use GraphQL\\Deferred;\n",[87,400,401],{"class":89,"line":109},[87,402,100],{"emptyLinePlaceholder":99},[87,404,405],{"class":89,"line":115},[87,406,407],{},"$postType = new ObjectType([\n",[87,409,410],{"class":89,"line":121},[87,411,412],{},"    'name' => 'Post',\n",[87,414,415],{"class":89,"line":127},[87,416,147],{},[87,418,419],{"class":89,"line":132},[87,420,421],{},"        'title' => Type::string(),\n",[87,423,424],{"class":89,"line":138},[87,425,426],{},"        'author' => [\n",[87,428,429],{"class":89,"line":144},[87,430,431],{},"            'type' => $userType,\n",[87,433,434],{"class":89,"line":150},[87,435,436],{},"            'resolve' => function ($post) {\n",[87,438,439],{"class":89,"line":156},[87,440,441],{},"                \u002F\u002F Buffer the author ID for batch loading\n",[87,443,444],{"class":89,"line":162},[87,445,446],{},"                UserBuffer::add($post['author_id']);\n",[87,448,449],{"class":89,"line":168},[87,450,100],{"emptyLinePlaceholder":99},[87,452,453],{"class":89,"line":174},[87,454,455],{},"                \u002F\u002F Defer the resolution until all author IDs are buffered\n",[87,457,458],{"class":89,"line":180},[87,459,460],{},"                return new Deferred(function () use ($post) {\n",[87,462,463],{"class":89,"line":186},[87,464,465],{},"                    UserBuffer::loadBuffered(); \u002F\u002F Fetches all buffered IDs in ONE query\n",[87,467,468],{"class":89,"line":192},[87,469,470],{},"                    return UserBuffer::get($post['author_id']);\n",[87,472,473],{"class":89,"line":198},[87,474,475],{},"                });\n",[87,477,478],{"class":89,"line":203},[87,479,177],{},[87,481,482],{"class":89,"line":209},[87,483,183],{},[87,485,486],{"class":89,"line":215},[87,487,189],{},[87,489,490],{"class":89,"line":220},[87,491,195],{},[351,493],{},[354,495,497],{"id":496},"limiting-query-complexity-and-depth","Limiting Query Complexity and Depth",[14,499,500],{},"Another important aspect of optimizing a GraphQL API is limiting the number of nested fields or limiting the data volume to the needed minimum. Because in GraphQL clients can ask for any data available in the API, it can result in large queries and high response data volume that can overload the server.",[14,502,503],{},"You can use query depth and query complexity limiters to protect your server:",[78,505,507],{"className":80,"code":506,"language":82,"meta":83,"style":83},"use GraphQL\\Validator\\Rules\\QueryDepth;\nuse GraphQL\\Validator\\Rules\\QueryComplexity;\nuse GraphQL\\GraphQL;\n\n\u002F\u002F Restrict maximum query depth to 5 levels\nDocumentValidator::addRule(new QueryDepth(5));\n\n\u002F\u002F Restrict maximum query complexity score to 100\nDocumentValidator::addRule(new QueryComplexity(100));\n",[45,508,509,514,519,523,527,532,537,541,546],{"__ignoreMap":83},[87,510,511],{"class":89,"line":90},[87,512,513],{},"use GraphQL\\Validator\\Rules\\QueryDepth;\n",[87,515,516],{"class":89,"line":96},[87,517,518],{},"use GraphQL\\Validator\\Rules\\QueryComplexity;\n",[87,520,521],{"class":89,"line":103},[87,522,118],{},[87,524,525],{"class":89,"line":109},[87,526,100],{"emptyLinePlaceholder":99},[87,528,529],{"class":89,"line":115},[87,530,531],{},"\u002F\u002F Restrict maximum query depth to 5 levels\n",[87,533,534],{"class":89,"line":121},[87,535,536],{},"DocumentValidator::addRule(new QueryDepth(5));\n",[87,538,539],{"class":89,"line":127},[87,540,100],{"emptyLinePlaceholder":99},[87,542,543],{"class":89,"line":132},[87,544,545],{},"\u002F\u002F Restrict maximum query complexity score to 100\n",[87,547,548],{"class":89,"line":138},[87,549,550],{},"DocumentValidator::addRule(new QueryComplexity(100));\n",[351,552],{},[354,554,556],{"id":555},"frequently-asked-questions-faq","Frequently Asked Questions (FAQ)",[558,559,561],"h3",{"id":560},"what-is-graphql","What is GraphQL?",[14,563,564],{},"GraphQL is a query language for APIs that allows clients to request only the data they need, making it an efficient and flexible alternative to traditional RESTful APIs.",[558,566,568],{"id":567},"what-is-the-advantage-of-using-graphql-over-rest","What is the advantage of using GraphQL over REST?",[14,570,571],{},"One of the main advantages of GraphQL over REST is its ability to request only the data you need. This reduces the amount of data that needs to be transferred over the network and allows for more efficient use of resources on both the client and the server. GraphQL also provides a more flexible and powerful way of querying data, allowing for more complex and dynamic queries.",[558,573,575],{"id":574},"what-are-some-benefits-of-using-webonyxgraphql-php-library","What are some benefits of using webonyx\u002Fgraphql-php library?",[14,577,578,580],{},[45,579,69],{}," is a popular and well-documented library for building GraphQL servers in PHP. It provides a set of tools for defining the types and fields of your API, a runtime for executing queries against the schema, and support for handling errors and validation. It also supports advanced features such as subscriptions, cursor-based pagination, and type definition caching.",[558,582,584],{"id":583},"how-can-i-improve-the-performance-of-my-graphql-api","How can I improve the performance of my GraphQL API?",[14,586,587],{},"There are several ways to improve the performance of a GraphQL API, such as using caching and batching techniques, limiting the number of nested fields, and limiting the data volume to the minimum needed. Additionally, you can also tune your database to handle the specific type of queries that GraphQL generates.",[558,589,591],{"id":590},"where-can-i-find-further-resources-on-graphql","Where can I find further resources on GraphQL?",[14,593,594],{},"Here are some resources that you may find helpful when working with GraphQL:",[22,596,597,609,616,623],{},[25,598,599,600],{},"Official GraphQL documentation: ",[601,602,603],"a",{"href":603,"rel":604,"target":608},"https:\u002F\u002Fgraphql.org\u002Flearn\u002F",[605,606,607],"nofollow","noopener","noreferrer","_blank",[25,610,611,612],{},"GraphQL PHP community: ",[601,613,614],{"href":614,"rel":615,"target":608},"https:\u002F\u002Fgithub.com\u002Fwebonyx\u002Fgraphql-php",[605,606,607],[25,617,618,619],{},"GraphQL on GitHub: ",[601,620,621],{"href":621,"rel":622,"target":608},"https:\u002F\u002Fgithub.com\u002Fgraphql",[605,606,607],[25,624,625,626],{},"GraphQL best practices on Apollo blog: ",[601,627,628],{"href":628,"rel":629,"target":608},"https:\u002F\u002Fwww.apollographql.com\u002Fblog\u002Fbest-practices-for-building-a-graphql-server-b7fa94b90891",[605,606,607],[14,631,632,633,635],{},"In conclusion, GraphQL is a powerful and flexible alternative to traditional RESTful APIs. With the help of a library like ",[45,634,69],{},", it's easy to implement a GraphQL server in PHP. Optimizing performance can be achieved by using caching and batching, limiting nested fields and limiting data volume. These advanced techniques can help to make your GraphQL API more efficient, reliable and user-friendly.",[637,638,639],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":83,"searchDepth":96,"depth":96,"links":641},[642,643,644],{"id":356,"depth":96,"text":357},{"id":496,"depth":96,"text":497},{"id":555,"depth":96,"text":556,"children":645},[646,647,648,649,650],{"id":560,"depth":103,"text":561},{"id":567,"depth":103,"text":568},{"id":574,"depth":103,"text":575},{"id":583,"depth":103,"text":584},{"id":590,"depth":103,"text":591},[652],"technical",null,"2023-01-19","How to optimize PHP GraphQL APIs: implementing caching, batching, solving the N+1 query problem using Webonyx Deferred Resolvers, and query complexity analysis.",false,"md","\u002Fimages\u002Fhero\u002Fgraphql.avif","en",{},"\u002Fphp-graphql-development-advanced-techniques-for-optimizing-your-apis",{"title":6,"description":655},"php-graphql-development-advanced-techniques-for-optimizing-your-apis",[665,82],"graphql","_HPsSrz4qOyc0S2jIobq0VZNUtMwhtK748e0ZcBVJ5Q",{"prev":668,"next":671,"others":674,"lucky":779,"readingTime":115},{"path":669,"title":670},"\u002Fgetting-started-with-devops-understanding-the-principles-and-adopting-the-tools","Getting Started with DevOps: Understanding the Principles and Adopting the Tools",{"path":672,"title":673},"\u002Fadvanced-techniques-for-dependency-injection-in-php-tips-code-samples-and-faqs","Advanced Techniques for Dependency Injection in PHP: Tips, Code Samples, and FAQs",[675,678,681,684,687,690,693,696,699,702,705,708,709,710,713,716,719,722,725,728,731,734,737,740,743,746,749,752,755,758,761,764,767,770,773,776],{"path":676,"title":677},"\u002Ffull-stack-project-development","Sample REST API Project",{"path":679,"title":680},"\u002Frest-api-authentication","How to Perform REST API Authentication?",{"path":682,"title":683},"\u002Frest-api-design","REST API Design: Principles and Output Format",{"path":685,"title":686},"\u002Frest-api-documentation-and-testing","How to Document and Test a REST API?",{"path":688,"title":689},"\u002Frest-api-error-handling","How to Perform REST API Error Handling?",{"path":691,"title":692},"\u002Frest-api-security","How to Secure a REST API?",{"path":694,"title":695},"\u002Frest-api-uri-structure","What Should the REST API URI Structure Be?",{"path":697,"title":698},"\u002Ftroubleshooting-cyberpanel-inaccessibility-after-ubuntu-release-upgrade","Troubleshooting CyberPanel Inaccessibility After Ubuntu Release Upgrade",{"path":700,"title":701},"\u002Freset-wordpress-admin-password-using-wp-cli","Reset WordPress Admin Password Using WP-CLI",{"path":703,"title":704},"\u002Fgraphql-vs-rest-api-which-is-the-best-choice-for-headless-wordpress","GraphQL vs REST API: Which is the Best Choice for Headless WordPress?",{"path":706,"title":707},"\u002Fgrow-your-business-in-turkey-with-expert-wordpress-plugin-and-theme-localization-and-support-services","Grow Your Business in Turkey with Expert WordPress Plugin and Theme Localization and Support Services",{"path":669,"title":670},{"path":672,"title":673},{"path":711,"title":712},"\u002Fmaximize-the-potential-of-headless-wordpress-with-graphql","Maximize the Potential of Headless WordPress with GraphQL",{"path":714,"title":715},"\u002Fwriting-clean-modular-and-reusable-code-in-php","Best Practices for Writing Clean, Modular, and Reusable Code in PHP",{"path":717,"title":718},"\u002Fheadless-cmss-an-overview-of-popular-alternatives-to-contentful-and-wordpress","Headless CMSs: An Overview of Popular Alternatives to Contentful and WordPress",{"path":720,"title":721},"\u002Fci-cd-for-php-a-comprehensive-guide","CI\u002FCD for PHP: A Comprehensive Guide",{"path":723,"title":724},"\u002Fintroduction-to-php-namespaces-a-beginners-guide-to-structuring-your-code","Introduction to PHP Namespaces: A Beginner's Guide to Structuring Your Code",{"path":726,"title":727},"\u002Fwhat-is-graylog-a-powerful-tool-for-collecting-indexing-and-analyzing-log-data","What is Graylog? A Powerful Tool for Collecting, Indexing, and Analyzing Log Data",{"path":729,"title":730},"\u002Felevate-your-turkish-audience-experience-with-professional-wordpress-plugin-and-theme-translation","Elevate Your Turkish Audience Experience with Professional WordPress Plugin and Theme Translation",{"path":732,"title":733},"\u002Fhow-to-set-up-a-self-hosted-api-gateway-a-comprehensive-guide","How to Set Up a Self-Hosted API Gateway: A Comprehensive Guide",{"path":735,"title":736},"\u002Fdifference-between-generators-and-iterators-in-php","The Key Differences Between PHP Generators and Iterators",{"path":738,"title":739},"\u002Fphp-and-machine-learning-a-winning-combination-with-php-ml","PHP and Machine Learning: A Winning Combination with PHP-ML",{"path":741,"title":742},"\u002Fphp-generators-a-beginners-guide-to-iteration","PHP Generators: A Beginner's Guide to Iteration",{"path":744,"title":745},"\u002Fmastering-closures-in-javascript-a-beginners-guide","Mastering Closures in JavaScript: A Beginner's Guide",{"path":747,"title":748},"\u002Fthe-top-php-certification-programs-for-developers","The Top PHP Certification Programs for Developers",{"path":750,"title":751},"\u002Fhow-to-revalidate-next-js-isr-cache-on-demand-cache-regeneration","How to Revalidate Next.js ISR Cache? On-Demand Cache Regeneration",{"path":753,"title":754},"\u002Ftips-for-translating-a-wordpress-plugin-wordpress-theme-to-turkish","Tips for Translating a WordPress Plugin \u002F WordPress Theme to Turkish",{"path":756,"title":757},"\u002Fall-about-headless-wordpress","All About Headless WordPress",{"path":759,"title":760},"\u002Finstall-composer-on-ubuntu","How to Install Composer on Ubuntu \u002F Linux",{"path":762,"title":763},"\u002Fwhat-is-an-api-gateway","What is an API Gateway? Should You Use It?",{"path":765,"title":766},"\u002Fis-jwt-safe-or-is-it-vulnerable","Is JWT Safe or Is It Vulnerable?",{"path":768,"title":769},"\u002Ftailwind-css-to-use-or-not-to-use-that-is-the-question","Tailwind CSS! To use? Or not to use? That is the question.",{"path":771,"title":772},"\u002Fwhat-is-hateoas","What is HATEOAS?",{"path":774,"title":775},"\u002Fhello-world","Hello World: A New Multilingual Journey",{"path":777,"title":778},"\u002Fwhat-is-ecmascript","What is ECMAScript? What is not?",{"path":732,"title":733},[781,783,785,787],{"path":676,"title":677,"date":782},"2026-06-20",{"path":714,"title":715,"date":784},"2023-01-17",{"path":723,"title":724,"date":786},"2023-01-13",{"path":741,"title":742,"date":788},"2023-01-10",[790,792,794],{"path":768,"title":769,"date":791},"2022-05-12",{"path":700,"title":701,"date":793},"2023-07-02",{"path":732,"title":733,"date":795},"2023-01-12",1782141980064]