-
Notifications
You must be signed in to change notification settings - Fork 0
20 API Introduction
We want to be able to get at our notes programmatically through other applications—say, a different web app or a mobile app. Rails gives you all the pieces you need to do that with a minimum of pain.
Because Rails encourages use of a RESTful pattern for resource-based controllers with standardized CRUD actions, it makes it easy to accept & return JSON, or even XML.
Looking back at elevenpeeps, we can see that the scaffold generator takes advantage of this built-in functionality. If you were to make requests to http://localhost:3000/chirps.json, you should see a JSON response in your browser.
If viewing JSON in a web browser is something you do often, try installing JSON Formatter for Chrome.
If you take a look back at the scaffolded chirps_controller.rb
in ElevenPeeps, you'll notice that the create
, update
, and destroy
actions each have a respond_to
block, and some of the actions have .json.jbuilder
views.
Let's take a look at the source in elevenpeeps for a minute to see what it's doing.
app/controllers/chirps_controller
class ChirpsController < ApplicationController
before_action :set_chirp, only: [:show, :edit, :update, :destroy]
# GET /chirps
# GET /chirps.json
def index
@chirps = Chirp.all
end
# GET /chirps/1
# GET /chirps/1.json
def show
end
# GET /chirps/new
def new
@chirp = Chirp.new
end
# GET /chirps/1/edit
def edit
end
# POST /chirps
# POST /chirps.json
def create
@chirp = Chirp.new(chirp_params)
respond_to do |format|
if @chirp.save
format.html { redirect_to @chirp, notice: 'Chirp was successfully created.' }
format.json { render :show, status: :created, location: @chirp }
else
format.html { render :new }
format.json { render json: @chirp.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /chirps/1
# PATCH/PUT /chirps/1.json
def update
respond_to do |format|
if @chirp.update(chirp_params)
format.html { redirect_to @chirp, notice: 'Chirp was successfully updated.' }
format.json { render :show, status: :ok, location: @chirp }
else
format.html { render :edit }
format.json { render json: @chirp.errors, status: :unprocessable_entity }
end
end
end
# DELETE /chirps/1
# DELETE /chirps/1.json
def destroy
@chirp.destroy
respond_to do |format|
format.html { redirect_to chirps_url, notice: 'Chirp was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_chirp
@chirp = Chirp.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def chirp_params
params.require(:chirp).permit(:content)
end
end
It's great to be able to have different responses to the same controller action/route, but if you need to have a standardized interface for third-party integrations, then it's best not to have API code mixed in with your web application code.
As we go through our codebase to make future changes and enhancements, it becomes hard to keep ourselves from breaking or changing our API. Even if we manage (with help from automated tests) never to break that API, we can still end up with little islands of code we don't like that must be there just to avoid breaking the API.
We're not going to follow the scaffolded example when writing the API for ElevenNote.