Introducing a PHP library for the Hashnode API

When I heard about the Hashnode Christmas Hackathon, I immediately began brainstorming ideas to develop something that members of the community might find useful, but would also be a great learning experience for me. After all, learning is at the heart of Hashnode.

In any case, after numerous scrapped ideas and half-baked prototypes (that I’ll talk about in an upcoming article!) I decided that I would go in the direction of building a library – something that I have never done before, and using PHP, a programming language that I’m quite familiar with. By working on this project, it was my ambition to learn more about GraphQL, the technology that Hashnode’s API (Application Programming Interface) utilises, and something I previously knew nothing about!

Enter, an unofficial PHP library for interacting with the Hashnode API in PHP.

How can I use it?

Visit the GitHub Repository

Update: The library is installable via Composer.

composer require oliverearl/php-hashnode

In your own code, you can instantiate a client instance and a root query object like this:

$client = new Hashnode();

$query = new RootQuery();

You can also specify a custom endpoint, or your Hashnode API token by adding it as a parameter to the Hashnode constructor:

$client = new Hashnode('https://some-other-endpoint.hashnode.com', [
  'Authorization' => 'token-goes-here'
]);

For more information on how to use the library, including how to retrieve data from the API, I strongly encourage you to view the repository’s README! I hope to write more in-depth documentation soon as it’s on the development roadmap!

You do need PHP 7.4 (or above) for the time being. Sorry about that!

Is it complete?

Almost. I really wanted to have it completely done before New Year’s Day, but truth be told I have had other responsibilities and familial commitments throughout the winter break that limited my free time. I hope you can understand!

However, all functionality to retrieve information from Hashnode is complete!

The development process

Originally, I wanted to develop something that was similar to how Laravel works with its models, where you could say $post->get(); and retrieve something, but this is currently out-of-my-depth and is something I’m hoping to be able to do in the future with more learning. I used a GraphQL client library for PHP and attempted to use the repository pattern to build ways of wrapping queries in method calls, but I realised that it would be impossible to build flexible GraphQL queries in the way that I wanted.

My gripes with GraphQL

One of the things I found most frustrating with GraphQL as part of its inherent design.

You only get what you request.

This wasn’t like what I was used to when working with RESTful APIs where I could retrieve everything that I wanted by accessing the appropriate endpoint. Instead, there was one endpoint, and I had to build the appropriate query. I was immensely frustrated at my lack of knowledge and knew I had to find another way.

I remember getting so angry that I accused GraphQL of being ‘rehashed SOAP with JSON’ and retiring to bed. After a good night’s sleep, I realised that I was just ignorant of what I didn’t fully understand – and that’s okay. So I got back to work on the project, but knew I needed a new approach.

Enter the GraphQL OQM library.

After a bit of research, I found the author of the GraphQL library had also developed another library for working with objects mapped to queries, or OQM (Object-Query Mapping). With this library, I was able to generate and map queries and arguments into classes of their own. Whilst this sounds straightforward, I spent a lot of time rewriting the code into PHP 7.4 typed code and organising things into a structure that was easy to work with for someone who is relatively new to object-oriented PHP.

Without discipline, agile methodologies can collapse

One of the most important things I learned while studying software engineering is that successful software projects require a careful balance of discipline and agility.

Without agility, you’re basically working to a methodology like Waterfall where the process is too rigid.

Without discipline, you’re just hacking code together and abandoning the process and any kind of planning. Mistakes and problems can then creep in.

I try to use Test-Driven Development (TDD) in all of my projects, where I will write tests and then get them to pass by implementing the required behaviour. By the time I went back to the drawing board and started again from scratch using the OQM library, I was writing and modifying code without testing it properly, so I had to go back and write tests afterwards. This is less than ideal, and I’m hoping to have more thorough test coverage and integration tests going forward. But since I was working solo, it wasn’t a fatal mistake to make.

What remains and how you can get involved

This project is something that I want to keep working on in the future! There is still some work to be done (a full list is available on the repository readme) and there are undoubtedly areas where the code can be improved, or maybe there are bugs.

If you want to get involved, some key areas that need implementing are:

  • Documentation! I haven’t had the time to write a great deal of documentation, but if you’re a keen writer, this would be a great place to help out.
  • Integration tests – while a (semi-complete) suite of unit tests exists, more elaborate tests that test against full queries need to be orchestrated.
  • Implementation of code that performs server-side mutation – in other words, we can currently retrieve data, but updating, deleting, and creating data is yet to be done!
  • Build some single-file examples of the API doing cool things and pull requesting them to join the examples directory!

What I learned

Despite me starting a new PHP software engineering job this January and having confidently worked with PHP and Laravel on a number of projects throughout my career I felt relatively out of my depth this time. I realised that it was okay to not know absolutely everything and that I shouldn’t get too frustrated when I can’t wrap my head around a concept the first time around. Something that I should probably know better by now.

I learned that although I was frustrated with GraphQL for not being able to just retrieve everything that I wanted, I did acknowledge that it’s incredibly efficient as it does just that. Returns what you want.

