My Personal Quality Principles

I’m joining a new team at work, and as I do so I’ve taken some time to reflect on how I want to contribute to the team. Obviously some of that will be specific to the context of the team I am on, but I’ve also decided to publish some of my personal quality principles. These are the principles that currently guide the approach I take to quality and testing.

  • Quality is a team sport. I don’t do all the testing. I might not even do most of the testing. My main goal is for the team to produce high quality software that makes customer’s lives better, and I believe that can only be accomplished if everyone on the team owns quality. This means that I will work with the team to make sure we are not cutting corners on the testing, and that we are all getting infected with the quality virus (don’t worry, it’s better for you than covid).
  • Testing should be an accelerant not a bottleneck.  This means that it should be rare or non-existent to be “waiting for testing to finish.” If testing is or becomes a bottleneck, I will work with the team to identify and mitigate the reasons it has become one. Time spent testing should be an investment in the future, not a form of evil that stops us from doing what we want.
  • Using testing as a safety net is an anti-pattern. Testing is not something that primarily happens after the code is written. Testing happens during design, during development and while code is in production. In other words, at every point in the software development lifecycle. Limiting testing to a just one step in the SDLC is inefficient and counterproductive. If the team is primarily relying on after-the-fact testing to stop them from getting hit by surprise bugs, I will do my best to help the team recognize and remove the need for a testing safety net.
  • People first. We write software so that we can make people’s lives better. If we are not doing that, we are making bad quality software. I want to know how our customer’s lives are being improved, which means knowing our customers needs and usage patterns. I love using telemetry and logging to understand the quality of our code, but we also need to remember that customers are fully rounded complex humans and not just data points. Alos, software is created by people, and so part of a people first approach to quality is to think about things that might impact the team. Software that makes the life of the team worse, is also bad quality software regardless of the impact it is having on customers.
  • Testing scalability is important.  Software development is all about scaling things. Testing needs to be done in a scalable way too. This means that I will work with the team invest in scalable test automation. Regression testing is too important to ignore, but particularly as a feature set grows, quickly becomes too slow to do manually.

Those are some of the principles that drive my approach to testing. The way that plays out in my day-to-day activities is, of course, going to vary widely depending on the needs of the team, but these are the goals and principles that lie behind the kinds of things I try to work on and advocate for.

Writing Words and Software

I have a problem when it comes to books. I want to read more than I have time to read. I’ve been able to mostly limit myself to just making insanely big Amazon wishlists, but sometimes I still can’t stop myself from buying books that “I’ll be sure to read soon.”

This has lead to a stack of unread books, and this year I’m trying to make that stack a bit smaller. One of the books I recently started reading from my backlog is T.E. Lawrence’s Seven Pillars of Wisdom. I’m not too far into the book yet, but in the introduction he talks about his process of writing it. He basically wrote the entire book from scratch 3 times along with numerous editing stages and re-works based on reviewer feedback.

The title itself came from another book that he wrote but decided not to publish because the considered it immature. Can you imagine having that kind of rigour going into what you write, before you publish it? We are used to having a fleeting thought and throwing it out there on Twitter for the world to see. I was struck by a thought and started pounding out this blog post. I’m certainly not going to spend 6 or 7 years working through different drafts of this and soliciting feedback before I put it out there for the world to see!

We live in different times and a tweet or blog post is a very different medium than a memoir style book, but have we gone too far? How much rigour and editing should we put into our public writing? What is the trade-off between getting something “out there” and making something good?

The internet is a medium the pushes us to one side of that balance. There is something about it that pushes us to publish our thoughts no matter how nascent or immature they might be – I feel it even as I type this post. How rare it is to pause even just for a few moments before we tap the send button. Taking 6 years to get our thoughts out there is incomprehensible.

I don’t think it is all bad, the push to publish. I’m publishing this blog post without taking a lot of time to review and get feedback. I certainly didn’t start it 6 years ago! However, we may do well to consider how the structures of the system we are in push us in certain ways. Are these ways all good? Could we be swinging the pendulum too far? Perhaps some between the extremes of 6 seconds and 6 years there is a sweet spot of thinking about the things that we publish to ensure that they actually will have a positive impacts on the world.

