Deprecated function: Creation of dynamic property Drupal\Core\DrupalKernel::$_serviceId is deprecated in Drupal\Core\DependencyInjection\Container->set() (line 20 of /home4/foketina/public_html/core/lib/Drupal/Core/DependencyInjection/Container.php).
Drupal\Core\DependencyInjection\Container->set('kernel', Object) (Line: 1191)
Drupal\Core\DrupalKernel->attachSynthetic(Object) (Line: 924)
Drupal\Core\DrupalKernel->initializeContainer() (Line: 472)
Drupal\Core\DrupalKernel->boot() (Line: 707)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Deprecated function: Creation of dynamic property Composer\Autoload\ClassLoader::$_serviceId is deprecated in Drupal\Core\DependencyInjection\Container->set() (line 20 of /home4/foketina/public_html/core/lib/Drupal/Core/DependencyInjection/Container.php).
Drupal\Core\DependencyInjection\Container->set('class_loader', Object) (Line: 1194)
Drupal\Core\DrupalKernel->attachSynthetic(Object) (Line: 924)
Drupal\Core\DrupalKernel->initializeContainer() (Line: 472)
Drupal\Core\DrupalKernel->boot() (Line: 707)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Deprecated function: Creation of dynamic property Drupal\Core\Http\RequestStack::$_serviceId is deprecated in Drupal\Component\DependencyInjection\Container->createService() (line 288 of /home4/foketina/public_html/core/lib/Drupal/Component/DependencyInjection/Container.php).
Drupal\Component\DependencyInjection\Container->createService(Array, 'request_stack') (Line: 176)
Drupal\Component\DependencyInjection\Container->get('request_stack', 2) (Line: 933)
Drupal\Core\DrupalKernel->initializeContainer() (Line: 472)
Drupal\Core\DrupalKernel->boot() (Line: 707)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
API https://skuhan.com/index.php/ en Check new tutorials: Search API and Solr in Drupal 8 https://skuhan.com/index.php/blogs/check-new-tutorials-search-api-and-solr-drupal-8 <span>Check new tutorials: Search API and Solr in Drupal 8</span> <span><span lang="" about="https://skuhan.com/user/1" typeof="schema:Person" property="schema:name" datatype="" xml:lang="">admin</span></span> <span>Wed, 03/04/2020 - 22:10</span> <div class="field field--name-field-s-b-image field--type-image field--label-hidden field--item"> <img src="https://skuhan.com/sites/default/files/2020-03/search-series.png" width="1920" height="1080" alt="" loading="lazy" typeof="foaf:Image" class="img-responsive" /> </div> <div class="field field--name-body field--type-text-with-summary field--label-hidden field--item"><p>Drupalize.me has published 18 tutorials on <a href="https://drupalize.me/series/search-api-and-solr-drupal">Search API and Solr in Drupal</a>. Learn about Drupal's built-in search capabilities and how to take your site's search to the next level with Apache Solr in this new series. You'll also learn how to set up your local development environment using Docker so that you can follow along. By the end of this series you'll have a firm grasp on concepts related to Search API and Solr in Drupal and how to configure the software for use on your Drupal 8 application.</p> <h3>Tutorials:</h3> <ul> <li><a href="https://drupalize.me/tutorial/why-solr">Why Solr?</a></li> <li><a href="https://drupalize.me/tutorial/plan-solr-installation">Plan a Solr Installation</a></li> <li><a href="https://drupalize.me/tutorial/use-solr-locally">Use Solr Locally</a></li> <li><a href="https://drupalize.me/tutorial/solr-cores">Solr Cores</a></li> <li><a href="https://drupalize.me/tutorial/install-search-api">Install Search API</a></li> <li><a href="https://drupalize.me/tutorial/solr-and-multiple-environments">Solr and Multiple Environments</a></li> <li><a href="https://drupalize.me/tutorial/create-search-api-indexes">Create Search API Indexes</a></li> <li><a href="https://drupalize.me/tutorial/populate-search-api-indexes">Populate Search API Indexes</a></li> <li><a href="https://drupalize.me/tutorial/index-reference-fields">Index Reference Fields</a></li> <li><a href="https://drupalize.me/tutorial/create-search-pages-and-blocks-views">Create Search Pages and Blocks with Views</a></li> <li><a href="https://drupalize.me/tutorial/multiple-search-api-indexes">Multiple Search API Indexes</a></li> <li><a href="https://drupalize.me/tutorial/processors-search">Processors in Search</a></li> <li><a href="https://drupalize.me/tutorial/add-excerpts-search-results">Add Excerpts for Search Results</a></li> <li><a href="https://drupalize.me/tutorial/add-autocomplete-search">Add Autocomplete to Search</a></li> <li><a href="https://drupalize.me/tutorial/filter-search-results">Filter Search Results</a></li> <li><a href="https://drupalize.me/tutorial/facets-search">Facets in Search</a></li> <li><a href="https://drupalize.me/tutorial/create-facet">Create a Facet</a></li> <li><a href="https://drupalize.me/tutorial/create-facet-using-taxonomy">Create a Facet using Taxonomy</a></li> </ul> <h3>About the author of these tutorials</h3> <p>Tess Flynn, also known as <a href="https://www.drupal.org/u/socketwench">socketwench</a>, is a devops engineer who has worked with Drupal for over a decade. She is the author of the Flag module for Drupal 8 and has given sessions at DrupalCons and DrupalCamps throughout the world on Drupal 8 development, Docker, and DevOps.</p> <p>Thanks, Tess!</p> <h3>What's next?</h3> <p>Next up, we'll be releasing a new guide based on our popular "Introduction to Theming" workshop. Watch for Hands-On Theming, a guide featuring practical exercises and video walkthroughs, to be published later this month.</p> <p>by <a href="https://drupalize.me/team/amber-matz">Amber Matz</a> (drupalize.me)</p></div> <div class="field field--name-field-s-b-tags field--type-entity-reference field--label-hidden field--items"> <div class="field--item"><a href="https://skuhan.com/taxonomy/term/53" hreflang="en">API</a></div> <div class="field--item"><a href="https://skuhan.com/taxonomy/term/58" hreflang="en">SOLR</a></div> <div class="field--item"><a href="https://skuhan.com/taxonomy/term/50" hreflang="en">Drupal 8</a></div> </div> Wed, 04 Mar 2020 21:10:30 +0000 admin 13 at https://skuhan.com Consuming REST APIs with Drupal 8 https://skuhan.com/index.php/blogs/consuming-rest-apis-drupal-8 <span>Consuming REST APIs with Drupal 8</span> <span><span lang="" about="https://skuhan.com/user/1" typeof="schema:Person" property="schema:name" datatype="" xml:lang="">admin</span></span> <span>Wed, 03/04/2020 - 17:14</span> <div class="field field--name-field-s-b-image field--type-image field--label-hidden field--item"> <img src="https://skuhan.com/sites/default/files/2020-03/Rest-API-introduction.jpg" width="700" height="368" alt="" loading="lazy" typeof="foaf:Image" class="img-responsive" /> </div> <div class="field field--name-body field--type-text-with-summary field--label-hidden field--item"><p>In trying to answer the question I realized that I first needed to know more about what they are trying to accomplish. Like with most things Drupal, there's more than one right way to accomplish a task. Choosing a solution requires understanding what options are available and the pros and cons of each. This got me thinking about the various different ways one could consume data from an API and display it using Drupal 8.</p> <h2>The problem at a high level</h2> <p>You've got data in an external service, available via a REST API, that you need to display on one or more pages in a Drupal site. Perhaps accessing that data requires authentication via OAuth2 or an API token. There are numerous ways to go about it. Which one should you choose? And how should you get started?</p> <p>Some questions to ask yourself before you start:</p> <ul> <li>How much data are we talking about?</li> <li>How frequently does the data you're consuming change, and how import is it that it's up-to-date? Are real-time updates required? Or is a short lag acceptable?</li> <li>Does that data being consumed from the API need to be incorporated into the Drupal-generated pages' HTML output? How does it impact SEO?</li> <li>How much control does a Drupal site administrator need to have over how the data is displayed?</li> </ul> <p>While I'm certain this list is not exhaustive, here's are some of the approaches I'm aware of:</p> <ul> <li>Use the Migrate API</li> <li>Create a Views Query Plugin</li> <li>Write a custom service that uses Guzzle or similar PHP SDK via Composer</li> <li>Use JavaScript</li> </ul> <p>I'll explain each one a little more, and provide some ideas about what you'll need to learn in order to implement them.</p> <h2>Option 1: Use the Migrate API</h2> <p>Use the Migrate API combined with the HTTP Fetchers in the Migrate Plus module to ingest data from an API and turn it into Drupal nodes (or any entity type).</p> <p>In this scenario you're dealing with a data set that doesn't change frequently (a few times per day, maybe), and/or it's okay for the data displayed on the site to lag a little behind what's in the external data service. This approach is somewhat analogous to using a static site generator like Gatsby, or Sculpin, that requires a build to occur in order for the site to get updated.</p> <p>In this case that build step is running your migration(s). The result is you'll end up with a Drupal entity for each record imported that would be no different than if a user had created a new node by filling out a form on your Drupal site. In addition, you get the complete extract, transform, load pipeline of the Migrate API to manipulate the ingested data as necessary.</p> <h3>Pros:</h3> <ul> <li>If you've worked with Migrate API before, this path likely provides the least friction</li> <li>Data is persisted into Drupal entities, which opens up the ability to use Views, Layout Builder, Field Formatters, and all the other powerful features of Drupal's Entity & Field APIs</li> <li>You can use Migrate API process plugins to transform data before it's used by Drupal</li> <li>Migrate Plus can handle common forms of authentication like OAuth 2 and HTTP Basic Auth</li> </ul> <h3>Cons:</h3> <ul> <li>Requires a <em>build</em> step to make new or updated data available</li> <li>Data duplication; you've now got an entity in Drupal that is a clone of some other existing data</li> <li>Probably not the best approach for really large data sets</li> </ul> <h3>Learn more about this approach:</h3> <ul> <li><a href="https://drupalize.me/topic/import-data-migrate-api">Import Data with Migrate API</a></li> <li>Learn about using <a href="https://www.drupal.org/docs/8/api/migrate-api/migrate-api-overview#identifier-highwater">highwater marks</a> to track changes and migrate only content that has been created or changed since the last time the migration ran</li> <li>Use data_fetcher, data_parser, and authentication plugins from the <a href="https://www.drupal.org/project/migrate_plus">Migrate Plus module</a> to <a href="https://www.lullabot.com/articles/pull-content-from-a-remote-drupal-8-site-using-migrate-and-json-api">pull content from a remote API</a>. Additional examples included in the migrate_plus module's code</li> </ul> <h2>Option 2: Create a Views Query Plugin</h2> <p>Write a Views Query Plugin that teaches Views how to access data from a remote API. Then use Views to create various displays of that data on your site.</p> <p>The biggest advantage of this approach is that you get the power of Views for building displays, without the need to persist the data into Drupal as Entities. This is approach is also well suited for scenarios where there's an existing module that already integrates with the third party API and provides a <a href="https://drupalize.me/topic/services">service</a> you can use to communicate with the API.</p> <h3>Pros:</h3> <ul> <li>You, or perhaps more importantly your editorial team, can use Views to build a UI for displaying and filtering the data</li> <li>Displays built with Views integrate well with Drupal's Layout Builder and Blocks systems</li> <li>Data is not persisted in Drupal and is queried fresh for each page view</li> <li>Can use Views caching to help improve performance and reduce the need to make API calls for every page load</li> </ul> <h3>Cons:</h3> <ul> <li>Requires a lot of custom code that is very specific to this one use-case</li> <li>Requires in-depth understanding of the underpinnings of the Views API</li> <li>Doesn't allow you to take advantage of other tools that interact with the Entity API</li> </ul> <h3>Learn more about this approach:</h3> <ul> <li><a href="https://www.lullabot.com/articles/building-views-query-plugins-dupal-8-part-1">This three part series</a> provides an in-depth example of writing a Views Query Plugin for accessing the FitBit API.</li> <li><a href="https://drupalize.me/tutorial/what-are-plugins">What are Plugins?</a>, and how to <a href="https://drupalize.me/tutorial/implement-plugin-any-type">Implement a Plugin of Any Type</a>.</li> <li>In the background you're likely to <a href="https://drupalize.me/blog/201512/speak-http-drupal-httpclient">use Guzzle for making HTTP requests</a> to obtain the data.</li> </ul> <h2>Option 3: Write a Service using Guzzle (or similar)</h2> <p>Write a Guzzle client, or use an existing PHP SDK to consume API data.</p> <p>Guzzle is included in Drupal 8 as a dependency, which makes it an attractive and accessible utility for module developers. But you could also use another similar low-level PHP HTTP client library, and add it to your project as a dependency via Composer.</p> <p>If you want the most control over how the data is consumed, and how it's displayed, you can use Guzzle to consume data from an API and then write one or more Controllers or Plugins for displaying that data in Drupal. Perhaps a page controller that provides a full page view of the data, and a block plugin that provides a summary view.</p> <p>This approach could be combined with the Views Query Plugin approach above, especially if there's not an existing module that provides a means to communicate with the API. In this scenario, you could create a service that is a wrapper around Guzzle for accessing the API, then use that service to retrieve the data to expose to views.</p> <p>If you need to do anything (<code>POST</code>, <code>PUT</code>, etc. ) other than <code>GET</code> from the API in question you'll almost certainly need to use this approach. The above two methods deal only with consuming data from an API.</p> <h3>Pros:</h3> <ul> <li>Able to leverage any existing PHP SDK available for the external API</li> <li>Some of the custom code you write could be reused outside of Drupal</li> <li>Greatest level of control over what is consumed, and how the consumed data is handled</li> <li>Large ecosystem of Guzzle middleware for handling common tasks like OAuth authentication</li> </ul> <h3>Cons:</h3> <ul> <li>Little to no integration with Drupal's existing tools like Views and others that are tailored to work with Entities</li> </ul> <h3>Learn more about this approach:</h3> <ul> <li><a href="https://drupalize.me/topic/services">Learn about using existing services</a> like Guzzle</li> <li><a href="https://drupalize.me/blog/201512/speak-http-drupal-httpclient">Speak HTTP with Drupal::httpClient</a></li> <li><a href="https://drupalize.me/topic/controllers">Create a controller</a> to provide one or more pages where someone can view the data</li> <li><a href="https://drupalize.me/topic/composer">Use Composer</a> to require any external dependencies</li> </ul> <h2>Option 4: JavaScript</h2> <p>Use client-side JavaScript to query the API and display the returned data.</p> <p>Another approach would be to write JavaScript that does the work of obtaining and displaying data from the API. Then integrate that JavaScript into Drupal as an asset library. A common example of something like this is a weather widget that displays the current weather for a user, or a Twitter widget that displays a list of most recent Tweets for a specific hash tag.</p> <p>You could also create a corresponding Drupal module with an admin settings form that would allow a user the ability to configure various aspects of the JavaScript application. Then expose those configuration values using Drupal's JavaScript settings API.</p> <p>While it's the least Drupal-y way of solving this problem, in many cases this might also be the easiest -- especially if the content you're consuming from the API is for display purposes only and there is no reason that Drupal needs to be aware of it.</p> <h3>Pros:</h3> <ul> <li>Data is consumed and displayed entirely by the client, making it easier to keep up-to-date in real time.</li> <li>Existing services often provide JavaScript widgets for displaying data from their system in real time that are virtually plug-and-play.</li> <li>Code can be used independent of Drupal.</li> </ul> <h3>Cons:</h3> <ul> <li>No server-side rendering, so any part of the page populated with data from the external API will not be visible to clients that don't support JavaScript. This also has potential SEO ramifications.</li> <li>You can't query the API directly if it requires an API key that you need to keep secret (e.g., because the key has access to POST/PUT/DELETE resources). In that case, you would need server-side code to act as a proxy between the API and the JavaScript frontend</li> <li>Drupal has no knowledge of the data that's being consumed.</li> <li>Drupal has little control over how the data is consumed, or how it's displayed.</li> </ul> <h3>Learn more about this approach:</h3> <ul> <li><a href="https://drupalize.me/topic/javascript-drupal">JavaScript in Drupal</a></li> <li><a href="https://drupalize.me/tutorial/use-server-side-settings-drupalsettings?p=2512">Use Server-Side Settings with drupalSettings</a></li> <li><a href="https://drupalize.me/series/drupal-8-and-reactjs">Get Started Using React and Drupal Together</a></li> <li><a href="https://drupalize.me/tutorial/create-settings-form-module?p=3277">Create a Settings Form in a Module</a></li> <li><a href="https://drupalize.me/guide/hands-on-theming/week-3/add-asset-library">Week 3: Add an Asset Library</a></li> </ul> <h2>Honorary mention: Feeds module</h2> <p>The <a href="https://www.drupal.org/project/feeds">Feeds module</a> is another popular method for consuming data from an API that serves as an alternative to the Migrate API approach outlined above. I've not personally used it with Drupal 8 yet, and would likely use the Migrate API based on the fact that I have much more experience with it. Feeds is probably worth at least taking a look at though.</p> <h2>Conclusion</h2> <p>There are a lot of different ways to approach the problem of consuming data from an API with Drupal. Picking the right one requires first understanding your specific use case, your data, and the level of control site administrators are going to need over how it's consumed and displayed. Remember to keep in mind that turning the data into Drupal entities can open up a whole bunch of possibilities for integration with other aspects of the Drupal ecosystem.</p> <p>What other ways can you think of that someone might go about solving the problem of consuming data from an API with Drupal?</p> <p>by <a href="https://drupalize.me/team/joe-shindelar">Joe Shindelar</a></p></div> <div class="field field--name-field-s-b-tags field--type-entity-reference field--label-hidden field--items"> <div class="field--item"><a href="https://skuhan.com/taxonomy/term/50" hreflang="en">Drupal 8</a></div> <div class="field--item"><a href="https://skuhan.com/taxonomy/term/53" hreflang="en">API</a></div> <div class="field--item"><a href="https://skuhan.com/taxonomy/term/54" hreflang="en">REST</a></div> </div> Wed, 04 Mar 2020 16:14:21 +0000 admin 10 at https://skuhan.com