portaldacalheta.pt
  • Principal
  • Design De Marque
  • Personnes Et Équipes Produit
  • Innovation
  • Kpi Et Analyses
Interface Web

Tutoriel Grape Gem: Comment créer une API de type REST dans Ruby



Comme Développeurs Ruby On Rails , nous avons souvent besoin d'étendre nos applications avec des points de terminaison d'API pour prendre en charge JavaScript Internet riche clients ou applications natives iPhone et Android. Il existe également des cas où le seul objectif de l'application est de servir les applications iPhone / Android via un JSON FEU.

Dans ce didacticiel, je montre comment utiliser Grain de raisin - un micro-framework d'API de type REST pour Ruby - pour créer un support backend dans Rails pour une API JSON. Le raisin est conçu pour fonctionner comme un moteur à crémaillère montable à complément nos applications web, sans interférant avec eux.



API Web dans Ruby utilisant Grape Gem



Cas d'utilisation

Le cas d'utilisation sur lequel nous allons nous concentrer pour ce didacticiel est une application capable de capturer et de revoir des sessions de programmation en binôme. L'application elle-même sera écrite pour iOS dans ObjectiveC et devra communiquer avec un service backend pour stocker et récupérer les données. Notre objectif dans ce didacticiel est la création d'un service de backend robuste et sécurisé prenant en charge une API JSON.



L'API prendra en charge les méthodes pour:

  • Connexion au système
  • Interroger les révisions de session de programmation de paires

REMARQUE: En plus de fournir la possibilité d'interroger les revues de session de programmation en binôme, la véritable API devrait également fournir une fonction pour soumettre des revues de programmation en binôme pour inclusion dans la base de données. Étant donné que la prise en charge de cela via l'API dépasse le cadre de ce didacticiel, nous supposerons simplement que la base de données a été remplie avec un échantillon de revues de programmation par paires.



Les principales exigences techniques comprennent:

  • Chaque appel d'API doit renvoyer un JSON valide
  • Chaque appel d'API échoué doit être enregistré avec un contexte et des informations adéquats pour être ensuite reproductible, et débogué si nécessaire

