]> Dogcows Code - chaz/talk-bring-your-own-user-agent/commitdiff
fix up notes
authorCharles McGarvey <cmcgarvey@bluehost.com>
Wed, 20 Jun 2018 22:38:15 +0000 (16:38 -0600)
committerCharles McGarvey <cmcgarvey@bluehost.com>
Wed, 20 Jun 2018 23:06:16 +0000 (17:06 -0600)
css/slides.css
slides.html

index b4e4513ac5b9983e9fd37d73a3f996c255c4b722..6821094345dca842f5a20933849c53ef08a717ae 100644 (file)
@@ -7,3 +7,11 @@
     font-size: 38px;
 }
 
     font-size: 38px;
 }
 
+#slide-but p {
+    font-size: 200px;
+}
+
+.major-em {
+    font-size: 180%;
+}
+
index 37678e64d19c9d667f18c8027717a6fa5b13af78..97c2778616fa9e0eaee0a29409ffd9425f80bfc7 100644 (file)
@@ -11,21 +11,6 @@ Hi, I'm Chaz.
 
 I want to talk to you about HTTP user agents.
 
 
 I want to talk to you about HTTP user agents.
 
-Some time ago I had an idea and I wrote a module and put it up on CPAN.
-
-I don't think anyone knows it exists because I didn't promote it at all. I didn't even really talk to anyone about it.
-I'm not a very social person.
-
-Anyway, I think it *might* actually be a good idea so I'm going to share it now.
-
----
-class: center, middle
-
-## The problem.
-
-???
-So here's the problem that I wanted to solve.
-
 ---
 class: img-map, center, middle
 
 ---
 class: img-map, center, middle
 
@@ -54,22 +39,30 @@ class: img-map, center, middle
 ???
 the Ontario Power Generation website.
 
 ???
 the Ontario Power Generation website.
 
+Random, but why not?
+
 ---
 class: img-map, center, middle
 
 ![WebService modules on CPAN](img/webservice-on-cpan-circled.png)
 
 ???
 ---
 class: img-map, center, middle
 
 ![WebService modules on CPAN](img/webservice-on-cpan-circled.png)
 
 ???
-Most of these modules congregate here.
+Most of these modules congregate here (or at least they should).
 
 ---
 class: center, middle
 
 ## `WebService`
 
 
 ---
 class: center, middle
 
 ## `WebService`
 
+???
+In the `WebService` namespace.
+
 --
 ## `Net`
 
 --
 ## `Net`
 
+???
+There are other common namespaces for this sort of thing...
+
 --
 ## `WWW`
 
 --
 ## `WWW`
 
@@ -98,9 +91,10 @@ modules often take care of some of the tricky or boring details, like:
 Details that are important but you don't want to read through the API documentation to figure it out.
 
 ---
 Details that are important but you don't want to read through the API documentation to figure it out.
 
 ---
+name: but
 class: center, middle
 
 class: center, middle
 
-## But
+But
 
 ???
 And here's the problem...
 
 ???
 And here's the problem...
@@ -108,7 +102,7 @@ And here's the problem...
 ---
 class: center, middle
 
 ---
 class: center, middle
 
-## These modules are **tightly-coupled** to specific user agents.
+## These modules are .major-em[**tightly-coupled**] to specific .major-em[user agents].
 
 ### ;-(
 
 
 ### ;-(
 
@@ -127,7 +121,7 @@ Most of them use `LWP` or `HTTP::Tiny`.
 ---
 class: center, middle
 
 ---
 class: center, middle
 
-## This has problems.
+## This... could be better.
 
 ???
 Now I'm going to try to convince you that this is a problem.
 
 ???
 Now I'm going to try to convince you that this is a problem.
@@ -135,16 +129,17 @@ Now I'm going to try to convince you that this is a problem.
 ---
 class: center, middle
 
 ---
 class: center, middle
 
-## Problem #1
+## Problem:
 
 ### How to configure the user agent...
 
 ???
 User agents typically have defaults and so may not need to be configured, but what if the user needs the user agent to
 
 ### How to configure the user agent...
 
 ???
 User agents typically have defaults and so may not need to be configured, but what if the user needs the user agent to