I’ve been talking about writing up until now, but if you take a moment to think about it, I think you’ll see the analogy to creating software. How much feedback and testing and thought should go into the software that we create before we publish it to the world? In software development, we aren’t generally trying to make something that will be an enduring classic that future generations will engage with 100 years from now, but are we really trying to make something that is an ephemeral as a tweet?

How much thought should go into the software that we publish? I think that if you look at social media platforms, you see a system that heavily rewards instant posting with little to no thought. I don’t know about you, but I find social media to be less and less helpful (although there are islands of usefulness in it). In software development we have a those that espouse code changes going live as quickly as possible. In doing so are we pushing our software systems to become as raw, unmediated and fickle as Twitter and Facebook? Are they going to become more like social media over time?

Let me clarify a few things. First of all, there are some great ways that I have seen people use social media. For example, it can be used as a way to test ideas and get some broad exposure to different ideas very quickly. If you are looking to grow and learn your ideas, social media platforms can be effective for that. The same applies to rapid releases of software development. If the point is to see if your idea is valid, or to better understand some different perspectives that you might be missing, getting your code out there as quickly as possible is a good idea.

If the point of sending your post out into the world is to get as many likes as possible, it seems much less likely to me that your are using the platform to do good in the world. The same with rapid releases of software changes. If the point is get your code out there so that you can have as many dollars as possible, it seems less likely to me that you are actually releasing in a way that is doing good in the world. Rapid releases are a useful tool, if used for the right thing; learning and growth.

A second thing. I am not advocating here for some form of long slow release process. In fact I think having the ability to nearly instantly release code to the public is an enormous advantage. What I’m advocating for here is that we use these kinds of things with thoughtfulness. Just because we can, doesn’t always mean we always should. Sometimes a tweet is the right thing, but sometime a blog post is better and sometimes you need to sit down and write an entire book.

Sometimes immediately releasing your code is the right thing to do, but sometimes a bit of patience and polishing pays off. Sometimes a long slow release pays off. But even then, consider T.E. Lawrence’s process for “releasing” his book.

He wrote the first draft and then lost most of it at a train station (Lesson: always use version control). He then rewrote it into a second draft, but with this draft he was just trying to get down as much as possible of the details before he forgot them. He made sure it was as accurate as possible, but in his words it was “hopelessly bad as a text.” (Lesson: create a prototype). He then wrote a third draft based on the accuracy and structure of the second, but written with much more care (Lesson: Learn from, but don’t ship the prototype). He then sent 5 copies of this text to friends of his for critical review (Lesson: Even things you think are good, can be improved by external feedback). He then incorporated that feedback into the final version of the book.

Overall Lesson: even when releasing something that needs more time and polish before going out, getting feedback along the way is important.

To pull this back to software development, if you are trying to release something that is good quality you will need to have learning loops in place. Testing up front is one such learning loop, but external feedback loops are important too. Just be careful to use that external feedback as a learning loop and not just as a way to feel good about having “released” something. In a world of rapid releasing, live code does not mean you are done. Done happens when you’ve made something that is making life better, not necessarily when you’ve shipped. Shipping is just an experiment. Make sure to treat it as such.

I’m hopeful for humanity. We have things like social media that have been around for a while, and we are starting to figure out their pitfalls. It has taken us as a species a bit of time to figure out this new medium. It doesn’t work like a book or even a blog post and so we can’t put the kind of trust in a post on LinkedIn or Facebook that you can in those other forms of writing. I think we are starting to figure that out and I’m hopeful that we will continue to get better at understanding how to use these platforms well.

In the same way, we have moved to shorter and shorter release cycles in software development, but we haven’t fully adjusted to the new world yet. We still sometimes think of those releases the way we thought of those big bang, year-long releases that we used to do. I think we are starting to get it though. A release is an experiment not a final state.

The more we learn the better we get. Keep on learning!

Photo by Raphael Schaller on Unsplash

Broken People; Broken Software

