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.