Aussi, puisque notre application devra servir des clients externes, nous devrons nous préoccuper de la sécurité. À cette fin:



  • Chaque demande doit être limitée à un petit sous-ensemble de développeurs que nous suivons
  • Toutes les demandes (autres que la connexion / l'inscription) doivent être authentifiées

Développement piloté par les tests et RSpec

Nous utiliserons Développement piloté par les tests (TDD) comme notre approche de développement logiciel pour aider à garantir le comportement déterministe de notre API.

À des fins de test, nous utiliserons RSpec , un framework de test bien connu dans la communauté RubyOnRails. Je ferai donc référence dans cet article à des «spécifications» plutôt qu'à des «tests».



À méthodologie de test complète comprend à la fois des tests «positifs» et «négatifs». Les spécifications négatives spécifieront, par exemple, comment le point de terminaison de l'API se comporte si certains paramètres sont manquants ou incorrects. Les spécifications positives couvrent les cas où l'API est invoquée correctement.

Commencer

Jetons les bases de notre API backend. Tout d'abord, nous devons créer une nouvelle application de rails:



rails new toptal_grape_blog

Ensuite, nous installerons RSpec en ajoutant rspec-rails dans notre gemfile:

group :development, :test do gem 'rspec-rails', '~> 3.2' end

Ensuite, à partir de notre ligne de commande, nous devons exécuter:

rails generate rspec:install

Nous pouvons également tirer parti de certains logiciels open source existants pour notre cadre de test. Plus précisément:

  • Devise - une solution d'authentification flexible pour Rails basée sur Directeur
  • factory_girl_rails - fournit l'intégration de Rails pour ouvrière , une bibliothèque pour configurer des objets Ruby comme données de test

Étape 1: Ajoutez-les à notre gemfile:

... gem 'devise' ... group :development, :test do ... gem 'factory_girl_rails', '~> 4.5' ... end

Étape 2: Générez un modèle utilisateur, initialisez le devise gem et ajoutez-le au modèle utilisateur (cela permet à la classe utilisateur d'être utilisée pour l'authentification).

rails g model user rails generate devise:install rails generate devise user

Étape 3: Incluez le factory_girl méthode de syntaxe dans notre rails_helper.rb fichier afin d'utiliser la version abrégée de la création d'utilisateur dans nos spécifications:

RSpec.configure do |config| config.include FactoryGirl::Syntax::Methods

Étape 4: Ajoutez la gemme de raisin à notre DSL et installez-la:

gem 'grape' bundle

Cas d'utilisation et spécifications de connexion utilisateur

Notre backend devra prendre en charge une capacité de connexion de base. Créons le squelette de notre login_spec, en supposant qu'une demande de connexion valide se compose d'une adresse e-mail et d'un mot de passe enregistrés:

require 'rails_helper' describe '/api/login' do context 'negative tests' do context 'missing params' do context 'password' do end context 'email' do end end context 'invalid params' do context 'incorrect password' do end context 'with a non-existent login' do end end end context 'positive tests' do context 'valid params' do end end end

Si l’un des paramètres est manquant, le client doit recevoir un code d’état de retour HTTP de 400 (c’est-à-dire une demande incorrecte), ainsi qu’un message d’erreur indiquant «e-mail est manquant» ou «mot de passe manquant».

Pour notre test, nous créerons un utilisateur valide et définirons l'adresse e-mail et le mot de passe de l'utilisateur comme paramètres d'origine pour cette suite de tests. Ensuite, nous personnaliserons ce hachage de paramètre pour chaque spécification spécifique en omettant le mot de passe / e-mail ou en le remplaçant.

Créons l'utilisateur et le hachage du paramètre au début de la spécification. Nous mettrons ce code après le bloc describe:

describe '/api/login' do let(:email) { user.email } let(:password) { user.password } let!(:user) { create :user } let(:original_params) { { email: email, password: password } } let(:params) { original_params } ...

Nous pouvons ensuite étendre notre contexte «paramètres manquants» / «mot de passe» comme suit:

let(:params) { original_params.except(:password) } it_behaves_like '400' it_behaves_like 'json result' it_behaves_like 'contains error msg', 'password is missing'

Mais au lieu de répéter les attentes dans les contextes «e-mail» et «mot de passe», nous pouvons utiliser les mêmes exemples partagés que les attentes. Pour cela, nous devons décommenter cette ligne dans notre rails_helper.rb fichier:

Dir[Rails.root.join('spec/support/**/*.rb')].each

Nous devons ensuite ajouter les 3 exemples partagés RSpec dans spec/support/shared.rb:

RSpec.shared_examples 'json result' do specify 'returns JSON' do api_call params expect { JSON.parse(response.body) }.not_to raise_error end end RSpec.shared_examples '400' do specify 'returns 400' do api_call params expect(response.status).to eq(400) end end RSpec.shared_examples 'contains error msg' do |msg| specify 'error msg is #{msg}' do api_call params json = JSON.parse(response.body) expect(json['error_msg']).to eq(msg) end end

Ces exemples partagés appellent le api_call méthode qui nous permet de définir le point de terminaison de l'API une seule fois dans notre spécification (conformément à la Principe DRY ). Nous définissons cette méthode comme suit:

describe '/api/login' do ... def api_call *params post '/api/login', *params end ...

Nous devrons également personnaliser l'usine pour notre utilisateur:

FactoryGirl.define do factory :user do password 'Passw0rd' password_confirmation sequence(:email) { |n| 'test#{n}@example.com' } end end

Et enfin, avant d'exécuter nos spécifications, nous devons exécuter nos migrations:

rake db:migrate

Gardez à l'esprit, cependant, que les spécifications échoueront toujours à ce stade, car nous n'avons pas encore mis en œuvre notre point de terminaison d'API. C’est la prochaine.

Implémentation du point de terminaison de l'API de connexion

Pour commencer, nous allons écrire un squelette vide pour notre API de connexion (app/api/login.rb):

class Login

Ensuite, nous allons écrire une classe d'agrégation qui agrège les points de terminaison de l'API (app/api/api.rb):

class API

OK, maintenant nous pouvons monter notre API dans les routes:

Rails.application.routes.draw do ... mount API => '/' ... end

Ajoutons maintenant le code pour vérifier les paramètres manquants. Nous pouvons ajouter ce code à api.rb en sauvant de Grape::Exceptions::ValidationErrors.

rescue_from Grape::Exceptions::ValidationErrors do |e| rack_response({ status: e.status, error_msg: e.message, }.to_json, 400) end

Pour le mot de passe invalide, nous vérifierons si le code de réponse http est 401, ce qui signifie un accès non autorisé. Ajoutons ceci au contexte du 'mot de passe incorrect':

let(:params) { original_params.merge(password: 'invalid') } it_behaves_like '401' it_behaves_like 'json result' it_behaves_like 'contains error msg', 'Bad Authentication Parameters'

La même logique est ensuite ajoutée au contexte «avec une connexion inexistante».

Nous implémentons ensuite la logique qui gère les tentatives d'authentification invalides dans notre login.rb comme suit:

post do user = User.find_by_email params[:email] if user.present? && user.valid_password?(params[:password]) else error_msg = 'Bad Authentication Parameters' error!({ 'error_msg' => error_msg }, 401) end end

À ce stade, toutes les spécifications négatives de l'API de connexion se comporteront correctement, mais nous devons toujours prendre en charge les spécifications positives de notre API de connexion. Notre spécification positive s'attend à ce que le point de terminaison renvoie un code de réponse HTTP de 200 (c'est-à-dire un succès) avec JSON valide et un jeton valide:

it_behaves_like '200' it_behaves_like 'json result' specify 'returns the token as part of the response' do api_call params expect(JSON.parse(response.body)['token']).to be_present end

Ajoutons également l'espérance du code de réponse 200 à spec/support/shared.rb:

RSpec.shared_examples '200' do specify 'returns 200' do api_call params expect(response.status).to eq(200) end end

En cas de connexion réussie, nous allons renvoyer le premier jeton d'authentification valide avec l'e-mail de l'utilisateur dans ce format:

{‘email’:, ‘token’:}

S'il n'y a pas encore de jeton, nous en créerons un pour l'utilisateur actuel:

... if user.present? && user.valid_password?(params[:password]) token = user.authentication_tokens.valid.first || AuthenticationToken.generate(user) status 200 else ...

Pour que cela fonctionne, nous aurons besoin d'un AuthenticationToken classe qui appartient à l'utilisateur. Nous allons générer ce modèle, puis exécuter la migration correspondante:

rails g model authentication_token token user:references expires_at:datetime rake db:migrate

Nous devons également ajouter l'association correspondante à notre modèle utilisateur:

class User

Ensuite, nous ajouterons la portée valide au AuthenticationToken classe:

class AuthenticationToken { where (expires_at > Time.zone.now) } end

Notez que nous avons utilisé la syntaxe Ruby dans le where déclaration. Ceci est rendu possible par notre utilisation du squeel gemme qui active la prise en charge de la syntaxe Ruby dans les requêtes activerecord.

Pour un utilisateur validé, nous allons créer une entité que nous appellerons 'utilisateur avec entité de jeton', en tirant parti des fonctionnalités de grape-entity gemme .

Écrivons la spécification de notre entité et mettons-la dans user_with_token_entity_spec.rb fichier:

require 'rails_helper' describe Entities::UserWithTokenEntity do describe 'fields' do subject(:subject) { Entities::UserWithTokenEntity } specify { expect(subject).to represent(:email)} let!(:token) { create :authentication_token } specify 'presents the first available token' do json = Entities::UserWithTokenEntity.new(token.user).as_json expect(json[:token]).to be_present end end end

Ajoutons ensuite les entités à user_entity.rb:

module Entities class UserEntity

Et enfin, ajoutez une autre classe à user_with_token_entity.rb:

module Entities class UserWithTokenEntity

Puisque nous ne voulons pas que les jetons restent valables indéfiniment, nous les faisons expirer après un jour:

FactoryGirl.define do factory :authentication_token do token 'MyString' expires_at 1.day.from_now user end end

Une fois tout cela fait, nous pouvons maintenant retourner le format JSON attendu avec notre nouvellement écrit UserWithTokenEntity:

... user = User.find_by_email params[:email] if user.present? && user.valid_password?(params[:password]) token = user.authentication_tokens.valid.first || AuthenticationToken.generate(user) status 200 present token.user, with: Entities::UserWithTokenEntity else ...

Cool. Maintenant, toutes nos spécifications sont acceptées et les exigences fonctionnelles du point de terminaison de l'API de connexion de base sont prises en charge.

Pair Programming Session Review API Endpoint: Prise en main

Notre backend devra autoriser autorisé les développeurs qui se sont connectés pour interroger les revues de sessions de programmation par paires.

Notre nouveau point de terminaison d'API sera monté sur /api/pair_programming_session et renverra les avis appartenant à un projet. Commençons par écrire un squelette de base pour cette spécification:

require 'rails_helper' describe '/api' do describe '/pair_programming_session' do def api_call *params get '/api/pair_programming_sessions', *params end context 'invalid params' do end context 'valid params' do end end end

Nous écrirons également un point de terminaison API vide correspondant (app/api/pair_programming_sessions.rb):

class PairProgrammingSessions

Montons ensuite notre nouvelle API (app/api/api.rb):

... mount Login mount PairProgrammingSessions end

Développons les spécifications et le point de terminaison de l'API en fonction des exigences un par un.

Pair Programming Session Review API Endpoint: Validation

L'une de nos exigences de sécurité non fonctionnelles les plus importantes était de restreindre l'accès à l'API à un petit sous-ensemble de développeurs que nous suivons. Précisons donc que:

... def api_call *params get '/api/pair_programming_sessions', *params end let(:token) { create :authentication_token } let(:original_params) { { token: token.token} } let(:params) { original_params } it_behaves_like 'restricted for developers' context 'invalid params' do ...

Ensuite, nous allons créer un shared_example dans notre shared.rb pour confirmer que la demande provient de l'un de nos développeurs enregistrés:

RSpec.shared_examples 'restricted for developers' do context 'without developer key' do specify 'should be an unauthorized call' do api_call params expect(response.status).to eq(401) end specify 'error code is 1001' do api_call params json = JSON.parse(response.body) expect(json['error_code']).to eq(ErrorCodes::DEVELOPER_KEY_MISSING) end end end

Nous devrons également créer un ErrorCodes classe (dans app/models/error_codes.rb):

module ErrorCodes DEVELOPER_KEY_MISSING = 1001 end

Puisque nous prévoyons que notre API se développera à l'avenir, nous allons implémenter un authorization_helper qui peut être réutilisé sur tous les points de terminaison d'API dans l'application pour restreindre l'accès aux développeurs enregistrés uniquement:

class PairProgrammingSessions

Nous allons définir la méthode restrict_access_to_developers dans le ApiHelpers::AuthenticationHerlper module (app/api/api_helpers/authentication_helper.rb). Cette méthode vérifiera simplement si la clé Authorization sous les en-têtes contient un ApiKey valide. (Chaque développeur souhaitant accéder à l'API aura besoin d'un ApiKey valide. Cela peut être fourni par un administrateur système ou via un processus d'enregistrement automatisé, mais ce mécanisme dépasse le cadre de cet article.)

module ApiHelpers module AuthenticationHelper def restrict_access_to_developers header_token = headers['Authorization'] key = ApiKey.where{ token == my{ header_token } } Rails.logger.info 'API call: #{headers} With params: #{params.inspect}' if ENV['DEBUG'] if key.blank? error_code = ErrorCodes::DEVELOPER_KEY_MISSING error_msg = 'please aquire a developer key' error!({ :error_msg => error_msg, :error_code => error_code }, 401) # LogAudit.new({env:env}).execute end end end end

Nous devons ensuite générer le modèle ApiKey et exécuter les migrations: rails g model api_key token rake db: migrate

Ceci fait, dans notre spec/api/pair_programming_spec.rb nous pouvons vérifier si l'utilisateur est authentifié:

... it_behaves_like 'restricted for developers' it_behaves_like 'unauthenticated' ...

Définissons également un unauthenticated exemple partagé qui peut être réutilisé dans toutes les spécifications (spec/support/shared.rb):

RSpec.shared_examples 'unauthenticated' do context 'unauthenticated' do specify 'returns 401 without token' do api_call params.except(:token), developer_header expect(response.status).to eq(401) end specify 'returns JSON' do api_call params.except(:token), developer_header json = JSON.parse(response.body) end end end

Cet exemple partagé nécessite le jeton dans l'en-tête du développeur, ajoutons-le donc à nos spécifications (spec/api/pair_programming_spec.rb):

... describe '/api' do let(:api_key) { create :api_key } let(:developer_header) { {'Authorization' => api_key.token} } ...

Maintenant, dans notre app/api/pair_programming_session.rb, essayons d'authentifier l'utilisateur:

... class PairProgrammingSessions

Implémentons le authenticate! méthode dans le AuthenticationHelper (app/api/api_helpers/authentication_helper.rb):

... module ApiHelpers module AuthenticationHelper TOKEN_PARAM_NAME = :token def token_value_from_request(token_param = TOKEN_PARAM_NAME) params[token_param] end def current_user token = AuthenticationToken.find_by_token(token_value_from_request) return nil unless token.present? @current_user ||= token.user end def signed_in? !!current_user end def authenticate! unless signed_in? AuditLog.create data: 'unauthenticated user access' error!({ :error_msg => 'authentication_error', :error_code => ErrorCodes::BAD_AUTHENTICATION_PARAMS }, 401) end end ...

(Notez que nous devons ajouter le code d'erreur BAD_AUTHENTICATION_PARAMS à notre classe ErrorCodes.)

Ensuite, spécifions ce qui se passe si le développeur appelle l'API avec un jeton non valide. Dans ce cas, le code retour sera 401 signalant un «accès non autorisé». Le résultat doit être JSON et un auditable doit être créé. Nous ajoutons donc ceci à spec/api/pair_programming_spec.rb:

... context 'invalid params' do context 'incorrect token' do let(:params) { original_params.merge(token: 'invalid') } it_behaves_like '401' it_behaves_like 'json result' it_behaves_like 'auditable created' it_behaves_like 'contains error msg', 'authentication_error' it_behaves_like 'contains error code', ErrorCodes::BAD_AUTHENTICATION_PARAMS end end ...

Nous ajouterons les exemples partagés «auditable created», «contains error code» et «contains error msg» à spec/support/shared.rb:

... RSpec.shared_examples 'contains error code' do |code| specify 'error code is #{code}' do api_call params, developer_header json = JSON.parse(response.body) expect(json['error_code']).to eq(code) end end RSpec.shared_examples 'contains error msg' do |msg| specify 'error msg is #{msg}' do api_call params, developer_header json = JSON.parse(response.body) expect(json['error_msg']).to eq(msg) end end RSpec.shared_examples 'auditable created' do specify 'creates an api call audit' do expect do api_call params, developer_header end.to change{ AuditLog.count }.by(1) end end ...

Nous devons également créer un modèle audit_log:

rails g model audit_log backtrace data user:references rake db:migrate

Pair Programming Session Review API Endpoint: retour des résultats

Pour un utilisateur authentifié et autorisé, un appel à ce point de terminaison d'API doit renvoyer un ensemble de révisions de sessions de programmation par paires regroupées par projet. Modifions notre spec/api/pair_programming_spec.rb en conséquence:

... context 'valid params' do it_behaves_like '200' it_behaves_like 'json result' end ...

Ceci spécifie qu'une demande soumise avec api_key valide | et les paramètres valides renvoie un code HTTP de 200 (c'est-à-dire succès) et que le résultat est renvoyé sous la forme d'un JSON valide.

Nous allons interroger puis renvoyer au format JSON ces sessions de programmation par paires où l'un des participants est l'utilisateur actuel (app/api/pair_programming_sessions.rb):

... get do sessions = PairProgrammingSession.where{(host_user == my{current_user}) | (visitor_user == my{current_user})} sessions = sessions.includes(:project, :host_user, :visitor_user, reviews: [:code_samples, :user] ) present sessions, with: Entities::PairProgrammingSessionsEntity end ...

Les sessions de programmation par paires sont modélisées comme suit dans la base de données:

qu'est-ce que s corp et c corp
  • Relation 1-à-plusieurs entre les projets et les sessions de programmation en binôme
  • Relation 1-à-plusieurs entre les sessions de programmation en binôme et les révisions
  • Relation 1-à-plusieurs entre les critiques et les exemples de code

Générons les modèles en conséquence, puis exécutons les migrations:

rails g model project name rails g model pair_programming_session project:references host_user:references visitor_user:references rails g model review pair_programming_session:references user:references comment rails g model code_sample review:references code:text rake db:migrate

Ensuite, nous devons modifier notre PairProgrammingSession et Review classes pour contenir les has_many les associations:

class Review

REMARQUE: Dans des circonstances normales, je générerais ces classes en écrivant d'abord des spécifications pour elles, mais puisque cela dépasse le cadre de cet article, je vais sauter cette étape.

Nous devons maintenant écrire les classes qui vont transformer nos modèles en leurs représentations JSON (appelées entités de raisin dans la terminologie du raisin). Pour plus de simplicité, nous utiliserons un mappage 1-to-1 entre les modèles et les entités de raisin.

Nous commençons par exposer les code champ du CodeSampleEntity (dans api/entities/code_sample_entity.rb):

module Entities class CodeSampleEntity

Ensuite, nous exposons le user et associés code_samples en réutilisant le UserEntity déjà défini | et le CodeSampleEntity:

module Entities class ReviewEntity

Nous exposons également le name champ du ProjectEntity:

module Entities class ProjectEntity

Enfin, nous assemblons l'entité en un nouveau PairProgrammingSessionsEntity où nous exposons le project, le host_user, le visitor_user et le reviews:

module Entities class PairProgrammingSessionsEntity

Et avec cela, notre API est entièrement implémentée!

Générer des données de test

À des fins de test, nous allons créer des exemples de données dans db/seeds.rb. Ce fichier doit contenir toute la création d'enregistrement nécessaire pour amorcer la base de données avec ses valeurs par défaut. Les données peuvent ensuite être chargées avec rake db:seed (ou créé avec la base de données lorsque db:setup est appelé). Voici un exemple de ce que cela pourrait inclure:

user_1 = User.create email: ' [email protected] ', password: 'password', password_confirmation: 'password' user_2 = User.create email: ' [email protected] ', password: 'password', password_confirmation: 'password' user_3 = User.create email: ' [email protected] ', password: 'password', password_confirmation: 'password' ApiKey.create token: '12345654321' project_1 = Project.create name: 'Time Sheets' project_2 = Project.create name: 'ApeeScape Blog' project_3 = Project.create name: 'Hobby Project' session_1 = PairProgrammingSession.create project: project_1, host_user: user_1, visitor_user: user_2 session_2 = PairProgrammingSession.create project: project_2, host_user: user_1, visitor_user: user_3 session_3 = PairProgrammingSession.create project: project_3, host_user: user_2, visitor_user: user_3 review_1 = session_1.reviews.create user: user_1, comment: 'Please DRY a bit your code' review_2 = session_1.reviews.create user: user_1, comment: 'Please DRY a bit your specs' review_3 = session_2.reviews.create user: user_1, comment: 'Please DRY your view templates' review_4 = session_2.reviews.create user: user_1, comment: 'Please clean your N+1 queries' review_1.code_samples.create code: 'Lorem Ipsum' review_1.code_samples.create code: 'Do not abuse the single responsibility principle' review_2.code_samples.create code: 'Use some shared examples' review_2.code_samples.create code: 'Use at the beginning of specs'

Maintenant, notre application est prête à être utilisée et nous pouvons lancer notre serveur rails.

Tester l'API

Nous utiliserons Swagger pour effectuer des tests manuels de notre API sur navigateur. Cependant, quelques étapes de configuration sont nécessaires pour que nous puissions utiliser Swagger.

Tout d'abord, nous devons ajouter quelques gemmes à notre fichier de gemmes:

... gem 'grape-swagger' gem 'grape-swagger-ui' ...

On lance alors bundle pour installer ces gemmes.

Nous devons également les ajouter aux actifs de notre pipeline d'actifs (dans config/initializers/assets.rb):

Rails.application.config.assets.precompile += %w( swagger_ui.js ) Rails.application.config.assets.precompile += %w( swagger_ui.css )

Enfin, dans app/api/api.rb nous devons monter le générateur swagger:

... add_swagger_documentation end ...

Nous pouvons maintenant profiter de la belle interface utilisateur de Swagger pour explorer notre API en accédant simplement à http://localhost:3000/api/swagger.

Swagger présente nos points de terminaison d'API d'une manière bien explorable. Si nous cliquons sur un point de terminaison, Swagger répertorie ses opérations. Si nous cliquons sur une opération, Swagger affiche ses paramètres obligatoires et facultatifs et leurs types de données.

Un détail restant avant de continuer: Étant donné que nous avons limité l'utilisation des développeurs d'API avec un api_key valide, nous ne pourrons pas accéder au point de terminaison de l'API directement à partir du navigateur car le serveur nécessitera un api_key valide. dans l'en-tête HTTP. Nous pouvons accomplir cela à des fins de test dans Google Chrome en utilisant le Modifier les en-têtes pour le plugin Google Chrome . Ce plugin nous permettra d'éditer l'en-tête HTTP et d'ajouter un api_key valide | (nous utiliserons le mannequin api_key de 12345654321 que nous avons inclus dans notre fichier de départ de base de données).

OK, maintenant nous sommes prêts à tester!

Pour appeler le pair_programming_sessions Point de terminaison de l'API, nous devons d'abord nous connecter. Nous utiliserons simplement les combinaisons d'adresse e-mail et de mot de passe de notre fichier de base de données et le soumettons via Swagger au point de terminaison de l'API de connexion, comme indiqué ci-dessous.

Comme vous pouvez le voir ci-dessus, le jeton appartenant à cet utilisateur est retourné, indiquant que l'API de connexion fonctionne aussi correctement que prévu. Nous pouvons maintenant utiliser ce jeton pour exécuter avec succès GET /api/pair_programming_sessions.json opération.

Comme indiqué, le résultat est renvoyé sous la forme d'un objet JSON hiérarchique correctement formaté. Notez que la structure JSON reflète deux associations 1-à-plusieurs imbriquées, car le projet a plusieurs révisions et une révision a plusieurs exemples de code. Si nous ne renvoyons pas la structure de cette manière, l'appelant de notre API devra demander séparément les révisions pour chaque projet, ce qui nécessitera de soumettre N requêtes à notre point de terminaison API. Avec cette structure, nous résolvons donc le problème de performance des requêtes N + 1.

Emballer

Comme indiqué ici, les spécifications complètes de votre API permettent de garantir que l'API implémentée répond correctement et de manière adéquate aux cas d'utilisation prévus (et non intentionnels!).

Bien que l'exemple d'API présenté dans ce didacticiel soit assez basique, l'approche et les techniques que nous avons illustrées peuvent servir de base à des API plus sophistiquées de complexité arbitraire utilisant le Grain de raisin gemme. Ce tutoriel a, espérons-le, démontré que Grape est un joyau utile et flexible qui peut aider à faciliter la mise en œuvre d'une API JSON dans vos applications Rails. Prendre plaisir!

Fastlane: automatisation iOS sur régulateur de vitesse

Mobile

Fastlane: automatisation iOS sur régulateur de vitesse
Cartes du parcours client - Ce qu'elles sont et comment en créer une

Cartes du parcours client - Ce qu'elles sont et comment en créer une

Conception Ux

Articles Populaires
Ingénieur senior full-stack, équipe post-embauche des talents
Ingénieur senior full-stack, équipe post-embauche des talents
En souvenir de Matthew Osborne
En souvenir de Matthew Osborne
Comment créer un pipeline de déploiement initial efficace
Comment créer un pipeline de déploiement initial efficace
L'impact du Brexit sur le secteur des services financiers
L'impact du Brexit sur le secteur des services financiers
Comment préparer un modèle de tableau des flux de trésorerie qui s'équilibre réellement
Comment préparer un modèle de tableau des flux de trésorerie qui s'équilibre réellement
 
Conquérir la recherche de chaînes avec l'algorithme Aho-Corasick
Conquérir la recherche de chaînes avec l'algorithme Aho-Corasick
Estimation des coûts logiciels dans la gestion de projet agile
Estimation des coûts logiciels dans la gestion de projet agile
5 qualités indispensables des meilleurs chefs de projet
5 qualités indispensables des meilleurs chefs de projet
Comment recréer gratuitement les ressources d'un terminal Bloomberg
Comment recréer gratuitement les ressources d'un terminal Bloomberg
Noyaux d'arbres: quantification de la similitude entre les données structurées en arborescence
Noyaux d'arbres: quantification de la similitude entre les données structurées en arborescence
Articles Populaires
  • couleur verte de l'année
  • préparation d'architecte de solutions certifié aws
  • ce n'est pas une fille d'annonce de site de rencontre
  • un problème de sécurité de messagerie qui peut être évité est :
  • css media queries points d'arrêt standard
  • que font les directeurs financiers
Catégories
  • Design De Marque
  • Personnes Et Équipes Produit
  • Innovation
  • Kpi Et Analyses
  • © 2022 | Tous Les Droits Sont Réservés

    portaldacalheta.pt