This world is a broken place. I recently read an article in my local newspaper about parents who lost their son to a drug overdose. The article was posted on Facebook and to read through the comments was hearwrenching. There were several other parents from my town that posted about how the healthcare system had failed them and their families and how they too had lost children to mental health and addictions.

When I read something like that I start to wonder. There is so much brokeness and hurt in our world. There are so many systems that are broken and we are all struggling in our own ways, but what am I doing to help? I have my comfortable life doing my comfortable job, but am I really making a difference? Is this world a better place because of what I do? Am I clawing back at the brokeness at least in some tiny way?

The answer is supposed to be, that by helping get better software into the world, I’m making a difference, and I suppose that is true. But we’ve all felt the weight of the current cultural momen that we are in. Is it enough?

I know I’m not responsible to solve the world’s problem. I know I can’t do it on my own. I know there will always be more that can be done, but how do I connect my work to something more? I don’t talk about it much on this blog, but I am a religious person, and so I do believe that we have a purpose in being here. We were made to do something. Part of that is to make this world a better place.

I’m not ready to give up this thing I love called software testing. I find it facinating. I love what I do and I want to keep doing it.

I just want to comit myself again to doing it with purpose.

I don’t do this to just move up in my career or to make more money. I do this to make life better for a few people. I do this because it brings me joy, and helps make me a better person. I do this because it’s a way to shake my fist at the darkness and brokeness in the world. I do this to cast a glimmer of light. Maybe together we can make a million glimmers of light and change something.

I want to see a world where people aren’t annoyed by software bugs, but also a world where software improves people’s lives. I don’t just want to ensure that we build it in the right way, but also that we build the right thing.

I don’t want to just find bugs (although I do still want to do that). I want to promote ethical software. I want to help people find their own meaning and fun in testing. I want to see us get better at making sofware that acutally enhances people’s lives. Not just better adoption or more users or even higher customer satisfaction ratings. Software that truly makes lives better.

Some of the brokeness in this world comes from software and if we testers won’t take the time to point it out who will? It time to shift the culture of tech. It’s time to stop treating humans like they are data points in our algorithims and instead start treating them like, I don’t know, complex beings with thought, desires, loves and hates. It’s time to do something different.

I don’t know – maybe this article is just therapy for me, but I want to see something different. I don’t know exactly what that is yet, but it’s time to explore it.

Photo by Marianna Smiley on Unsplash

Queuing Theory and Testing

Just for fun, I was recently reading about queuing theory (that’s a normal thing people do for fun right?). One of the things that you need to think about in queuing theory is scheduling policy. There are a number of different way that you can pick which object in the queue goes next. One scheduling policy that intuitively makes sense to me in the first-in, first-out policy. Basically, you would pick the thing that has been in the queue the longest as the one that goes next.

But you can also choose to use a last-in, first-out policy. That doesn’t seem very fair to me. Think about waiting in a queue at the grocery store. You’ve been in line for a while, and someone else comes along and stands behind you in line, but when the next chashier is ready, they help the person who joined the line after you. The last one to join the line is the first one out. Why would you ever choose this scheduling policy?

Well, since I was just reading this for fun, I didn’t bother myself about it too much, but then a couple of days later it hit me that we often use a variation of this policy in the way we manage our backlogs. Things that have been recently added to the backlog are more likely to be worked on than things that have been there for a long time.

Why is that?

One reason for it might be availability bias. The newest items added to the backlog are fresh in our minds and so they seem to be more important. This is a bias, but since software is built by humans, for other humans, it might not be so bad to have human biases in the decisions. Things that are fresh in our minds are probably fresh because they are related to new features that we were working on. These things might be ok to work on first as they might be fresh in our clients minds too. Of course, we should still at least give a little bit of thought to that before assuming it is true in every particular situation, but it might not be an all bad thing.

Another reason for using this kind of queue scheduling is that it might be cheaper to work on stuff that is fresh rather than having to get back into an old context. If we have just created the story or filled out the details on a defect, we should have a pretty good understanding of what we need to do for it. This can mean that we can more quickly complete the newer work in the backlog than we can the older.

