Laravel Octane: Build your first plugin for RoadRunner
Tags: laravel, php, go, roadrunner
Published: 2021-08-23 08:19:23

---
title: Laravel Octane: Build your first plugin for RoadRunner
published: true
date: 2021-08-22 18:45:02 UTC
tags: laravel,php,golang,roadrunner
canonical_url: 
---

![](https://cdn-images-1.medium.com/max/1024/0*DX6bEZaCX1AJXts4)<figcaption>Photo by <a href="https://unsplash.com/@alan_rodriguez?utm_source=medium&amp;utm_medium=referral">Alan Rodriguez</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption>

Hopefully in choosing to read this article you will have read my first article about [compiling _RoadRunner_ from source](https://dev.to/slyfirefox/laravel-octane-compiling-roadrunner-from-source-5c4i) and now you want to continue into making customisations to the resulting server with your very first plugin. If you haven’t read it then you might be best doing so before continuing as it establishes steps you’ll need to take in this article.

For the sake of simplicity you should also have a _GitHub_ account as we’ll be using a template repository to make a copy and store in your own repository on GitHub. You could also just download the code but doing so would require additional steps that won’t be covered here.

If you have any difficulties or just want to play with the code you can find them all in the following repos:

[The Plugin](https://github.com/peterfox/roadrunner-plugin-demo), [The RoadRunner Binary](https://github.com/peterfox/roadrunner-custom-plugin-binary) and the [Laravel Octane app](https://github.com/peterfox/octane-custom-roadrunner-demo/tree/compiled-rpc-plugin).

### Using the Plugin template

Making a plugin for _RoadRunner_ is fairly simple but is a bit of a steep learning curving if you’re also still new to _Golang_. Writing the plugin is one thing but making a tested plugin that meets the standard of other _Go_ devs is difficult. To speed up this process I’ve produced a [template project on GitHub](https://github.com/peterfox/roadrunner-plugin-template) that you can copy to get yourself started.

The basics of a plugin is a simple structure in _Go_ that implements the interfaces required to be a service in [_Endure_](https://github.com/spiral/endure). _Endure_ is a service container for _Golang_, written by [_Spiral_](https://spiralscout.com/), the same company that develops _RoadRunne_r.

The template project also sets out tests and CI via [_GitHub Actions_](https://github.com/features/actions). This will be a great starting point for making your own plugin. Once you’ve copied the project we can get started.

### Customising the Plugin

The first step in customising the Plugin is to setup the go.mod file. When copying the template directory you will have created it with a new name which is unique on github. So for instance if your username is _foo_ and you name the repository _bar_ you will have a unique repository at _github.com/foo/bar_. Modules in go are equally named based on where the module can be found so the go get command knows where to download the source code from. The go.mod file has a module directive, this must reflect it’s location online otherwise it won’t be accepted by the go get command. You can see below what the file looks like and what needs to be changed.

```
module github.com/_<your account>_/_<repository name>_

go 1.16

require (
   github.com/spiral/endure v1.0.2
   github.com/spiral/errors v1.0.11
   github.com/spiral/goridge/v3 v3.1.4
   github.com/spiral/roadrunner/v2 v2.3.2
   github.com/stretchr/testify v1.7.0
)
```

The next step is to come up with a name for the plugin itself. This name will be used in the container as a unique identifier but also will show up in the logs when a plugin makes use of the logging service. This makes it easy to know if your plugin is working.

We make this change in the plugin.go file by changing the PluginName constant.

```
const PluginName = "name_of_your_plugin"
```

After doing so we have a basic enough plugin ready to be compiled into our custom _RoadRunner_ build.

### Adding the plugin as a dependency and compiling RoadRunner

By this point you hopefully have cloned/forked a copy of the [_RoadRunner_ binary](https://github.com/spiral/roadrunner-binary) project. If not, you need to do so.

Installing a plugin into _RoadRunner_ requires only a couple steps. First we have to download the dependency from within a terminal, where the current directory is the route for our RoadRunner binary project. Making sure the module name is the same as the account/repository our go.mod file which only need to tell go to add the module to the binary project to keep it as a dependency. This is really no different than the way _PHP_ uses composer to manage dependencies.

We can do this by simply running the following command:

```
go get github.com/<your account>/<repository name>
```

Take note the package url should be the same as the module name in go.mod or this will cause the package installation to fail. So for me that would be go get github.com/peterfox/roadrunner-plugin-demo.

Now in the binary project we must edit the internal/container/plugins.go file. Here we can import the plugin and add it to the list of other plugins like so:

{% gist https://gist.github.com/peterfox/67ad412270ee27644a047143d46d0506 %}

After this we can compile the binary as we have done so before and if there are no issues we can go about using it with Laravel by simply copying the compiled rr binary to our _Laravel_ project that has _Octane_ already installed.

We now only need to add our plugin to the .rr.yaml config to make sure that the plugin loads:

```
name_of_your_plugin:
    value: foobar
```

After this we can start up the _Octane_ with the php artisan octane:start command. At this point if we have done everything correctly we will have no errors in executing the command and can still load the default route on our _Laravel_ application as we could before.

### Communicating between PHP and Go code

Once you have a plugin with methods exposed via _RPC_, you now want to use them in _Laravel_ itself. This will equally require you to install an extra _PHP_ package to communicate with the _RPC_ server. This will be done with Composer:

```
composer require spiral/goridge
```

Then we can implement a very simple route to demonstrate calling the _RPC_ server.

{% gist https://gist.github.com/peterfox/cf430f2b1ab46ac63ee121fc86ffb904 %}

Once we test this route through we should get back a simple message as a response:

```
{"message":"Hello"}
```

This response means that the _PHP_ code has managed to serialise a _PHP_ array, deserialise in the RoadRunner application and then return the same structure to be serialized and deserialized from _Go_ to _PHP_ creating a bridge between the two programming languages.

### Conclusion

What we’ve done here may not seem much but it really is the start of something very powerful. Under the hood we’ve managed to expose the power of _Go_ to our _PHP_ application, something that would be far more complicated if we were writing a _PHP_ extension instead.

_RPC_ accessibility isn’t the only functionality that _RoadRunner_ plugins can offer and I hope to be exploring more of this in the future in further articles as well as little tips for developing with _Golang_ and diving a little into the components _RoadRunner_ uses.

I’m Peter Fox, a software developer in the UK who works with Laravel among other things. Thank you for reading my article, I’ve got several more on both medium and dev.to. If you want to know more about me, head over to [https://www.peterfox.me](https://www.peterfox.me/). Also feel free to follow me @[SlyFireFox](https://twitter.com/SlyFireFox) on twitter for more Laravel tips and tutorials in the future.