Conclusions

I hope you enjoyed my little write-up and I hope you enjoy playing with the Hashnode PHP library as much as I did developing it! Of course, it’s not perfect and I’m not the best programmer going, so if you can help me improve it, I would love your help and hope to see you on GitHub!

Thanks again to everyone at Hashnode and I hope that you have had a wonderful holiday season and a merry Christmas to those celebrating. Have a safe and fun New Year’s Eve and I’ll see you in 2021!

Documentation in Laravel 8 with Enlighten

The importance of software documentation, even in an agile world, is undisputed. Keeping documentation, especially for APIs, up-to-date however can be an additional burden on a development team, and thus automatically generated documentation can help supplement this by producing reference materials. This is where Enlighten comes in.

In this guide, we’ll get Laravel Enlighten up and running, which utilises your existing PHPUnit tests (because you should be writing tests) to produce and publish beautiful, customisable documentation, without needing to run any additional commands.

System Requirements

Enlighten does require both PHP 7.4 and Laravel 8. I don’t know whether it works with Lumen. 

If you’re running anything earlier, such as Laravel 6 LTS, I would instead recommend Scribe. For other frameworks or vanilla PHP applications, try phpDocumentor.

You will also need a secondary database. It does not need to be a different kind of database, but it does need to be persistent.

You also need an up-to-date version of Git. This is unlikely to be a problem on macOS, Linux or Windows Subsystem for Linux, but it gave me some teething problems directly running on Windows 10 under Laragon.

Please also note that these are as simple installation instructions as possible. For troubleshooting and optional installation steps, please check the project’s repository.

Installation

Composer installation

Do not use sudo for any of these commands. That will open a whole Pandora’s box you don’t want to deal with.

Using Composer, require Enlighten into your Laravel project using the following command. If you somehow don’t have it, grab it here.

composer require styde/enlighten --dev

Registering the service provider

Next, add the following to your config/app.php file to register Enlighten’s service provider. If you’re not sure where this needs to go, put it underneath the package service providers comment, like thus:

[
  'providers' => [
    // ...
    /*
     * Package Service Providers...
     */
     Styde\Enlighten\Providers\EnlightenServiceProvider::class,
    // ...
  ]
];

Important: Be sure to end the line in a comma, not a semicolon.

Publish assets to the public directory

Run the following command to publish Enlighten’s assets to your public directory. Without this, any documents you generate will lack any CSS formatting or JavaScript.

php artisan vendor:publish --tag=enlighten-build

Integrating Enlighten into your tests

In order for Enlighten to activate during testing and to have access to test data, it will need to be imported and initialised during the setup phase of your tests. You can do this in your TestCase.php abstract class, or in individual test files.

For example:

<?php

namespace Tests;

use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
use Styde\Enlighten\Tests\EnlightenSetup; // import this trait

abstract class TestCase extends BaseTestCase
{
  use CreatesApplication;
  use EnlightenSetup; // and use said trait here

  protected function setUp(): void
  {
    parent::setUp();

    $this->setUpEnlighten(); // the final piece of the puzzle
  }
}

Important: I believe you need to still call parent::setUp() in your setUp() methods within your tests.

Setting up the secondary database

As aforementioned, Enlighten needs another database to record information. The easiest way to do this is to create another database with the same name of your existing one, except with an _enlighten suffix.

For example, if you have used a MySQL database named laravel, you can create another one called laravel_enlighten which will be used automatically. This assumes you’re using the same database connection, credentials, and driver.

Once you’ve made it, run your migrations to get it set up:

php artisan migrate

Optional: Custom database setup

If you need to use something else, add a new entry to your config/database.php file with the name enlighten. This can support a different driver, credentials, database name, etc. You can add this information as custom entries in your .env file – possibly with an _ENLIGHTEN suffix for clarity.

For example:

'enlighten' => [
  'driver' => 'mysql',
  'host' => env('DB_HOST_ENLIGHTEN', '127.0.0.1')
  'port' => env('DB_PORT_ENLIGHTEN', '3306')
  'database' => env('DB_DATABASE_ENLIGHTEN', 'laravel_enlighten')
  'username' => env('DB_USERNAME_ENLIGHTEN', 'root')
  'password' => env('DB_PASSWORD_ENLIGHTEN', '')
// …
],

I think that you could use an SQLite database in theory, but I haven’t tested this and generally stick to the defaults.

Don’t forget to run your migrations if you choose this route.

Running Enlighten

Once you’ve set everything up, Enlighten will run when you run your test suite:

php artisan test

You can then find your new documentation at the yourwebsite.test/enlighten/ URL.

What’s next?

This guide was designed to get Enlighten up and running as easily as possible. More customisation and configuration options are available to make your documentation as detailed and organised as possible. You can read more on the project’s repository.

I hope that you’ve found this guide useful and I encourage you to check it out with your Laravel API projects! It goes without saying, but Enlighten wasn’t written by me – it’s an open-source project headed by Duilio Palacios and Jeff Ochoa.

Thank you so much for reading.