I don’t want to gloss over a glaring reality though. The last-in, first-out policy means that those poor items at the front of the queue are very unlikely to ever get a turn. Since there is always more work to be done than there are people available to do it, without some other mechanism to bubble up those older tickets they will languish forever. Most teams have mechanisms that do this (even if they are not deliberately put in place). For example, a client might escalate a known issues and hence bump it up in the queue.

But can we be more intentional about them? What do you think? What are your strategies for dealing with those old defects or stories that have been in backlog for years?

I’m an Author?

I love learning new things. One of the reasons I started this blog was so that I could capture some of the things I’ve learned, but also so that I could learn more effectively. I have always found that for me one of the best ways to learn is by explaining the thing I’m learning to others. Blogging has allowed me to hone and deepen my thinking on a lot of things related to testing.

In the last couple of years I have also branched out into learning and teaching with video courses. I’ve made courses on a number of different testing related topics, and in the process of doing that have been able to learn a lot.

Last year Packt Publishing approached me about writing a book on API testing with Postman. I had published a video course about this with them previously, but writing a book is a lot of work so I said I would have to decline. However, after thinking about it a bit more and discussing it with my manager, we worked out an agreement where I would be able to go down to 4 days a week at work so that I would have the time to work on the book.

Writing a book!

I have to say, writing a book really is a LOT of work. I was already fairly familiar with Postman and API testing, but in the course of writing the book I found I had to really dive deep into some areas. When you dive deep into something you start to discover that there is a lot that you don’t know yet. I had to learn new things and struggle through fundamental concepts. I wanted to make sure that I understood what was going on at a deep level so that I could clearly and simply explain it in the book.

I also spent a lot of time coming up with practical examples. Things that the readers can do on their own. Books are great. I read 3 or 4 books a month and I think books are probably the biggest bang for your buck that you can get when it comes to learning. However, as the ancient Greek philosoper Epictetus said “Books are the training weights of the mind. They are very helpful, but it would be a bad mistake to suppose that one has made progress simply by having internalized their contents.” You can’t just read a book and think that you know the subject. You need to internalize it’s contents. With technical books like this one, I think that is best done by working through the subject on your own. To that end, I have numerous challenges and worked examples that help the readers internalize what they are learning.

Writing a book was certainly a tough and challenging endeavor, but it was also a helpful part of my ongoing quest to be a life-long learner. I learned a lot, and I find myself working on some new things at work that come directly out of the things that I learned. I hope that if you read the book, you find that you are able to learn a lot too!

Free Copies?!

I’ve not only been learning new things about API testing, I’ve also been learning about how book publishing works. One of the things that is important with new books is to get some reviews. In light of that, the publisher has a few free copies available in exchange for your honest review of the book. If you are interested in that, feel free to reach out to me on twitter, or LinkedIn or feel free to send me an email at davewesterveld@gmail.com and I’ll see if I can get you a free copy.

The book is called API Testing and Development with Postman and it is coming out on May 7th (2021). If you do pick it up, let me know what you think! I hope it is helpful.

I guess in a way I have been an author for a long time. I’ve been blogging for many years, and I have published a lot of video courses, but there is something about writing a book that makes me feel like I can now actually call myself an author. Damion Synadinos, has a talk called More Than That, where he talks about the different ways that we label ourselves. Well, I feel like now I have applied a new label to myself. I’m an author.

I guess I better go update my LinkedIn profile.

Photo by Aaron Burden on Unsplash

New Post on TestProject Blog

I know I haven’t been writing on here much lately, but if you are looking to read something I wrote, check out my latest post on the TestProject blog.

It’s about getting started with their open source Java SDK. I like learning new things and this was a fun way for me to learn a bit more about Java!

As I say in that post

 When you have a powerful tool, you don’t need to avoid it. Rather, you need to learn how to wield it well.

It was fun diving in to learn how to better use that tool. Check out the full post here.

Creating Schema for an API

