Conociendo JSON API   

Kattya Cuevas

Backend developer

Ruby: 4 years

Python: 1 year

 

API

  • Application Programming Interfaces 
  • Conjunto de procedimientos para ser usados
    por otro software
  • Interactuar con servicios web
  • Actualmente se le dice API REST

API REST

  • Usa el estándar HTTP
  • Métodos o procesos estándar (GET, POST,
    PUT, DELETE)
  • Es independiente del lenguaje

Recursos

  • A lo que queremos acceder, modificar o borrar
  • Se representan a través de URI
  • No son acciones
  • Filtros y otras operaciones

HTTP Status Code

  • 1xx: Informativas
  • 2xx: Correctas
  • 3xx: Redirección
  • 4xx: Error del cliente
  • 5xx: Error del servidor

Representaciones

  • Formatos en que se recibe la respuesta
  • Los más comunes son XML y JSON
  • Se envían a través de la solicitud
    Header Content-Type

JSON

  • Formato de texto para el intercambio de datos
  • Tipos de datos disponibles: números, cadenas, booleanos, null, array, objetos.
{
    "firstName": "Kattya",
    "lastName": "Cuevas",
    "age": 23,
    "isAdmin": False,
    "actualJob": null,
    "previousJob": [
        {
            "position": "Backend developer",
            "company": "Platzi"
        },
        {
            "position": "Software developer",
            "company": "devAcademy"
        }
    ]
}

Especificaciones

Top level

DEBE PUEDE
- data
- errors
- meta
- jsonapi
- links (self, related)
- included 

Resource object

DEBE PUEDE
- id
- type
- attributes
- relationships
- links
- meta 

Sorting

/people?sort=page
/people?sort=age,-name

Pagination

/articles?page[number]=3&page[size]=10
first, last, prev, next
{
  "data": [{
    "type": "articles",
    "id": "1",
    "attributes": {
      "title": "JSON API paints my bikeshed!"
    },
    "links": {
      "self": "http://example.com/articles/1"
    },
    "relationships": {
      "author": {
        "links": {
          "self": "http://example.com/articles/1/relationships/author",
          "related": "http://example.com/articles/1/author"
        },
        "data": { "type": "people", "id": "9" }
      },
      "comments": {
        "links": {
          "self": "http://example.com/articles/1/relationships/comments",
          "related": "http://example.com/articles/1/comments"
        },
        "data": [
          { "type": "comments", "id": "5" },
          { "type": "comments", "id": "12" }
        ]
      }
    }
  }],
  "included": [{
    "type": "people",
    "id": "9",
    "attributes": {
      "first-name": "Dan",
      "last-name": "Gebhardt",
      "twitter": "dgeb"
    },
    "links": {
      "self": "http://example.com/people/9"
    }
  }, {
    "type": "comments",
    "id": "5",
    "attributes": {
      "body": "First!"
    },
    "relationships": {
      "author": {
        "data": { "type": "people", "id": "2" }
      }
    },
    "links": {
      "self": "http://example.com/comments/5"
    }
  }, {
    "type": "comments",
    "id": "12",
    "attributes": {
      "body": "I like XML better"
    },
    "relationships": {
      "author": {
        "data": { "type": "people", "id": "9" }
      }
    },
    "links": {
      "self": "http://example.com/comments/12"
    }
  }]
}

Ruby on Rails

$ rails new json-api --api
$ cd json-api

Crear un nuevo proyecto e ingresar en la carpeta

Crear scaffold con la estructura de datos básica de un blog

$ rails generate scaffold user first_name:string last_name:string
$ rails generate scaffold post title:string body:text user:references
$ rails generate scaffold comment body:text user:references post:references
$ rake db:migrate

Ruby on Rails

class User < ApplicationRecord
  has_many :posts
  has_many :comments
end

Editar los modelos. Primero en /app/models/user.rb

class Post < ApplicationRecord
  belongs_to :user
  has_many :comments
end

Luego en /app/models/post.rb

Ruby on Rails

# Users
user1 = User.create(first_name: 'Juan', last_name: 'Ramirez')
user2 = User.create(first_name: 'Maria', last_name: 'Perez')

# Posts
post1 = user1.posts.create(title: 'Primero', body: 'Este es el primero')
post2 = user1.posts.create(title: 'Segundo', body: 'Este es el segundo')
post3 = user2.posts.create(title: 'Tercero', body: 'Este es el tercero')
post4 = user2.posts.create(title: 'Cuarto', body: 'Este es el cuarto')

# Comments
post1.comments.create(body: "No se entiende", user: user2)
post2.comments.create(body: "Muy buena explicación", user: user2)
post3.comments.create(body: "No se entiende", user: user1)
post4.comments.create(body: "Muy buena explicación", user: user1)

Llenamos con un poco de datos nuestro ejemplo. Para ello, editamos en /db/seeds.rb

Para que se ejecute, corremos en la terminal

$ rake db:seed

Ruby on Rails

Iniciamos el servidor local con rails server e ingresamos a las rutas creadas

Ruby on Rails

gem 'active_model_serializers', '~> 0.10.0'

Vamos a serializar el json generado. Agregamos una gema en el Gemfile

Corremos "bundle install" para que se agregue la gema y creamos los serializers

$ rails generate serializer user
$ rails generate serializer post
$ rails generate serializer comment
class UserSerializer < ActiveModel::Serializer
  attributes :id, :first_name, :say_hello

  has_many :posts

  def say_hello
    "Hello #{object.first_name}"
  end
end

Editamos el user_serializer para mostrar más datos del usuario

Ruby on Rails

ActiveModel::Serializer.config.adapter = :json_api

Creamos un archivo llamado "active_model_serializers.rb" en /config/initializers y agregamos

Si van de nuevo a la lista de usuarios, verán el cambio

Ruby on Rails

Rails.application.routes.default_url_options = {
  host: 'localhost',
  port: 3000
}

Para agregar los links en los objectos, configuramos la URL por defecto en /config/enviroments/development.rb agregando:

link(:self) { user_url(object) }

Ahora editamos el user_serializer, para agregar los links de referencia:

Conociendo JSON api

By Kattya Cuevas Montes

Conociendo JSON api

  • 197