Introduction

If you are using Ruby – communicating with Fortnox is a piece of cake using raw Net::HTTP or the HTTParty gem. In these examples we will look at how to use both methods.

Before we get started you need to have you Access-Token and Client-Secret available. Didn’t get yours yet? Sign up as a Developer using this form.

In the following examples we will assume that you have set up three constants, BASE_URL, ACCESS_TOKEN and CLIENT_SECRET, to hold you login information, like this:

BASE_URL = 'http://api.fortnox.se/3'
CLIENT_SECRET = 'your-client-secret-here'
ACCESS_TOKEN = 'your-access-token-here'

You can of course use whatever method you like to hold your secrets. In Rails 4.1 there is the secrets.yaml file, another good general solution is to use the Dotenv gem to read the values from environment variables.

You can also download the source code for these examples from our github repository: https://github.com/FortnoxAB/api-example-ruby. And feel free to contribute there by sending us code for other ruby HTTP libraries!

Net::HTTP

Net::HTTP is Ruby’s standard library implementation for HTTP. It’s included in your Ruby distribution and allows you to go HTTP requests without depending on any external libraries.

That said it’s a bit clunky to use. But it does work fine and below I’ll show you how to use it. If you don’t like the verbose syntax and wouldn’t mind including an external gem I recommend you scroll down to the section about John Nunemaker excellent HTTParty gem.

Helper

To make our life easier we create a set of helper methods to remove all the repetition between the different calls. We start by defining the overall wrapper that does the heavy lifting and sets up almost all of Net::HTTP for us.

require 'uri'
require 'net/https'
require 'json'

def execute_request( endpoint, body = nil )
  uri = URI.parse( BASE_URL + endpoint )
  http = Net::HTTP.new( uri.host, uri.port )
  http.use_ssl = true
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE

  request = yield( uri )

  request[ 'Accept' ] = 'application/json'
  request[ 'Client-Secret' ] = CLIENT_SECRET
  request[ 'Access-Token' ] = ACCESS_TOKEN

  if( body )
    request[ 'Content-Type' ] = 'application/json'
    request.body = body.to_json
  end

  response = http.request( request )
  JSON.parse( response.body ) if response.body
end

For each request method we will need a further wrapper that simply takes the uri object we created and return a Net::HTTP::Request object of the correct type.

For help on extending the above helper into something more useful for you have a look at the examples of the Net::HTTP cheat sheet on Github.

GET

First we create a small helper function that uses execute_request and provides it with a GET request object.

def get( endpoint )
  execute_request( endpoint ) do |uri|
    Net::HTTP::Get.new( uri.request_uri )
  end
end

To echo a count of all articles you can then use the get method.

hash = get( '/articles' )
number_of_articles = hash[ 'Articles' ].length
puts "Received #{ number_of_articles } articles..." # => Received 37 articles...

That will print the number of articles you received back from the server.

To get a single article you use the same helper but specify what product number  you would like to get in the argument

article = get( '/articles/42' ) # => {"Article"=>{"@url"=>"https://api.fortnox.se/3/articles/42", ... }}
puts "Article 42: #{ article }"

POST

First we create a small helper function that uses execute_request and provides it with a POST request object.

def post( endpoint, data )
  execute_request( endpoint, data ) do |uri|
    Net::HTTP::Post.new( uri.request_uri )
  end
end

You can then create new resources by calling post with a list endpoint

post( '/articles', { "Article" => { "Description" => "My article description" }} ) # => {"Article"=>{"@url"=>"https://api.fortnox.se/3/articles/43", ... }}

PUT

First we create a small helper function that uses execute_request and provides it with a PUT request object.

def put( endpoint, data )
  execute_request( endpoint, data ) do |uri|
    Net::HTTP::Put.new( uri.request_uri )
  end
end

You can then update resources by calling put with a single resource endpoint

put( '/articles/42', { "Article" => { "Description" => "My updated description" }} ) # => {"Article"=>{"@url"=>"https://api.fortnox.se/3/articles/43", ... }}

DELETE

First we create a small helper function that uses execute_request and provides it with a DELETE request object.

def delete( endpoint )
  execute_request( endpoint ) do |uri|
    Net::HTTP::Delete.new( uri.request_uri )
  end
end

You can then delete resources by calling delete with a single resource endpoint

delete( '/articles/42' ) # => nil

HTTParty

Helper

You could use HTTParty without any additional helpers. A call would then look something like this

require 'httparty'
require 'json'

HTTParty.put(
  BASE_URL + '/articles/42',
  {
    body: {'Article' => { 'Description' => 'My updated description' }}.to_json,
    headers: {
      'Accept' => 'application/json',
      'Client-Secret' => CLIENT_SECRET,
      'Access-Token' => ACCESS_TOKEN,
      'Content-Type' => 'application/json',
    }
  }
)

But to reduce the amount of repetition in our code we will write a small wrapper class for HTTParty

require 'httparty'
require 'json'

class Fortnox
  include HTTParty

  base_uri BASE_URL
  headers 'Accept' => 'application/json', 'Client-Secret' => CLIENT_SECRET, 'Access-Token' => ACCESS_TOKEN

  def self.post( endpoint, body )
    options = { body: body.to_json, headers: { 'Content-Type' => 'application/json' }}
    super endpoint, options
  end

  def self.put( endpoint, body )
    options = { body: body.to_json, headers: { 'Content-Type' => 'application/json' }}
    super endpoint, options
  end
end

For more examples of using the HTTParty library to help you extend the above micro framework to something that works as you want have a look at the HTTParty examples on Github.

GET

To echo a count of all articles you can then use the Fortnox.get method.

hash = Fortnox.get( '/articles' )
number_of_articles = hash[ 'Articles' ].length
puts "Received #{ number_of_articles } articles..." # => Received 37 articles...

That will print the number of articles you received back from the server.

To get a single article you use the same helper but specify what product number  you would like to get in the argument

article = Fortnox.get( '/articles/42' ) # => #<HTTParty::Response:0x7fe3c18b6af8 parsed_response={"Article"=>{"@url"=>"https://api.fortnox.se/3/articles/42", ... }}>
puts "Article 42: #{ article.to_hash }" # => {"Article"=>{"@url"=>"https://api.fortnox.se/3/articles/42", ... }}

POST

You can create new resources by calling Fortnox.post with a list endpoint

Fortnox.post( '/articles', { "Article" => { "Description" => "My article description" }} ) # => #<HTTParty::Response:0x7fe3c0a2f250 parsed_response={"Article"=>{"@url"=>"https://api.fortnox.se/3/articles/43", ... }}>

PUT

You can update resources by calling Fortnox.put with a single resource endpoint

Fortnox.put( '/articles/43', { "Article" => { "Description" => "My updated description" }} ) # => #<HTTParty::Response:0x7fe3c20693b8 parsed_response={"Article"=>{"@url"=>"https://api.fortnox.se/3/articles/43", ... }}>

DELETE

You can delete resources by calling Fortnox.delete with a single resource endpoint

Fortnox.delete( '/articles/43' ) # => #<HTTParty::Response:0x10 parsed_response=nil, ... >

Wrapper libraries

If you prefer to work with something a bit more abstracted than raw API calls there is a third party wrapper library being built that abstracts this all away and gives you a nice, object oriented interface to the models and relations without having to worry about headers, content types or parsing. Have a look at the Fortnox::API gem at Github for more details on features and status of the project.