From the outside, software development and magic are indistinguishable. Of course, with enough time you can understand how it works and for those of us who have made it through the frustration of learning to code, it’s really not all that magical after all. It’s just the application of a few simple rules.

I kind of felt that way about schema. I’d heard the term before and I had seen errors come up in my code editor saying that I had a schema validation error. As far as could tell though this all came about by some sort of magic. Well, it turns out this kind of magic can also be learned.

In my last blog post, I wrote about what it was like getting started with creating an Open API specification. In that post, I glossed over the part about creating a schema for the API. However, that was actually the hardest part of getting started with Open API for me. I realized that I didn’t really know that much about schema and how testers can use it. If you too are in that boat, I hope this article will help you out a bit!

What is an API Schema?

Well, when it comes to API schema, we are talking about a set of rules that dictate what the API request or response is allowed to look like. Creating an API schema is about finding the patterns in what the API does and creating rules that define those patterns.

At this point you might still be a bit confused and thinking “give me something concrete.” Well who am I to argue with you on this? When the people ask for concrete examples they get them, even if the people are only made up voices in my head.

Suppose you were looking at an API that gives you data about COVID cases in your country. One of the fields in the API response is the number of cases. You know some things about this field. For example, I’m pretty sure you can’t have less than 0 COVID cases (unfortunately). I’m also pretty sure you can’t have partial cases of covid. This means that you know that this field needs to be an integer that is greater than or equal to 0. These are some rules that you can apply to that field in your API response. What an API schema does is gives you a way to encode and document these rules.

How Does Open API use Schema?

Open API uses the JSON Schema as it’s starting point. It doesn’t use all the elements of JSON Schema and it does add some of it’s own elements as well, although the latest 3.1 Open API spec has pretty much synchronized the two. You can define the schema in a couple of ways. You can just do it directly inline with the resource you are trying to define, or you can create it in a shared schema section in the specification file and refer to it from the resource. I will show you an example of the second way of doing it.

In the previous post, I showed an example of defining an endpoint that looked like this:

paths:
  /endpoint/path/{pathParameter}:
    get:
      description: Makes the world a better place.
      responses:
        '200':
          description: You got a totally ok result.
       content:
            application/vnd.siren+json:
              schema:
                $ref: '#/components/schemas/SchemaName'

The $ref: part points to where it should be getting the schem from. You can create that section in the specification file and then add your schema into it.

components:
  schemas:
    SchemaName:

In this section you can then create the rules that you want to enforce. I have found the documentation on this page to be helpful with figuring out how to create the schema rules that I want. If you consider the example of an endpoint that should only have positive integers, you could specify the schema for it like this:

components:
  schemas:
    SchemaName:
      type: integer
      minimum: 1

By referencing this schema in a response, you would be saying that htis response can only contain integers that are 1 or more. There are of course, many other rules that you might want to specify in a schema, and you can see some great examples in the documentation I referenced above.

I know this is a very quick survey through the subject, but hopefully it helps you to get a grasp on what a schema is and on how and why you would want to use one in an Open API Specification.

Photo by Ivan Aleksic on Unsplash

Getting started with the Open API Specification

Twenty, twenty-one, twenty-two. Twenty-two seconds! Twenty-two seconds to load the data for a simple table. Somehow we had repeated the same mistake we had run into before. A year or two before we were working with an API that used sperate endpoints for each cell in the table we were creating on the page. That works fine until you have a table with 100 rows and 5 or 6 columns. Now you have to send hundreds of API calls and even if each one is small on it’s own, it takes time for the calls to traverse the network. The HTTP protocol limits the number of calls you can make concurrently and so queing theory applies and the load time for the table gets really slow.

And now here we were. We were creating another table in our UI and the API that supplied it had a different endpoint for each cell in the table. How did we get here? During the design we had discussed performance and how we would need to design the API so that we wouldn’t come across this exact issue. Somehow as a team when we go caught up in the work of creating the APIs that would pull together all the data we needed, we missed this piece of the API design.

