How I built a REST microservice
DevNet API
Scavenger
Hunt
Ashley Roach – Cisco DevNet
Principal Engineer & Evangelist
@aroach
@aroach@CiscoDevNetdeveloper.cisco.com
About Me
• API & Cloud Evangelist
• 10+ Yrs Technical Product Mgmt
• Life-long, self-taught developer
• Denver, CO
• github.com/aroach & github.com/ciscodevnet
• Podcast: devtools.libsyn.com
DevNet Vision
Help developers build solutions
and grow their careers.
Learn Code Inspire Monetize
@aroach@CiscoDevNetdeveloper.cisco.com
• §1: Why and What
• §2: Show the code
@aroach@CiscoDevNetdeveloper.cisco.com
§1: Why and What
@aroach@CiscoDevNetdeveloper.cisco.com
Cross-train our technical
field
@aroach@CiscoDevNetdeveloper.cisco.com
What Did We Do?
• Created background “mini-hacks” activity at
sales conference
• Needed a way for them to submit answers
• Why not make them do it via an API?!
@aroach@CiscoDevNetdeveloper.cisco.com
How we ran it
• Three challenges per day (Jive site)
• Answers were provided at the beginning of the next day
• Support via a Cisco Spark room
• Submissions were analyzed after the event
• Small monetary rewards to top 3 finishers
@aroach@CiscoDevNetdeveloper.cisco.com
Meetup!
@aroach@CiscoDevNetdeveloper.cisco.com
Solution evaluation was hardest part
• Wrote a CLI
• Created manually, but could have used swagger-code-
gen
• Wrote test cases
• Manual validation in the end
@aroach@CiscoDevNetdeveloper.cisco.com
§ 2: Show the code
@aroach@CiscoDevNetdeveloper.cisco.com
Project Requirements
• Build an API quickly (~a couple days)
• Data Persistence
• User and API Authorization
• Only an API (No UI for user)
• Package in a “cloud native” way
@aroach@CiscoDevNetdeveloper.cisco.com
Infrastructure Architecture
DBaaS
CI/CD
Scheduler
@aroach@CiscoDevNetdeveloper.cisco.com
Technologies involved and evaluated
• I know MEAN stack (Mongo, Express, Angular, Node)
• I wanted to try out building using a REST modeling tool
• Swagger-node
• Osprey (RAML-based): seemed less feature rich
• Containerized to be deployed on ciscoshipped.io
• GitHub
• Postman
• MongoHub (Mongo client)
• mLab (Hosted mongo)
@aroach@CiscoDevNetdeveloper.cisco.com
OpenAPI Spec (fka Swagger)
• Open specification for describing REST APIs
• A top-down approach where you would use
the Swagger Editor to create your Swagger definition
and then use the integrated Swagger Codegen tools to
generate server implementation.
• A bottom-up approach where you have an existing
REST API for which you want to create a Swagger
definition.
@aroach@CiscoDevNetdeveloper.cisco.com
Dockerfile
FROM node:5.11.1
# Create app directory
RUN mkdir -p /usr/src/app
# Establish where your CMD will execute
WORKDIR /usr/src/app
# Bundle app source into the container
COPY ./node_modules /usr/src/app/node_modules
COPY ./api /usr/src/app/api
COPY ./config /usr/src/app/config
COPY ./app.js /usr/src/app/
# Expose the port for the app
EXPOSE 10010
# Execute "node app.js"
CMD ["node", "app.js"]
@aroach@CiscoDevNetdeveloper.cisco.com
Docker run --link
• Legacy container links within the Docker default bridge.
• This is a bridge network named bridge created
automatically when you install Docker.
• Superceeded by Docker Networks feature
@aroach@CiscoDevNetdeveloper.cisco.com
Makefile
run:
docker run --rm --name $(NAME)-$(INSTANCE) $(LINK)
$(PORTS) $(VOLUMES) $(ENV) $(NS)/$(REPO):$(VERSION)
$ make run
$ docker run --rm --name devnet-challenge-api-default
--link mymongo:mongo -p 8080:10010 --env-file=.env
ciscodevnet/devnet-challenge-api:v1
@aroach@CiscoDevNetdeveloper.cisco.com
Node Libraries Used
• Swagger-node
• Express: Node HTTP server
• Bcrypt: Password hashing in DB
• Mongoose: Node mongo library
• Jsonwebtoken: JWT library
• Password-generator: generate random passwords
• Marked: Convert Markdown to HTML for docs
@aroach@CiscoDevNetdeveloper.cisco.com
Swagger-node
• Runtime environment that includes Swagger Editor
• swagger project <command>
• Start
• Edit
• node app.js for proper deployments
@aroach@CiscoDevNetdeveloper.cisco.com
Swagger Editor
@aroach@CiscoDevNetdeveloper.cisco.com
My swagger-node workflow
IDEA
Swagger
Edit
Add/Edit
Model &
Controller
Swagger
test
Make build
& run
Verify
git add /
commit /
push
shipped
deploy
Verify
@aroach@CiscoDevNetdeveloper.cisco.com
.
├── Dockerfile
├── README.md
├── api
│ ├── controllers
│ │ ├── README.md
│ │ ├── authenticate.controller.js
│ │ ├── challenge.controller.js
│ │ ├── challenge.model.js
│ │ ├── health.controller.js
│ │ ├── user.controller.js
│ │ └── user.model.js
│ ├── helpers
│ │ ├── README.md
│ │ └── mongoose
│ │ ├── common-fields.js
│ │ └── search.js
│ ├── mocks
│ │ └── README.md
│ └── swagger
│ └── swagger.yaml
Correspond to swagger
properties:
// swagger.yaml
• x-swagger-router-controller
• operationId
Anatomy of project
@aroach@CiscoDevNetdeveloper.cisco.com
# swagger.yaml
paths: /users:
x-swagger-router-controller: user.controller
post:
description: Create a user account
operationId: createUser
produces:
- application/json
parameters:
- name: user
in: body
description: Your requested username
required: true
schema:
$ref: "#/definitions/NewUser"
responses:
"201":
description: "created user"
schema:
$ref: "#/definitions/NewUserResponse"
"400":
description: Bad request (duplicate user)
schema:
$ref: "#/definitions/ErrorResponse"
default:
description: "unexpected error"
schema:
$ref: "#/definitions/ErrorResponse"
// user.controller.js
exports.createUser = function(req, res) { }
@aroach@CiscoDevNetdeveloper.cisco.com
├── app.js
├── config
│ ├── README.md
│ ├── default.yaml
│ └── seeds
│ └── basic.js
├── env_make
├── Makefile
├── package.json
├── static
│ ├── css
│ │ └── main.css
│ └── howto.md
└── test
└── api
├── controllers
│ ├── README.md
│ ├── authenticate.js
│ └── health.js
└── helpers
└── README.md
// app.js
var express = require('express');
app.use(express.static('static'));
@aroach@CiscoDevNetdeveloper.cisco.com
@aroach@CiscoDevNetdeveloper.cisco.com
• Swagger-node provides fast REST API creation
• Prototyping, mocking
• Spec-first development was an adjustment
• Container-based workflows made deployment
super simple
Takeaways
@aroach@CiscoDevNetdeveloper.cisco.com
Helpful Links
• https://communities.cisco.com/people/asroach/blog/2016/09/19/building-the-devnet-api-
scavenger-hunt
• https://communities.cisco.com/people/asroach/blog/2016/08/11/creating-a-cisco-spark-
membership-via-google-forms
• https://github.com/swagger-api/swagger-node
• https://github.com/CiscoDevNet/rest-api-swagger
• https://scotch.io/tutorials/authenticate-a-node-js-api-with-json-web-tokens
• http://blog.mongodb.org/post/32866457221/password-authentication-with-mongoose-part-1
• http://www.itnotes.de/docker/development/tools/2014/08/31/speed-up-your-docker-workflow-
with-a-makefile/
• http://sahatyalkabov.com/how-to-implement-password-reset-in-nodejs/
• https://marcqualie.com/2015/07/docker-dotenv
@aroach@CiscoDevNetdeveloper.cisco.com
Thank you!
Building a REST API Microservice for the DevNet API Scavenger Hunt

Building a REST API Microservice for the DevNet API Scavenger Hunt