Skip to content
fall2016-project-axis7818 created by GitHub Classroom
Java JavaScript HTML CSS
Branch: master
Clone or download
Pull request Compare This branch is even with cpe305:master.
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
.settings
common
docs
service
.gitignore
.project
.travis.yml
README.md
pom.xml

README.md

NowYouKnow

Build Status

A simple web app and API for asking and answering simple/stupid questions.

Cameron Taylor


topic


question


random


System Architecture

Now You Know is built with a 3 tier service oriented architecture. All of the database infrastructure is stored in the nowyouknow.common package, all of the service infrastructure is stored in the nowyouknow.service package, and all of the front-end code is stored in service/src/main/resources/public and served statically.

system architecture


Data Entities

These objects are the main entities that are stored in the database. They exist in the nowyouknow.common.data package and represent database rows. Interactions with the database are done with the nowyouknow.common.dao package with CrudRepository interfaces. All Dao objects extend Spring's CrudRepository. Only additional methods are documented here.

Class Diagram

class diagram

Topic

id: Long
A unique identifier.
name: String
The name of the topic.
description: String
A short description of the topic.
questions: List
A list of all questions under this topic.

TopicDao

findByName(name: String): Topic
Finds a Topic object by its name.

Question

id: Long
A unique identifier.
text: String
The question itself.
open: Boolean
Whether or not a question is open for being answered or edited.
whenAsked: Date
The point in time when the question was asked.
topic: Topic
The topic that the question falls under. Can be null.
reaction: Reaction
The reaction object for this question. Cannot be null
answers: List
A list of all answers for this question.

Answer

id: Long
A unique identifier
text: String
The actual answer.
whenAnswered: Date
The point in time when the answer was made.
question: Question
The question that this Answer answers. Cannot be null.
reaction: Reaction
The reaction object for this Answer. Cannot be null

Reaction

id: Long
A unique identifier.
likes: Integer
The number of times this object was 'liked'.
dislikes: Integer
The number of times this object was 'disliked'.
laughs: Integer
The number of times this object was 'laughed'.

System Design

Architecture

MVC

The MVC pattern is used in two places: service controllers and Angular's front end. The service controllers hold methods (controller) that house business logic and access the database (model) accordingly. The results of these operations are passed to the front-end (view) when they have completed.

Angular takes the resulting data from API calls and builds its own javascript objects to act as a model local to the browser. These model objects are presented in html form and controllers written in javascript handle user interactions, form validation, and communication with the service.

Dependency Injection

The pattern of dependency injection is used throughout the entire project. All java classes are valid beans and all javascript components are wrapped as appropriate angular components. This means that every object in the system can be mocked and injected into other objects according to the needs of that object. For example, when testing the controllers, the DAO objects are mocked so that they do not perform any database accesses. This allows for true unit testing that isolates the controllers' behavior.

Design Patterns

As it stands now, there are no GoF design patterns present in the NowYouKnow codebase. This is on purpose as there were no opportunities to leverage any of these design patterns in an appropriate fashion. I had intended to add a Reactable interface to use a bridge pattern, but since my Question and Answer classes needed to map directly to database tables, this was hard to do while preserving ORM (Object Relational Mapping).


Key Learning

The thing that I liked the best about my project was the use of dependency injection. Not only did this allow for strong and thorough unit tests, but it also allowed me to better take advantage of functionality offered by the Spring framework. The code that I wrote in this project follows "best practice" conventions closer than any other code I have written, and even though the overall project is not super complex, it is beautiful code to look at.

The most important lesson that I learned was that Software Engineering is not just writing code. I already knew this, but I never had an appreciation for just how important it is to write good documentation and testing. Writing actual system code only took about 20% of my time working on the project.


REST Resources

Topic, Question, and Answer objects each have a corresponding class in nowyouknow.service.results that represents a flattened version of the object. These are the entities that are converted to/from json request bodies.

JsonTopic

{
   "id": 1,
   "name": "Hitchhiker's Guide To The Galaxy"
}

JsonQuestion

{
   "id": 1,
   "text": "What is the answer to life, the universe, and everything?",
   "open": true,
   "whenAsked": 57392084732,
   "topicId": 1,
   "likes": 894,
   "dislikes": 32,
   "laughs": 123
}

JsonAnswer

{
   "id": 1,
   "text": "42",
   "questionId": 1,
   "likes": 42,
   "dislikes": 0,
   "laughs": 3
}

/topic

Requests to this URI are handled by TopicController.

POST /topic/

{
   "name": "New Topic"
}

Post a new topic. The name must be less than 257 characters and a topic of the same name cannot already exist in the database.

GET /topic/

Retrieves a list of all topics.

GET /topic/{identifier}

Retrieve a single topic. The identifier can be the topic's name or id.

GET /topic/{identifier}/questions

Retrieve a list of all questions for a given topic. The identifier can be the topic's name or id.

PUT /topic/{identifier}

{
   "name": "New Name"
}

Update a topic identified by {identifier} with the body parameters. A topic with the same name cannot exist in the database.

DELETE /topic/{identifier}

Delete a topic. Identifier can be the id or name.

/question

Requests to this URI are handled by QuestionController.

POST /question/

GET /question/{id}

GET /question/{id}/answers

PUT /question/{id}

DELETE /question/{id}

/answer

Requests to this URI are handled by AnswerController.

POST /answer/

PUT /answer/{id}

GET /answer/{id}


You can’t perform that action at this time.