We are a well functioning, highly productive software development team. In fact, we refactored the API to work as it should have within a week, and yet we had missed this. I suspect we aren’t the only team that has faced something like this. We were building a system that would deal with a lot of complexity and present it in a simple way so that our clients wouldn’t need to deal with it. The challenge of course, is that there are so many details to keep in mind. Domain and functional requirements. Design and presentation of the UI. Security and correct user permissions. Accessibility and performance. It isn’t possible to keep this all our heads at the same time. Thing get missed.

That’s why we have testers right?

I don’t know. That doesn’t feel like the right approach to me. Sure, we can use after-the-fact testing to find those bugs, but we had already identified this bug. We knew that creating an API where each cell in a table needs to call a different endpoint is not scalable. In essence, we had to find this bug twice. Once during design and once after development. The second time we found it, the bug was expensive to fix. Could we have prevented that regression? Can we create regression tests for our designs?

This is one of the problems that API specifications attempt to solve. In reflecting on this issue, I started to wonder if we could have saved ourselves a lot of rework by encoding the things we had discussed and discovered during our design sessions. What if we wrote them down in an API definition that set out what the API should look like and do?

You can’t do much about the past, but you can learn lessons from it and use those lessons to make the future better. I’m sure our team will be writing more APIs in the future and so I want to explore some of the different API specification to see if there is something that would make sense for us to use in the future.

Open API Specification

The most common specification format is the Open API Specification (or OAS). It has in many ways become the default specification for describing how APIs work. It has very broad adoption across many companies and has a large supporting community. It is designed for RESTful APIs, which we use, and it has support for almost anything you would do with these APIs.

I’ll be honest though, I find it overwhelming to get started with. It is a lot of work to document every detail of what your API can or should do. Since we have existing APIs that do not yet have API definitions I thought I would try using the Swagger inspector. It gave me something to get me started, but it still needed a lot to be done by hand. Since at this point, my goal is more around evaluating if this makes sense for future APIs, I decided to instead look at creating a definition “from scratch”. I’d like to use a design first rather than code first approach to this.

So how hard is it to create an API defintion that follows the OpenAPI Specification?

The Tools

Well, let’s start with talking about the tools. There are a lot of Swagger tools that work with Open API Specifications. Confusingly the OAS used to be called Swagger, but once you get past that, there are still many tools out there. It’s easy to get lost in trying to figure out which tool does what, and which one you want to use. I know because I spent too much time trying to figure out which one to use. Eventually I decided that I wouldn’t use any of the custom built tools. OpenAPI defintions are just text files (either yaml or json format) and so they can be edited in any text editor.

I created a file in my trusty Visual Studio Code, installed a couple of OpenAPI formatting and linting extentions and I was finally off the races. I’m sure that if I use this more, I will eventually want tools that are built specificially for the OAS, but I’ll stick with the basics for now and see where the pain points show up as I scale. If you are new to using the OpenAPI Spec, I’d recomend taking this approach too. Not only will it force you to understand what is going on more deeply, but it will also remove a whole layer of confusion that can get in the way of just getting started.

Creating the API Defintion file

A blank file staring at you can be intimidating, but I guess the best way to get something done is to start doing it, so let’s look at what data needs to go into this file.

The First Section

So, how do you actually create an API definition with the OAS? The basics of it are straigtforward. Start with a bit of boilerplate at the top that says what version of the OpenAPI Spec you are using along with some information about the API your are creating the definition for.

openapi: 3.0.1
info:
  title: A cool API
  description: This API does cool stuff
  version: '1.0'
servers:
  - url: https://{tenantId}.domain.api.com
    variables:
      tenantId:
        default: tenant-id-guid-123

One simple thing I ran into here was that each instance that we create (and we have at least one for each of our clients) has a different base url. This includes all the testing sites. Pretty easy to take care of though. You can create a parameter in the url. You can read more about how the base urls work here if you want.

Defining an Endpoint

With the boiler-plate out of the way, the next thing to define is an endpoint. Endpoints are defined under the paths section.

paths:
  /endpoint/path/{pathParameter}:
    get:
      description: Makes the world a better place.
      responses:
        '200':
          description: You got a totally ok result.
      parameters:
        - name: pathParameter
          in: path
          required: true
          schema:
            type: integer
            format: int64
            minimum: 6606