-support proxying, caching, TLS, or shorter timeouts?
-
-If the webservice package is *composing* (or wrapping) a user agent, then the webservice package needs to expose all of
-the ways that the user agent can be configured.
+support
+- proxying,
+- caching,
+- TLS verification,
+- timeouts...
 
 ---
 class: ex-code
 
 ---
 class: ex-code
@@ -163,9 +158,11 @@ my $resp = $ws->account_info;
 
 ???
 So, one way this has been solved is for the webservice to expose all the attributes and knobs needed to configure the
 
 ???
 So, one way this has been solved is for the webservice to expose all the attributes and knobs needed to configure the
-internal agent.
+internal agent and just pass them through.
 
 
-But that's terrible.
+But this kinda bad because now every webservice module has to do this,
+
+...and every module will probably do it slightly differently.
 
 ---
 class: ex-code
 
 ---
 class: ex-code
@@ -186,9 +183,12 @@ my $resp = $ws->account_info;
 ```
 
 ???
 ```
 
 ???
-So someone remembered that dependency injection was a thing, so now we have modules that let you pass in your own user
+Then someone remembered that dependency injection was a thing, so now we have modules that let you pass in your own user
 agent.
 
 agent.
 
+This is great because it lets the user set up the user agent however they want, and webservice modules writers don't
+need to do any of that boring work.
+
 Big improvement!
 
 ---
 Big improvement!
 
 ---
@@ -210,8 +210,10 @@ my $resp = $ws->account_info;       # ;-(
 ```
 
 ???
 ```
 
 ???
-But I can't just plug in any user agent I want! If the webservice module was written for `HTTP::Tiny` or any other user
-agent, it's expecting that I'm going to pass it the kind of user agent it wants.
+But I can't just plug in any user agent I want!
+
+If the webservice module was written for `HTTP::Tiny` or any other user agent, it's expecting that I'm going to pass it
+the kind of user agent it wants.
 
 This makes me sad.
 
 
 This makes me sad.
 
@@ -223,7 +225,7 @@ class: center, middle
 ???
 I think the user writing a program should decide which user agent to use.
 
 ???
 I think the user writing a program should decide which user agent to use.
 
-After all, they're the ones who know what the requirements of their app are.
+After all, they're the ones who know the requirements of their program.
 
 If I'm writing a program that needs to use the least amount of resources, and I want to use a webservice that is coupled
 with a *not* tiny user agent, then I'm out of luck.
 
 If I'm writing a program that needs to use the least amount of resources, and I want to use a webservice that is coupled
 with a *not* tiny user agent, then I'm out of luck.
@@ -231,31 +233,41 @@ with a *not* tiny user agent, then I'm out of luck.
 Or if somebody wrote a great webservice module using a blocking interface like `HTTP::Tiny` or `LWP` that I want to use
 but my program is event-driven and so can't block, then I'm out of luck again.
 
 Or if somebody wrote a great webservice module using a blocking interface like `HTTP::Tiny` or `LWP` that I want to use
 but my program is event-driven and so can't block, then I'm out of luck again.
 
-So then what, are we just going to write separate webservice modules for each user agent?
-
 ---
 ---
-
 ## [`Mail::SendGrid`](https://metacpan.org/pod/Mail::SendGrid) -> [`HTTP::Tiny`](https://metacpan.org/pod/HTTP::Tiny)
 ## [`Mojo::Sendgrid`](https://metacpan.org/pod/Mojo::Sendgrid) -> [`Mojo::UserAgent`](https://metacpan.org/pod/Mojo::UserAgent)
 ## [`WebService::SendGrid`](https://metacpan.org/pod/WebService::SendGrid) -> [`Net::Curl::Simple`](https://metacpan.org/pod/Net::Curl::Simple)
 ## [`Mail::SendGrid`](https://metacpan.org/pod/Mail::SendGrid) -> [`HTTP::Tiny`](https://metacpan.org/pod/HTTP::Tiny)
 ## [`Mojo::Sendgrid`](https://metacpan.org/pod/Mojo::Sendgrid) -> [`Mojo::UserAgent`](https://metacpan.org/pod/Mojo::UserAgent)
 ## [`WebService::SendGrid`](https://metacpan.org/pod/WebService::SendGrid) -> [`Net::Curl::Simple`](https://metacpan.org/pod/Net::Curl::Simple)
