This blog post is part of a series about the development of ALE News using an approach to software development called Acceptance Test-Driven Development. For an overview please see the introductory article.
Unlike in the past I wanted to use a modern web application architecture. The server should not be concerned with any presentation duties. That means: no HTML will be created on the server. Instead there will be a server application exposing RESTful web services and the actual website will be rendered in the browser - being a pure client consuming the services from the server.
I want to start with a service that allows CRUD operations onto an archive for article metadata.
Before going deep it makes sense to gain a rough overview of the task at hand. What follows is an overview of the planned service to access the archive for article metadata.
Feature: CRUD and list scooped articles
Scenario: Create new article metadata
Scenario: Read article metadata
Scenario: Update article metadata
Scenario: Delete article metadata
Scenario: List article metadata
With that feature description I outlined what my service is going to do.
With that in place I was talking to my self and came up with the following, more detailed, scenario for creating a new entry in the metadata archive.
RESTful web services use HTTP verbs to perform actions onto a resource. A good overview is available at Wikipedia. To create a new item one sends a POST request to the web service and the service should then return some ID for the newly created item.
Scenario: Create new article metadata
When I post the following article metadata to the article service with URI "/article"
| Author | Title | location |
| Stephan Schwab | From competition it is a big leap to cooperation | http://www.stephan-schwab.com/china/culture/management/thoughts/2014/08/30/collaboration-or-cooperation.html |
Then an article ID is returned
And the article metadata has been stored in the archive
I would have written this scenario in a slightly different way:
Scenario: Create new article metadata
When I post the following article metadata to the article service
| Author | Title | location |
| Stephan Schwab | From competition it is a big leap to cooperation | http://www.stephan-schwab.com/china/culture/management/thoughts/2014/08/30/collaboration-or-cooperation.html |
Then an article ID is returned
And the article metadata has been stored in the archive
The second version is more about WHAT the service does and does not give away and details about how to use the service. However, when working with a group of developers earlier this year in Berlin I learned that sometimes giving away a little hint isn’t that bad. Those developers wanted to have their scenarios express how to use the service so that the scenarios can be used as some sort of user documentation for those consuming the service. I think that makes sense.
Then I created the necessary boilerplate for Cucumber JVM and provided step definitions for the first two steps of my scenario - just enough to get started.
@When("^I post the following article metadata to the article service with URI \"(.*?)\"$")
public void postArticle(String uri, List<ArticleMetadata> metadata) throws Throwable {
expectedMetadata = metadata.get(0);
actualArticleId = ClientBuilder.newClient()
.target("http://localhost:8080/article-service").path(uri)
.request(MediaType.APPLICATION_JSON_TYPE).post(Entity.entity(expectedMetadata, MediaType.APPLICATION_JSON))
.readEntity(ArticleId.class);
}
@Then("^an article ID is returned$")
public void an_article_ID_is_returned() throws Throwable {
assertThat(actualArticleId.getId(), is(notNullValue())) ;
}
The Java step definition contains a number of technical details. Those are clearly about how to use the service and should definitely not be in the scenario description.
The data format used by consumer and service is JSON. In the request the client is asking for JSON data: request(MediaType.APPLICATION_JSON_TYPE)
. It is also sending the encoded entity (the article metadata) as JSON: post(Entity.entity(expectedMetadata, MediaType.APPLICATION_JSON))
With that in place I needed to write just enough code to at least get to the Then an article ID is returned step. So I wrote this:
@Path("article")
public class ArticleResource {
// todo: fake
private static ArticleMetadata fakeArticle ;
@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public ArticleId storeArticle(ArticleMetadata metadata) {
ArticleId id = ArticleId.generate() ;
fakeArticle = metadata ;
fakeArticle.setId(id.getId()) ;
return id ;
}
}
Note that I’m using a static variable to hold the article metadata posted to the service.
Unlike other approaches, I want to focus on the behavior of the service and not spend time thinking about how the service will perform it’s work on the inside. There will be a time for that later on. At the moment I feel that for the new version of ALE News I need the ability to somehow store and retrieve article metadata but there is certainly a lot more than just that. I want to explore those other things first a bit before spending time and effort on fleshing out a service that I might need to change substantially or replace with something else soon.
After all, software product development is a journey and you never know what you will discover.
Previous | 19 Sep 2014 | Next |
This article has been posted to social media sites. There might be comments. Just follow the links:
About me
Hello! My name is Stephan Schwab.
As International Software Development Coach and Consultant I help CEOs and Department Leaders to improve value creation and cohesion within their organization. The outcome will be higher quality, customer delight and more revenue.
Learn about my professional experience since 1986.
Professional Services
I'm fluent in these human languages:
Scrum Pair-Coaching to develop technical competence:
Resources for new clients:
Search
Special Content
Highlights of the Year
Living on planet Earth
Open Source Projects
Stay in touch
My Books
Everything
See a listing of all posts on this site.