I’m obviously redacting some stuff here, since these are internal APIs, but it’s interesting to note how easy it is to create a parameter in the path. All I needed to do was to include it in the path defition and then create a parameters section under the request to define what kind of parameter it was.

You will notice though, that the responses object only defines the response code. It says nothing about what kind of content this API should give back. That seems like it would be kind of important. Defining this opens up a whole new can of worms. Obviously the API does not always give back an identical response every time you call it, and so you can’t just copy a response and put in in there. Instead you need to specify some general rules that should apply to the response. For example, you could specify that it should be a list and that each item in the list should be a string. These kinds of rules are known as schema. The kinds of objects our API represents are pretty complex and so it takes a bit of work to create a schema for them.

In fact, as I dug into this I realized that this is actually the area that was the most intimidating to me. I’m pretty comfortable with the way RESTful APIs work and so setting up stuff with the paths was pretty intuitive. However, although I have benefited greatly from using schema that other have made to help with validation, I have not had to create schema before. I did find a good schema generation tool here that really helped, but I needed to go through and do a lot of clean up. Everything that went into creating the schema is worthy of it’s own blog post someday, so I won’t go down that rabbit trail right now.

After creating the schema, I could use it to define how the content of the response should look:

paths:
  /endpoint/path/{pathParameter}:
    get:
      description: Makes the world a better place.
      responses:
        '200':
          description: You got a totally ok result.
       content:
            application/vnd.siren+json:
              schema:
                $ref: '#/components/schemas/SchemaName'

In the content object I’ve first defined the content type. This is what is returned in the Content-Type header of the response. I then use a $ref object to specify a reference location where it should look for the schema for this response. Schema is often shared between different parts of an API, and so by moving it into it’s own section, you can reference it from multiple places without needing to create it multiple times.

Defining Security

As I said earlier, I won’t get into the details of creating the schema in this post. Instead let’s look at how to define security options. The API I’m investigating uses bearer tokens which is pretty easy to define with the OAS.

components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
security:
  - bearerAuth: []

And with that, I have an extremely basic, but functional schema. I’ll leave it there for now, but in future posts I will share how it went when I was creating a schema and also share how I used the definition file to actually do something useful.

Although it was a bit intimidating at first, as I worked my way throught this, it didn’t take long to feel like I could put together something useful. How did you find it getting started with using the Open API Specification?

Photo by Jon Eric Marababol on Unsplash

Getting Started with API Specification Languages

The quest for ever higher levels of abstraction never ends in computing. I used to work at a company that still ran some FORTRAN code. Although out of date now, the invention of FORTRAN in the 1950 was revolutionary in the way it abstracted away the need for humans to work with assembly language and punch cards. Fast forward a couple of decades and object oriented languages like C++ came along with increased levels of abstraction. Then we got rid of the need for humans to do garbage collection and memory allocation in increasingly abstract languages. We have continued to created additional layers of abstraction through widespread use of libraries and I would argue even through the increase use of APIs.

But we didn’t stop there.

Once APIs become widespread, we started looking for ways to simplify our interactions with them. This is where API Specification languages come into play. I want to explore some of the different specification languages that are in common use over a few blog posts. Before diving into specific specifications though, I want to look at what an API specification is.

What are API Specifications?

API specifications provide a structured way to define an API. If you follow the rules of the specification, you can interact with the API at a higher level of abstraction. For example, an API specification could be used to automatically create mock servers that you can use for testing and experimentation during development. You can also do things like automatically generate documentation and contract tests. You can even use these specifications to generate some kinds of code, for both server implementations and for client side code that calls the API.

RESTful APIs follow an architectural style laid out by Roy Fielding in his doctoral dissertation. This means that there are general principles laid out that they follow, but there is not a strict protocol that they must adhere to. This balance between structure and flexibility has been a powerful concept and has contributed to the widespread adoption of this kind of API architecture. There is no such thing as a perfect solution, however, and this one is no different. For example, one of the benefits of strict API protocols like SOAP is that the structure must be specified following strict programmatic rules. This means that the API definition must be written in a way that computers can easily understand. This makes it easy to create a lot of general-purpose automation for these kinds of APIs. If a computer can understand the layout of an API, you can automatically generate some kinds of documentation, tests and even code from that specification.

