Technical Test on Article API
Abstract
For the technical test on an set of article API, this document outlines its requirements, and the design, development environment, test for its implementation.
Each original requirement is assigned a unique id starting with capital 'R', which helps requirements management, especially when no management system is in place that is critical for team-based software development. Such unique requirement identification is also vital in designing test plan, particularly test case-to-requirement matrix. In addition, these requirement ids have been cited in codebase for pertinent implementation.
Other than three endpoins specified in teh original requirements, I have further added one (R4) to list attributes of all articles.
Requirements
Endpoints
Originally, it's required to create a simple API with three endpoints. I've further added one to list attributes of all articles.
- R1: POST/articles - Should hanlde the receipt of some article data in JSON format, and store within the service.
- R2: GET/articles/{id} - Should return the JSON representation of the article.
- R3: GET/tags/{tagName}/{date} - Should return the list of article(s) that have that tag name on the given date and some summary data about that tag for that day.
- R4: GET/articles/all - Not part of original requirements, but proposed to list all articles' attributes.
Content Structure of an Article
R5: An article has the following attributes id, title, date, body, and list of tags. for example:
{
"id": "1",
"title": "latest science shows that potato chips are better for you than sugar",
"date" : "2016-09-22",
"body" : "some text, potentially containing simple markup about how potato chips are great",
"tags" : ["health", "fitness", "science"]
}
Content Structure of GET/tags/{tagName}/{date} result in JSON
R6: The GET /tags/{tagName}/{date} endpoint should produce the following JSON. Note that the actual url would look like /tags/health/20160922.
{
"tag" : "health",
"count" : 17,
"articles" :
[
"1",
"7"
],
"related_tags" :
[
"science",
"fitness"
]
}
R7: The related_tags field contains a list of tags that are on the articles that the current tag is on for the same day. It should not contain duplicates.
R8: The count field shows the number of tags for the tag for that day.
R9: The articles field contains a list of ids for the last 10 articles entered for that day.
Design
Gin web framework is utilised to build the application.
Gin is a HTTP web framework written in Go (Golang). It features a Martini-like API with up to 40 times faster performance.
List of assumptions
- For requirement #8 (R8), those counted tags are non-duplicate, including inquiring tag name.
- The date of each article proposed in the original requirements is assumed to be publishing date, hence I have to add a date-related field also contain time, of the article's entry, in order to be sortable to include the most recently ten articles entered for the date. The added field shall contain UTC time and be named EntryTime.
Source of articles data
For the sake of maintenance, the source of articles data shall be contained in a file named articles.json. For possible further population of the input data, just do it at the file without having to go to modify the Go code, followed by rebuilding of the code.
Choice of languages and library
Language/Library | Version | Reference | Reason |
---|---|---|---|
Golang | go1.17.1 windows/amd64 | Mandatory choice of language | |
github.com/gin-contrib/sse | v0.1.0 | go.mod & go.sum | Better performance of resultant web app |
github.com/gin-gonic/gin | v1.7.7 | go.mod & go.sum | |
time | Parse UTC-based EntryTime of each article | ||
sort | Sort multiple pieces of UTC-based EntryTime info before cutting of ten most recent entries |
Development Environment
OS (Operating System)
OS | Version | OS Build |
---|---|---|
Windows 10 Home | 21H1 | 19043.1466 |
IDE (Integrated Development Environment)
To code, execute the application at the server side. Or even execute curl command to communicate with the application at server side from client side.
Tool | Version |
---|---|
Visual Studio Code | v1.63.2 |
Web Browser
To open URL to access the article API. Following three major brands of browser work as expected.
Tool | Version |
---|---|
Firefox Developer Edition | v97.0b4 (64-bit) |
Google Chrome | v97.0.4692.71 (Official Build) (64-bit) |
Microsoft Edge | v97.0.1072.02 (Official Build) (64-bit) |
Command line tool
To transfer data to and from a server that hosts the article API.
Tool | Version | Remark |
---|---|---|
cURL | v7.65.3 (x86_64-w64-mingw32) | aka Client URL |
GitBash
When not issued from VS Code, we need an shell emulation layer for executing cURL command, or issuing Git command.
Tool | Version | Remark |
---|---|---|
GitBash | v2.23.0.windows.1 | aka Client URL |
Setup/Installation
Enter GitBash and Preparation
Open a GitBash and change into a working directory.
Execute following command:
git init
Cloning
Left-mouse click on green "Code" button at middle right of the screen, then click on button, as illustrated by the screenshot below.
Execute command in following syntax:
git clone <clone path>
Where <clone path> is the clone gained through aforementioned process
Then you will see the cloning process as shown below.
Execution
Under a GitBash or VS Code, issue following command to execute the app.
go run .
Either under VS Code or GetBash, once seeing following message, prepare to go to a browser for further testing from frontend.
Test
Via Web Browser
Following matric illustrates the mapping between test cases and requirements.
Test Case | URL | Requirement Id | Description | Expected Result |
---|---|---|---|---|
1 | localhost:8080/articles/all | R4 | List all articles | |
2 | localhost:8080/articles/1 | R2 | List article with Id=1 | |
3 | localhost:8080/articles/2 | R2 | List article with Id=2 | |
2 | localhost:8080/articles/15 | R2 | List article with Id=15 | |
3 | localhost:8080/articles/16 | R2 | List article with Id=16 | |
6 | localhost:8080/articles/17 | R2 | List article with non-existing Id | Expected to see |
7 | http://localhost:8080/tags/climate%20change/2013-01-21 | R3 | List articles whose Date is "2013-01-21" and tag name is "Climate Change" |
Via cURL
Resemble to test case#1
Find a GetBash, issue following command
curl -X GET http://localhost:8080/articles/all
or shell script under GetBash:
./curlGetArticles.sh
On screen, should see output message resemble to that of test case#1 stated above.
Resemble to test case#2
Find a GetBash, execute following command
curl -X GET http://localhost:8080/articles/1
or shell script under GetBash:
./curlGetArticle1.sh
On screen, should see output message resemble to that of test case#2 stated above.
Resemble to test case#6
Find a GetBash, execute following command
curl -X GET http://localhost:8080/articles/17
or shell script under GetBash:
./curlGetArticleNonExisting.sh
On screen, should see output message resemble to that of test case#6 stated above.
Test Case#8
Requirement Coverage: R1
Find a GetBash, execute following command
curl -i \ -H "Content-Type: application/json" \ -X POST \ -d '{"Id":"19","Title":"Test Article 19 psuedo title","Date":"2022-01-17","Body":"Psuedo body","Tags": ["tag1", "tag2", "tag3"]}' \ http://localhost:8080/articles
or shell script under GetBash:
./curlPost.sh
To verify the result of such "POST" act, either use a web brwser to open following URL:
localhost:8080/articles/19
or shell script under GetBash:
./curlGetArticle19.sh
Configuration
Eventhough it's kind of low frequency of adjustment, I make following three constants configurable at the beginning of codebase main.go.
Constant | Value (string) |
---|---|
DevHostURL | localhost:8080 |
ARTICLES_FILE | articles.json |
MAX_ARTICLES_OF_TAGNAME_DATE_QUERY | 10 |
Wish list
- Move articles data from file to MongoDB.
- Integrate Selenium + Ginkgo + Gomock for automated web application test.
- Upon closure of the API application, the executioner should be asked whether to save the recent addition of article(s), very likely through "POST" act, back to data file articles.json.