 Bye, good morning. Thanks for coming. Some of you went early enough and I've got a bunch of people standing at the back, I'm sorry. I hope that you can see the slides. If anyone would rather have the slides on their own device, either to add some notes, or to make them easier to read, they're already online. I've just tweeted them from my Twitter account. If you look at, I'm also Lorna Jane on SpeakerDeck. So if you'd rather grab those slides, that's where they are, please help yourselves. My name's Lorna. I'm a Developer Advocate with IBM. Ac oedd hyn yn dgylcheddyn nhw'n dwy Lord krath o'r cyd-fyrdd o yndyn Lly mae 300 o arden nhw'n credu iawn. Rwy'n gweithio'r rhai ffost ar leion fy mod iddyn nhw... ...reulio'r cyd-fyrdd o'r Llyfrgell hwn i ddechrau a mwyafhau ar y dyn ni... ...bi'n cyd-fyrdd a rydyn nhw'n ddechrau i ddechrau. anything that makes things better for developers using IBM Cloud, that's what I do. My specialist topics are mostly open sourced databases, open sourced scripting languages and of course our cloud. Today I'm going to be speaking about web hooks and this might lead you to ask What is a web hook? A web hook is an HTTP host request I'm totally not going to do this, but I would feel entirely justified if I ended my talk now. I think the pub's probably open if anyone. I'm going to give you some more information, but hold on to this. If you know about post requests, then you're already qualified to work with webhooks. This is everything that you need to know. You've also already seen them out and about, even if you don't know this is what they're called. You have seen webhooks in the wild. They're what power your Slack integrations. If you have your GitHub or GitLab projects chatting into channel, do not let me give the chat ops talk now, we'll be here all day. The idea that we can integrate two systems, you do something in one place, you push the GitHub and that event causes something to happen in the conversation. I love chat ops, I love having notifications in the channel in context with the conversation that the developers are having. If you are looking to integrate a system that doesn't have a click here to add this integration on Slack, you just choose incoming webhook and you can accept any kind of notification into your Slack channel. On GitHub, we have it with the builds. This is a Travis CI build, somebody owned a pull request and the build failed. We know not to merge it, but that build was run on Travis in response to new commits on GitHub and that integration is also a webhook. Webhooks are all over the place. I use them quite a lot with Zapier which is an amazing platform. Do not Google this now, listen to my talk first, right? Because it's too interesting. But if you haven't played with Zapier, have a look. It's a brilliant way of integrating lots of different events. Something happens on Dropbox, take a copy of it, upload it here. When you tweet this, do that, add it to a Google Doc. Somebody mentions you, put it over here. So there's lots and lots of ways that we can use these webhooks to exchange data between systems, to allow systems to react to one another. Exchanging data between systems over HTTP and you're thinking, I think she's trying to sell us APIs with a different name. Let's compare those two ideas. How APIs work. The client asks the server, please may I have some data? And the server says, here's your data. Unless there isn't any, in which case it kind of says, nope. In a friendly way. Compare this with webhooks. The same conversation takes place, but the server starts the conversation. The server says, hey client, I have some data for you. And the client says, thanks, smiley. In HTTP we spell this like 200 okay. But you can think of it as thanks, smiley. So that's a webhook. The server starts the conversation. The server has to know where the clients are that would want this data. So there's a little bit of preamble. We have to set this up in advance. Like many excellent technical concepts, these things seem pretty much equivalent until you think about how they're going to work in practice, under load or over time. So let's have a look at this. And for this I flipped the diagram round. Time is going left to right with the client at the top and the server at the bottom. So with an API model we're going to be polling. The client asks the server for some data and may or may not get some. And you can see this quite chattery set of traffic going on here and only one piece of data getting delivered the second conversation along. Compare this with the webhooks. When there's some data we send the data. We don't need to talk about it the rest of the time. We're not doing an ongoing, anything? No. Anything? No. Webhooks are a bit more efficient. Isn't a coincidence that it's GitHub that I keep using as an example? Can you think about how many repositories you have on your GitHub account or maybe your organization's GitHub account? Now think about what the web traffic would look like if your CI servers were pinging every one of those repos every minute to look for changes. And you'd have to wait up to 60 seconds for the build to even get in the queue or the message to come in the channel and to us that's outrageous. Who wants to wait 60 seconds? What is this? An overnight batch CSV import. We're accustomed to this reactive programming that the on-demand webhooks give us. I wanted to touch a little bit on the data that we put into the webhook payloads and this brilliant idea that I would show you a real example. Webhook payloads are quite verbose. There are 111 more lines not shown here. I experimented with a smaller font but it was basically nonsense. Right? Verbose is kinder where it's at with webhooks. But you need to take into consideration when you're designing payloads of your own. We often work with this kind of loose spec JSON nested data and we try and include the majority of things that a user is going to need. Here you can see that we've got the previous commit ref, the new commit ref, some information about what happened here, a link to comparison, and then inside the commits array there'll be information with the commit ID, the committer ID, the timestamp, the email, the message for every commit. All the details of the repository, all the links to the contributors and branches and pull requests and everything of that repository. And the same for the pusher and the sender which are normally the same but not always. So there's a lot of stuff in here and I think it's a fairly typical webhook payload idea. When you're designing webhook payloads it's exactly, it feels very machine oriented but we exactly need to begin from a user story. Why would a user subscribe to this webhook event? What is it they're going to do next? What reaction are they having? Because if you send just the commit references in an array and let's say you're the Linux kernel project and there are tens of thousands of people hundreds of thousands of people subscribed to that event you send out the webhook from your wonderfully scalable system which I'm going to show you how to build and then every single one of those consumers makes an API call for each commit reference to get the name of the committer and the commit message and the other information. And this is what I like to call a DIY thundering herd problem, right? You made this. You sent out an incomplete event notification and caused all of those incoming API requests so be careful. Try to think about what people are likely to do next. Feel free to go minimal with your payload but then look at which API calls get hit next and start adding data in. It should be safe to add data into your payload that shouldn't break other people's code. We, over years of working with APIs I mean I've been building APIs long enough that we considered not only the cost of the user's data package and the speed of the network but also whether they would have a chip in their phone and powerful enough to decode this format. A lot of them didn't have good string manipulation chips. I'm going back a while. And for APIs, for mobile-facing stuff, even for client web-facing stuff we tend to try to keep things quite small. We're very conscious of packet size. Webhooks are, for the most part, server-to-server. They're two server-side applications communicating with each other, however many, all communicating with each other. You can assume that these are powerful machines on a decent network. So verbose is actually okay depending on your use case. Keep the data format simple. I saw a project a while ago which had this absolute... I mean it was glorious. It was beautiful, validated schemers and whatever. No third party could integrate with it because it was just too complicated and it wasn't well-supported enough across different programming languages. Seriously, JSON, BSAM, Apache Thrift, some sort of serialized format, just keep it super simple and very standard and then everyone can integrate with you. Please don't forget that we know how to secure HTTP traffic. We've been doing this web thing for a little while. So don't forget how to do that and don't invent anything new. We know how to secure this. Think about what your attack vectors are. I think this is a massive issue in our industry right now, particularly with the advent of the Internet of Things where security seems to be completely optional in many cases. So don't go there. Think about what can happen. If you are receiving webhooks, you've got an open endpoint, anybody could post to that. What could that do if a lot of requests came in? If you're publishing webhooks, what if a lot of people subscribed to that? How much can your system scale? How much potentially wasted resource do you want on that? Do you need to register everybody? Think about what those things can do because this is at scale. So it's not a person making a web request. It's a botnet taking all of your platforms out or at least running up your hosting bills. Always use SSL. This is non-negotiable. If you are doing webhooks and you are not using HTTPS, you are doing it wrong. There are very few situations where I tell you you are doing it wrong. Not using SSL on production webhooks, if you register for a GitHub webhook, you'll notice that they offer the shared secret option. If you set a secret, they use that to create a hash that you can then check on your side when the packet arrives. Everything you know about HTTP is good. Hopefully I'm not teaching anyone anything new. Okay. The bunnies are here to remind me to slow down and just take a break between sections. I don't blow your minds completely. I mean, I'm not promising I won't, but... I'm going to show you how to publish webhooks from your own PHP application. Before we start, let's talk about why you might want to do that. Please just don't go and publish webhooks for no reason. There are some very clear use cases. The first one has to be the GitHub continuous integration problem, right? Something pulls your API loads and mostly gets no data. Brilliant, move it to a webhook right now. Or at least offer it. Maybe not everyone knows how to handle those webhooks. Not all of your clients want that. But if you have an API, you have a lot of polling, then yes, I would definitely recommend it. If it's common for another application to react to changes in your application. Now I'm saying application like this is yours and this is going to be like some other third party somewhere else in the world. I am sure that a lot of you are moving to a more modern microservices, componentised architecture. One application and another application could be components within the same organisation. This is the most common use of webhooks I see. Internal integration. Sending notifications between parts of your own system. Those parts might be owned by other people. So the other team might own that component, you own this component and you just agree on how you integrate. And I see both webhooks but also message queues in use here. I also see webhooks a lot for notifications. So especially if you're using an external or third party library for push notifications to devices, that kind of thing, then that's a really good use case as well for webhooks or even just moving your own notification stuff out into a separate component where books can really help with that as well. So with that in mind, I have built you an example application. I tried to keep it quite simple and it is a retro guest book. So once upon a time, quite a long time ago, was probably if you were online before the year 2000, we all had websites and these websites had guest books on them. I'm conscious not all of you were online before the year 2000, so I'm just going to explain this to you and we'll skate over how old I am. And the idea of the guest book is exactly like you see in a nice holiday cottage or a hotel where you write your name or where you're from and how much you liked the place. You always write something nice. That is exactly what the internet was like in 1999 because we had these guest books on our website, it's like early dynamic webpages and there's lots of people laughing at me in the audience. And without registering any users, without any moderation on the comment content at all, people could write their name and write what they liked about your website and we displayed those things on our websites. That was a real thing. Lots of people just shaking their heads at me. I know, I know, but genuinely it was a real thing. Ask me about webbrings in the bar, it will blow your mind. Okay, so this example application is a guest book, so it allows us to write our name and leave a comment. It allows us to see those comments that have already been stored and because we're really cutting edge with our guest book, it also sends webbooks so you can register to get notifications of a new comment. If you just can't wait to check the database later, you can get a webbook notification of any new comment on your guest book. It looks like this. The reason it looks like a developer made it is because she did. It's got CSS, what do you want from me? I'm an API developer for a reason. Okay. The process when you fill in the form looks something like this. First we validate the data. Then we write the data to the database. Then we normally return a response to the user. But we're going to deal with webhooks. We're going to send the webhooks to the subscribers before we return the response to the user. There are a few ways we might do this. Some of them make more impact on how long the user has to wait than others. Option one for this Turquoise Circle is simply to look up the list of webhooks and send each webhook in turn. If there's 10,000 people registered, the user is going to wait a really long time to see their page. Okay. We could probably improve on that. Let's use a queue. A queue is ideal for asynchronous processing. Don't let me give a whole rabbit MQ talk now. I'm determined to get you to the front of the lunch queue. Okay. So, we have a queue. So what we do is we take the new comment that was made. We take that data. We look up a list of webhooks and we just stick all that data in the queue, fire and forget, and we return the response to the user. Why am I looking up the webhooks from the web page? We could do that later. I like to look up the list of subscribers here because the website component already has access to the database. It's already reading and writing to the database. If every single part of your system writes to the database or reads from the database, you've just created some... That's not microservices. That's some kind of almighty mess. I know a lot of organisations that have converted to microservices and coincidentally, their DBA resigned. Right. This is what happens. So we need to be really careful about our data hygiene. So I am going to do all the database work up top, put it all on the queue. I don't need to look anything else up after this point. So this is all independent. And then, yeah, we'll write a worker that takes the message off the queue and sends those hooks in a loop. Awesome. I just want to jump in with some PHP code. This is how you write to a queue. This is all on GitHub. You can see the full version where I just ripped out a load of... I think you all know how to write to databases. I took that bit out so it would fit on the slide. So first of all, we sanitise the incoming data from the form that you saw. We save the data to the database. We pick up a list of web hooks. We assemble the dates. We connect to Rabbit. And then we just create a new message and publish it to the queue. So this is all the code you need to write to Rabbit MQ. Feel confident you're all going to handle this. If you're using Rabbit MQs, go for it. It's really not that hard. I'm using Rabbit MQ here. We have it on IBM Cloud. That's not the only reason. I actually love Rabbit MQ. It's not really a hardship, but it's like, oh, I have to use Rabbit. How terrible. But if you're using Beanstalk D, I have known and loved. I've used Gearman with PHP as well, bit further back. All of that stuff is good. I have that in your stack already. So that thing really, I'm not hiding anything complicated from you here. So we could do this. Website puts messages on the queue and the worker just loops and sends. This is kind of tedious. And if something goes wrong partway through, we don't really know where we got up to. So at the risk of delivering a Rabbit MQ lecture, I think you're geeks and you might be interested. Here's how I really do it. So I do exactly the same. I put the comment data list of webhooks onto a message. The first worker picks that up and puts one new message into a different queue for each webhook we need to send. So one endpoint and the message data into each one. Those jobs that go in the second queue are now independent. This is what distributes systems are made of. They do not have any external dependencies. They do not need to make any network calls. They do not need to look up anything about the database. We just have a worker that we can now scale this horizontally as much as we need to because every job is independent. And this is why I do it this way. Webhooks, because you're holding the connection open, can be a real difficult performance issue. If you've worked with the Slack integrations, you don't respond within three seconds, they close the connection. This is because otherwise they run out of web server, holding connections open, waiting for you. So I'm going to talk a little bit more about receiving webhooks in a bit. But this is why I do it this way. To keep each piece independent and to allow you to scale up. Obviously I'm hoping all of you will write terribly successful applications and therefore you'll have to scale up loads because you'll be really successful. So, this is what we've got. The website puts things in the queue. The first worker puts more things one per end point into the notification queue. We have a bunch of workers actually sending those webhooks, which is sort of relatedly slower. I am going to attempt to demo that guest book and show you around how those moving parts actually move and how you would do this as a developer. For my end points I'm going to use a tool called Request Bin. This is a free tool, it's hosted by Runscope so if you find Request Bin doesn't do what you need you'll find Runscope does do what you need but Runscope support Request Bin it's also an open source project so if you're sat close enough to one of the screens you can see I'm actually running it on a VM it's just Python and I think it has a salary dependency and I use this loads if I'm not sure if I'm sending the right web format or anything just put this in as your end point and then inspect it you'll see an example. Let's see if I can run a video and talk at the same time it could be a challenge. First of all I would like to introduce you to the Rabbit MQ management console this is just a plugin for Rabbit it gives you a web interface at the top you'll see how many messages are in the queue all the queues and down here you'll see things being published to the queue delivered acknowledged we'll see those graphs changing as we go through so here we are with Rabbit MQ and the first thing we need to do is set up these end points with Request Bin so this is what Request Bin looks like click the big green I'd like a new Request Bin button and copy the URL here's the guest book so we will register our webhook end point with the guest book so that new comments will send notifications to that end point so here's an end point this isn't all that interesting unless you have more than one end point so I'm just going to do that again with Request Bin and register a second URL with the guest book so that we you'll see that we go from one message to two messages all the workers on this system are currently stopped if they weren't you wouldn't see anything on the Rabbit MQ admin console because we're like sending a web request it's quite quick I've definitely had this problem before when developing with any kind of queues and workers set up I would very strongly recommend that you regularly stop all your workers while you're developing and testing the system because that shows you what happens when the queues are building up or the workers are stalled for any reason so you should see what happens if just the queues are quite long and it's slow because on dev you never see that you don't see it until load testing but you can kind of preempt it I had one where I could reliably do the image processing on a new registration before we loaded the welcome page except one day I broke my workers and I realised that if it wasn't there it was the ugliest error ever and we put in a placeholder image which we never saw forgot about it we were soft live and then a famous footballer tweeted a link to it lots of people registered strangely enough and the image processing queue fell over quite quickly but it all just kept on working users had an experience that showed them some sort of placeholder image and our workers eventually caught up overnight and we ran out of inodes anyway wow that was a tangent right let's add a comment so remember this is a guest book so we're going to write something nice a bit like you're going to do in your joined-in feedback later so we save a comment and we check out the RabbitMQ admin console oh yeah look a single message has arrived we've added one comment, we're in the first queue now I'll start the workers so this is just the first worker and if you have a look at what happens here in the bottom graph I've had one message acknowledged and two messages published because we took the list of webhooks list, there's two of them and our comment data and turned it into two messages, these are independent if I now start the other worker to process the second queue that's why I've got them running under different system djobs here it is let's start that service and check back with RabbitMQ I've got two messages acknowledged and nothing in the queue we can also go and check out request bin because request bin is where we'll have received our webhooks it doesn't scale up all that well so I'm not sure if you can read this but it shows an incoming post request all the headers that were sent this can be really useful for diagnostics if you need to, you can see everything that came in the content type and here's the actual content which is the comment of my session coming in there and the same if I refresh the other request bin as well another bunny? I'm really glad I put these bunnies in also kittens are overrated my team saw this talk rehearsal and they said it needs more cats needs more cats and I was a bit like it's all about the function you need the thing to perform rather than what they look like so thanks bunnies you're helping me here so what you've seen there is how in a PHP application we would add messages to a queue and then process those messages there's a lot of moving parts there if you're accustomed to just browser sends request, web server sends response there's a lot moving here but I'm hoping that I'm showing you around alright let's look at the other side of this now I think this part is the most important part of this talk I'm not sure that every application has a use case for publishing webhooks just depending on what you're doing may not lend itself really well but I think receiving webhooks integrating with other people's applications whether it's in your actual application or in your bot or other internal tools I think as developers this is something we can all work with so if I lost you already then please tune back in I promise to be less scary just remember it's just a post request it's a weird setup because it's kind of like a backwards API if you're building an API then you are the server and people ask you for things and the post request comes this way whereas often when you're receiving webhooks you're kind of the client but the HTTP traffic comes in the same way PHP is designed to solve the web problem it is ideal perfect for these kinds of applications some things I'd really like to just kind of flag or recommend to you is to think hard about what needs to be done immediately when the webhook arrives and what can be done asynchronously a lot of the time this doesn't well it's a webhook it's not really real time anyway a lot of the time it doesn't need to be instant and if you are doing processing as the webhook arrives then you're holding your web connection open and this way lies madness holding open web connection incoming connections is where the hockey stick graph comes from because then everything's waiting and everything's waiting and everything gets slower all goes wrong so if you can and this depends on your application just accept the data store it, make sure you've got it and then send back the acknowledgement I already remember 200 okay smiley I already mentioned that Slack have rules about how quickly you need to respond when you do this right so you need to there isn't time for you to bootstrap an enormous full stack PHP framework and check that all the incoming data is valid and the accounts are active and then I used to work on a smart energy system and it recalculated the monthly running totals every time a reading came in well the readings came in every 5 minutes but we had a 48 hour lag on processing them because we were constantly recalculating the running totals right so really think about what you're doing here if you can just store it and process it later you've all worked with systems that do this you've integrated with PayPal then you get that that callback later so that you forward your user to PayPal they get forwarded back to you and then you get the notification to say yes the payment went through right so that's an out of band notification coming back to you you can do that with webhooks try not to validate data try not to hang around try to just accept it and log the incoming and the body of the data in full always just log the whole thing I have been increasingly moving this kind of functionality to a serverless end point one of the reasons that I like to store immediately is just to try to protect myself against the very bursty nature of internet traffic in general webhooks in particular seems to be the stuff happening and there are hooks everywhere or it's quite quiet with that smart energy project they used to instrument a whole block of lats and then turn it on all at once every device in the building would phone home the server would fall over so look out for that look out for being able to accept all of that data and process it even if it lags by a few seconds most applications it's fine let's talk about serverless I'll try not to talk too much about serverless the serverless technology and I'm just going to try and introduce it I know some of you haven't used it the idea behind I love the name serverless this is nonsense it's right up there with no ops no ops I might not need to do any ops I'm a developer it's best if I do not do ops but somebody did the best ops you've ever seen and calling it no ops seems a bit rubbish really serverless is the same they're really awesome excellent servers and what happens is you write just a function and I'm about to show you an example and you don't worry about the operating system the framework you need to worry about your language dependencies but essentially you just write a function and you deploy just the function it gets containerised for you and you just say when this happens run my function you can run a command line, make it run it's very common and this is what we'll see in this example to hook it up with like an incoming HTTP request when a request comes to this endpoint run my function it might be when there's a change on that database run my function every five minutes run my function when this value of this feed crosses this particular boundary run my function you just set up the function and what's beautiful about this is it's incredibly simple it's much easier than any actual whole framework PHP it's so small it's like writing really small command line apps but you just run them in the cloud it's pay as you go if you deploy this and nobody uses it it doesn't cost you anything there's no capacity planning there's no please sir may I have another server it just runs when it runs and you can keep an eye on it all of the platforms have free tiers so for prototyping or low traffic sites you're never going to pay for it anyway if the opposite is true and you get a lot of triggers causing your function to run then it just scales up horizontally when you turn on the building of sensors and all those devices phone home at once we'll just run some more of those functions and handle that load so again you need to think about horizontally scalable systems and how you can keep each of those pieces of work as independent as possible you've probably heard of Amazon Lambda obviously here comes the IBM cloud they pay me and my hosting bills there's nothing to not like about this IBM cloud has IBM cloud functions it's actually a hosted version of an open source project called Apache open whisk so you can develop with that locally or an open whisk on your own hosting anyway or we have a hosted version that I use and like Apache open whisk and I think some of the other serverless providers but I'm not sure supports PHP out the box so you don't need to dockerize it or whatever to work around it supports PHP out the box that implementation was done by Rob Allen who I can't embarrass because he's on the stage upstairs so he's not here, me to point at so we have PHP running on our platform so serverless PHP, yeah that's a thing and it lends itself to serverless because PHP is pretty simple it reads from top to bottom it's great, works well with incoming web requests it's a web language if you want to use another platform I'm not sure but I suspect in a room full of PHP developers that maybe some of you know some JavaScript maybe and Node.js is supported on all of the platforms and typically you'll find yourself reading the Node.js documentation on all the platforms regardless of which language you're using so that's serverless you write a function, you deploy the function, you say when it should run so here's my function it's written in PHP a little bit of white space crime to fit it on the slide not too much, sorry about the closing bracket really couldn't fit it on so you write a function and it should be called main and that function accepts one parameter, everyone's still with me okay that function accepts one parameter and it's called params, it can be called whatever you like and here is all the incoming data so if you've set variables when you deployed your function like environment variable style then you'll find those here if there are variables that you set when you called the function then you'll find those here if you can optionally set it up to pass incoming post variables or pass your JSON body and extract those variables as well I've not done that because it makes me a bit register globals frightened itchy online too I'm accessing that parameters variable to pull out the cloud and URL you'll see that being set in a demo in a minute and then I'm manually decoding the body so to get the body just as it was it comes in base 64 encoded so you can just decode it and then mines JSON you've just seen my webhook this code is going to receive the webhook that you just saw me publish so I'm just JSON decoding it and notice that this is a very optimistic version everything's fine we successfully decode everything there's no problems with the base 64 encoding it's valid JSON every time there are no error conditions this is like totally optimistic developer advocate doesn't run on production code so then we store it and we send the response so here I'm writing to CouchDB I've recently published a new PHP CouchDB library so if you're working with PHP and CouchDB please try it and then tell me what you'd like done differently because it's new but it turned my 10 lines of code into 3 so I am using it because I like it that's why I made it and what we do here is we connect to CouchDB we say which database we'd like to use it's called incoming it's where I store my incoming webhook data we set up some metadata to record when we received it and set the status to be new if you are just going to come back and loop through the data that's come in and look at which hasn't been processed yet then the status field's quite useful I'm using CouchDB so realistically I would be watching the changes feed but for an ordinary database you probably would want to come back and look at it like that and then just create the record again and return thanks with a smiley on line 11 because that's how we do that's how we do webhooks we send back that 200 ok and I'm sending back the smiley right so let me show you this as it happens because I want to give you a better concept of again how the developer experience is for that so that would be this one here it is so in this directory I have some files none of this should look alarming you all use composer yes we've got deploy.sh that's my hacky script to I just edited my php file here is what I'm going to run I'm going to type those commands and walk through them with you here I've got a git ignore file because I've got a vendor file hook.zip is what we're going to create index.php is where the code actually lives where the function lives and I'll be our entry point it needs to be at the root of the zip file that we're about to make log me.sh don't think he's under source control but if you look at my blog it's to work with openwisk you can say show me the last activations the last functions that ran and then you can do give me the logs from this activation so this is a script that does one of those and greps it, cuts it, puts it through xargs and just shows me the most reason it's a little hacky script so here's my code I'm going to zip it and then I'm going to deploy it and the reason that I'm zipping it is because I'm using that phpcouchdb library it's currently I'm about to fix this currently not available by default on openwisk but if you have any composer dependencies guzzles there by default that covers a lot of use cases if you have any dependencies then you can just use composer and then zip it like this so I'm using zip with dash r because I'm going to recurse down into the vendor directory you probably want to use dash q here to avoid the insane output that you're about to see and into hook.zip I'm putting index.php that's where my function is and I'm putting the vendor folder because I need those dependencies as well and I'm including the auto loader so there's the zip file created next we'll deploy this function so here's a bunch of gobbledygook let's work through it so bx the ibmcloud used to be called bluemix so its command is still called bluemix or bx for short then I'm working with openwisk so it's bluemix openwisk and I'm going to create an action I know that word doesn't say create but openwisk if it doesn't exist and you try to update it so you can write update in all your scripts and it will always work I love this, just seems super friendly so we're going to update an action this is the name of the action guestbook comment when there's a guestbook comment it's going to hit this end point I've called it guestbook comment it is a PHP action I need to specify the kind when I upload a zip file if you upload index.php without zipping it without dependencies it knows what to do but because I'm zipping it it can't tell we'll say please run it with PHP I would like dash dash web raw meaning please don't try and pass my incoming variables I would rather do that myself and know where my data came from maybe I'm being old fashioned about that maybe not and finally I need to specify where the code is that's the zip file that we just created so cool, we updated the action in fact we've created it but it says we've updated it now I've made it I need to set those parameters remember I need to connect to the database so I'm going to update the action give the name of the action and specify some parameters you just do that on the command line here and what I usually do is this step goes in the continuous integration so I just push to master and Travis says oh yeah, okay here's the script that I run here are the environment variables that are already set up I'll deploy these parameters with these actions or on OpenWis there are also packages so I'm setting a URL there this isn't the real URL so then there's like a little pause well I set it correctly in the other window so it's set to my real credentials and the whole thing works, brilliant now I'm going to get the URL of this action so I just say to the action what URL you want and it says this mess all of the serverless platforms offer API gateways where you can set up nicer roots and some authentication there you can also set it up so that there's like a disconnect between the URL and you can change which action it points to so that's really good for blue green deployment trying to keep it really simple today so that when I'm copying and pasting the raw web URL I often use webhooks just like this I'm not sure if I should say that I just grab the URL and work with it usually for the slack bot notification type stuff tend to just use this anyway, so yay let's add a new comment first of all I'm going to put that URL that I just copied in so that we register it as a webhook and then when I add a new comment the webhook will webhook here it is, yay more positive comments, there it is it's quite hard to show an incoming webhook but we did write to the database in our action that we created we wrote to cloud and so we can go and have a look at cloud and see our data there so there's our incoming data this is the incoming database holding incoming data I'm not confused at all and there's the data we can see it in detail here I'm learning so much learning so much and the metadata that we added as well with that new status so our action received the incoming webhook from the guest book and wrote it to the database and sent back the success response kind of give you an idea of how this would work do often also write to queues here at this stage put the incoming webhook data into a queue and then deal with it later that also works and you may want to store I'm using CouchDB this is cloud and it's the product name Apache CouchDB it's an open source document database if you've used MongoDB CouchDB is in the same umbrella area they're both document databases so you can store this nested JSON in your database if the fields are slightly different that's fine you can store nested JSON you can search nested JSON if you're not using a document database then you might want to extract some of the fields that you're going to want to search on but if you're using Postgres it has brilliant JSON support and the new and my SQLs have probably all the JSON support that you need for this kind of thing awesome one more thing I want to mention I have a slide on it is it this? No this? Yes one more thing I want to mention is Engrog in this example I was pushing my receiving code to the cloud making a serverless endpoint a lot of the time the development work that we do is on our local machines or on virtual machines and that's annoying for testing webhooks because you need a public URL to register so that the incoming webhook so the server can find your client but your client's on a virtual machine on your laptop inside the corporate network ok so the answer to that problem is called Engrog it's a brilliant tool you run it from command line saying which port you would like to tunnel from and it tunnels out to Engrog servers gives you a public URL and that URL if you use it allows incoming web stuff to come into your dev server this is brilliant for testing webhooks it is brilliant for testing websites on phones or other devices or asking other people in other locations to look at what's on your dev machine that's not the good part ok the good part is that Engrog has a dashboard it allows you to inspect in detail the headers and body and everything of request and response of all the traffic that's coming over here I use it a lot just to diagnose what's gone wrong between HTTP between two things that's also not the good part on that dashboard when you inspect the request and response there's a button and the button says replay so if your webhook is the webhook that github sends when someone adds a comment to a closed pull request on a particular open source project right you create that event once capture it in Engrog and if your response wasn't quite perfect change the code press the replay button press the replay button you don't need to do that it's when you're testing the webhook for when a new user has registered and it's convoluted but it's really frustrating so this is the good part of changing what you're doing so so powerful for lots of aspects of web development but especially these incoming webhooks key tool I had this in my demo and I took it out because I'm really using serverless now I had to leave the slide in to give you this tip okay by now perhaps you've realised that I am a huge fan of webhooks they've made my PHP applications dance and sing in a way that I'm not sure how I'd have implemented a lot of those features without this and I think in an increasingly componentised and event driven world all those big kind of rhetoric software architecture talks they tell you how that you should do things keep things separate they don't really tell you how webhooks are one way you can do that and it's a post request and suddenly all this stuff is within your grasp using them at the right time knowing when they're useful they're useful when one system or component needs to notify when an event happens another system where polling is less useful right so something happens we're going to broadcast it it's a pub sub it's event driven architectures I've tried hard to include what you need as a PHP developer and it's all vanilla PHP but you can do it in all of your frameworks and if you need examples come and see me of how that implements it I know there were a lot of moving parts here and I put in a queue as well you're a pretty qualified technical audience I think you can handle it and this is how I really do it I didn't want to bring you a dumbed down version yes there's a GitHub repo yes it's a simple example of any good shadow of how I would build a more complex system as an engineer I'm a developer advocate today that's not what I've always done crucially webhooks they're HTTP they're just the web you understand the web you already know how to do this you already know how to make a post request from PHP if you don't know how to make a post request from PHP you need to see me after class and this will enable so many things in your applications and with that I just have a few links to share and then I'm going to get you to the front of the lunch cube right so please leave feedback the organisation is using joined in it is a brilliant way to let speakers know what's working not working please tell me what's not working as well because I do this all the time so other audiences will have to sit through this terrible experience if you don't fix me if you want to try any of the stuff that I've mentioned check out IBM Cloud we have free tiers your PHP will run there on an ordinary hosting platform you can try out the serverless stuff as well we have my SQL on our platform let me know how that experience goes because my job to improve things and I would like to improve things for the PHP community specifically link to request bin, link to Engrock I rarely are not here this year which I would guess means you didn't buy enough books last year but I am the author of PHP Web Services which has a chapter on webhooks so you might find that useful as well here's the repo for the example app here is the PHP CouchDB library and with that I'll say thanks for your attention