Without that strict specification, each RESTful API may have some nuances to it that are different from others. As humans, this is generally fine. We can quickly and easily figure out where those differences are and accommodate them. Computers struggle with this. Things have to be very clearly and explicitly laid out for a computer to use it. This challenge with RESTful APIs was recognized pretty early on, and so some API specification formats were proposed.

Should you use an API Specification Language?

Yes.

And no.

Asking if you should use an API specification language is like asking if you should use a hammer. In order to answer that question, you need to first know if you are trying to get in a nail or a screw. Whether or not to use it depends on what you are trying to do.

API specification languages are good for helping you solve certain kinds of problems. They can help to keep things consisent between documentation and the functionality of your code. They can also be used to help you design APIs and to establish and enforce contracts around how an API should work.

However, there are downsides as well. If you want to use an API specification you need to be willing to maintain it. They often won’t have much value if you let them get out of sync with the underlying code. There are tools that can help with this maintance, but it is an important consideration if you are looking to implement the use of an API specification. Since using API specifications can cause some additional overhead they are usually best suited to scenarios where you have multiple people across multiple teams working on a set of APIs and where you need clear and unambigous ways to communicate how an API works.

So should you use an API specification language? I would say that unless you are working on a very small API with a small team, it is something worth considering. In my experience many development teams could benefit from a little more rigour in their processes and API specification will help with that. Just go in with your eyes wide open and don’t expect it to be some kind of magic pill. As with anything, it take hard work and discipline to use well.

Types of API Specifications

There are three main RESTful API specifications: RAML (https://raml.org/), API Blueprint (https://apiblueprint.org/) and OpenAPI (https://github.com/OAI/OpenAPI-Specification). Previously OpenAPI was called Swagger, so if you hear anyone talking about Swagger, just realize that it is the same thing as OpenAPI.

Over the next couple of weeks, I will share posts diving into these three API specifications and how to use them, but for now I just want you to have an idea of what they are. API specifications can be a powerful testing tool. You can use them to keep documentation, tests and even underlying code all in sync with each other. They can also be a tool that helps to maintain contracts between different parts of an application and can help less technical people get included in the design and testing of APIs. As I go through how to use each of the specifications, I’ll talk about this stuff in more detail. Stay tuned for more posts in this series!

Photo by Tim Gouw on Unsplash

What Problems do your Customers have?

Back in the days before COVID, when we could go to museums en masse, the Louvre in Paris had a problem. They had moved the Mona Lisa to a new room. The problem was, the room was only accessible through a single door and the resulting bottleneck led to many who had bought tickets being turned away or having to wait in line for hours to see the painting.

It was a horrible customer experience for thousands of museum goers. How many of them do think complained? How many requested a refund?

How do you know if you have a good quality product? Well, one of the things you could measure for that is how often you get customer complaints. Surely if there are very few clients complaining, the quality is good right?

Well, those museum goers who had a horrible experience: about 2% complained and less than 1% asked for a refund. I think there are two lessons to learn here.

In the first place, one customer complaint might just mean 50 to 100 other customers have the same pain point and never bothered to complain. Take customer complaints seriously. In the second place, you can’t rely on customer complaints to let you know when you have quality problems.

You need to do testing before releasing, and you need to have other ways of discovering problems that have been released that don’t require relying on customer complaints. When testing ahead of a release, don’t just look for functional bugs. Look for where users might experience pain. What things are going to give the customer a negative experience with the product?

Also, don’t just throw a product out there and assume that you’ll hear about the problems. Invest in some monitoring. Figure how to find those pain points for your customers and improve them without waiting for a complaint. As a software industry we have spent many years teaching people to put up with annoyances and frustrations. We can do better.

Photo by Mika Baumeister on Unsplash