+## ...
 
 ???
 
 ???
-Yeah, that's exactly what's up.
-
-What we need is user agent adapter (as in the adapter pattern).
+The solution we've come up with so far is to just implement a new webservice module for each type of user agent that
+anyone cares to use.
 
 
-Something that has an inteface that module writers can code against and then translates the request and response
-appropriately for whatever real user agent is provided.
+Wasted effort. :-(
 
 ---
 
 ---
+class: center, middle
+
+## There's a better way.
+
+???
+What we need is user agent **adapter**.
+
+As in, the **adapter pattern**, which is the same pattern we generally use for the myriad "Any" modules.
+
+We need something that has an common inteface that module writers can code against, and then adapters to transform the
+request and response appropriately for whatever real user agent is wanted.
+
+So yeah, this isn't an original idea of mine.
 
 
+---
 ## [`HTTP::Any`](https://metacpan.org/pod/HTTP::Any)
 
 ???
 I searched CPAN and found just such a thing!
 
 --
 ## [`HTTP::Any`](https://metacpan.org/pod/HTTP::Any)
 
 ???
 I searched CPAN and found just such a thing!
 
 --
-#### But it has fatal flaws...
+#### But it has some .major-em[fatal flaws]...
 
 ???
 in my opinion. (No offense to this module's author.)
 
 ???
 in my opinion. (No offense to this module's author.)
@@ -264,8 +276,9 @@ in my opinion. (No offense to this module's author.)
 ### 1. It provides its own *new* interface.
 
 ???
 ### 1. It provides its own *new* interface.
 
 ???
-- And nobody wants to learn yet another user agent interface.
-- And it's a callback interface in order to support non-blocking user agents,
+- Okay, this one's not fatal.
+- Nobody wants to learn yet another user agent interface.
+- And it's a callback interface in order to support non-blocking user agents.
 
 But having to set callback functions if you're not actually using a non-blocking user agent is kinda clunky.
 
 
 But having to set callback functions if you're not actually using a non-blocking user agent is kinda clunky.
 
@@ -273,7 +286,9 @@ But having to set callback functions if you're not actually using a non-blocking
 ### 2. It doesn't support many user agents.
 
 ???
 ### 2. It doesn't support many user agents.
 
 ???
-only `LWP`, `AnyEvent`, and `Curl`.
+- `LWP`
+- `Curl`
+- `AnyEvent`
 
 --
 ### 3. It doesn't actually provide a common interface.
 
 --
 ### 3. It doesn't actually provide a common interface.
@@ -281,10 +296,15 @@ only `LWP`, `AnyEvent`, and `Curl`.
 ???
 so it's not really usable as an adapter.
 
 ???
 so it's not really usable as an adapter.
 
+There were a couple other potential solutions on CPAN I found, but none of them overcome all of these problems.
+
+Some of the modules that look like they might work at face value, actually are aiming to solve the opposite problem;
+that is, when the user doesn't care what user agent is used, just find one and use it.
+
 ---
 class: center, middle
 
 ---
 class: center, middle
 
-## I wrote a module to fix these problems.
+## I wrote a module.
 
 ---
 class: center, middle
 
 ---
 class: center, middle
@@ -292,9 +312,9 @@ class: center, middle
 ## [`HTTP::AnyUA`](https://metacpan.org/pod/HTTP::AnyUA)
 
 ???
 ## [`HTTP::AnyUA`](https://metacpan.org/pod/HTTP::AnyUA)
 
 ???
-This one is different because it has a "UA" at the end.
+This one is different because it has a "UA" at the end (for "user agent").
 
 
-It's also a true HTTP user agent adapter providing a common interface.
+It also solves the problems I had with the other module.
 
 ---
 ## [`HTTP::AnyUA`](https://metacpan.org/pod/HTTP::AnyUA)
 
 ---
 ## [`HTTP::AnyUA`](https://metacpan.org/pod/HTTP::AnyUA)
@@ -303,7 +323,9 @@ It's also a true HTTP user agent adapter providing a common interface.
 
 ???
 - So not much new to learn.
 
 ???
 - So not much new to learn.
-- And you don't have to use callbacks if your user agent is non-blocking.
+- And it doesn't make you use a callback interface if your user agent is non-blocking.
+
+If your webservice module already uses `HTTP::Tiny`, this is *almost* a drop-in replacement.
 
 --
 ### 2. Supports at least six user agents.
 
 --
 ### 2. Supports at least six user agents.
@@ -322,17 +344,19 @@ It's also a true HTTP user agent adapter providing a common interface.
 ???
 Plus any user agent that inherits from any of these in a well-behaved manner should also work.
 
 ???
 Plus any user agent that inherits from any of these in a well-behaved manner should also work.
 
+It's pretty easy to support for other user agents.
+
 --
 ### 3. Provides a *common* interface.
 
 ???
 --
 ### 3. Provides a *common* interface.
 
 ???
-which, like I said, is the `HTTP::Tiny` interface.
+The interface, like I said, is the `HTTP::Tiny` interface.
 
 ---
 class: ex-code
 
 ```perl
 
 ---
 class: ex-code
 
 ```perl
-has ua => (
+has ua => (                 # <-- user agent
     is       => 'ro',
     required => 1,
 );
     is       => 'ro',
     required => 1,
 );
@@ -465,22 +489,31 @@ class: center, middle
 ???
 I think this is pretty cool already, but I'll show you one more thing before I get kicked off that's even cooler...
 
 ???
 I think this is pretty cool already, but I'll show you one more thing before I get kicked off that's even cooler...
 
+When you have a request response pipeline that is shaped like this, it begs to have...
+
 ---
 class: center, middle
 
 ![HTTP::AnyUA with middleware diagram](img/http-anyua-middleware-diagram.svg)
 
 ???
 ---
 class: center, middle
 
 ![HTTP::AnyUA with middleware diagram](img/http-anyua-middleware-diagram.svg)
 
 ???
-You can write components that work for any user agent and plug them in. I've written only a couple such components, one
-to time the request takes and another to ensure a proper 'content-length' header is set.
+Just like in PSGI where you can have middleware components between whatever server handler and the app, you can do the
+same sort of thing for the client.
+
+You can write components that work for any user agent and plug them in.
+
+I've written only a couple components,
+- one to time or profile each request and
+- another to ensure a proper 'content-length' header is set.
 
 Middleware components can do anything, even short-circuit and not actually call the user agent.
 
 
 Middleware components can do anything, even short-circuit and not actually call the user agent.
 
-I started writing a caching component. This middleware is taking me awhile to write because I want it to be
-`RFC-7234`-compliant (and my interest jumps around), but it would be cool because not every user agent has a decent
+I started writing a caching component, but it's taking me awhile to write because I do want it to be
+`RFC-7234`-compliant (and my interest jumps around), but it will be cool because not every user agent has a decent
 cache.
 
 cache.
 
-With HTTP::AnyUA, I just need to implement the cache once and it works for all of them.
+With HTTP::AnyUA, I just need to implement the cache once and it works for all user agents that can be plugged into this
+pipeline.
 
 ---
 class: center, middle
 
 ---
 class: center, middle
@@ -488,8 +521,10 @@ class: center, middle
 ## Conclusion
 
 ???
 ## Conclusion
 
 ???
-If you're writing a module that needs to *use* an HTTP user agent but otherwise has no reason to prefer one over
-another, consider using `HTTP::AnyUA` or something like it.
+If you're writing a module that needs to *use* an HTTP user agent but otherwise has no reason to care what the user
+agent actually is, consider using `HTTP::AnyUA` or something like it (instead of coupling directly with a user agent).
+
+It will make your webservice module usable by more people.
 
 ---
 class: center, middle
 
 ---
 class: center, middle
This page took 0.028838 seconds and 4 git commands to generate.