2021年12月21日火曜日

I compared how "GraphQL", which changes the flow of application development, is different from REST. (Rails version).

https://www.webprofessional.jp/rest-2-0-graphql/

I shared it.

Rails seems to be fun and quick to develop, but maintenance after that is very painful for other people and others, that is, other than the person himself, so it is a baggage for team development and maintenance by a third party after development. I will never be a male.

consultant

Masahiro Ishizuka

2021/12/21

The following articles

It is the thing of 2017/07/12.

 

Michael Paris 

495

Articles in this issue reproduced from SitePoint
Copyright © 2017, All rights reserved. SitePoint Pty Ltd. www.sitepoint.com. Translation copyright © 2017, KADOKAWA ASCII Research Laboratories, Inc. Japanese syndication rights arranged with SitePoint Pty Ltd, Collingwood, Victoria, Australia through Tuttle-Mori Agency, Inc., Tokyo

Where is the API of the query language "GraphQL" developed by Facebook useful? I will explain with a sample comparing with the conventional REST API.

GraphQL is an API query language. It has excellent performance, a developer experience, and powerful tools to replace REST.

Here are three common use cases for working with REST and GraphQL. We have prepared a simple front-end app made with HTML and jQuery, as well as the code for each of the REST API and GraphQL API, where you can see information on popular movies and performers.

Experience the differences, strengths and weaknesses while working with the API. First of all, I will briefly introduce the background of the technology.

The dawn of the Web

Early websites were as simple as sending static HTML documents over the Internet. Eventually, it became possible to dynamically acquire the content stored in the database with SQL etc. and operate it with JavaScript. I was browsing with a web browser on my desktop PC.

Normal Image

REST: API prosperity

The times have gone by, and in 2007 Steve Jobs introduced the iPhone. The influence of smartphones extends beyond the world, culture and communications to development work. We needed to develop for iPhone, Android, and tablets, not just desktops.

Developers have begun to use the RESTful API to display data in apps of all shapes and sizes The development model has the following form.

REST Server

GraphQL: API evolution

GraphQL is an open source language developed by Facebook. It can be used instead of REST as a mechanism for creating APIs. While REST is a conceptual design model used to design and implement APIs, GraphQL has standardized languages, types, and specifications that make a strong connection between clients and servers. Having a standardized language for communication between different devices simplifies large, cross-platform app development.

GraphQL development model.

GraphQL Server

Compare GraphQL and REST

Let's experience it right away. The code is in the GitHub repository .

The code contains three projects.

  1. RESTful API
  2. GraphQL API
  3. A simple client page made with jQuery and HTML

The project is intentionally simplified to make it easier to compare technologies.

Open three terminal windows and cd to the RESTful , GraphQL , Client folders in your project repository From each folder , start your development server with npm run dev .

Query by REST

The RESTful API in the sample project has several endpoints.

end pointExplanation
/ moviesReturns an array of objects containing movie links (eg [{href:'http: //localhost/movie/1'}])
/ movie /: idReturns one movie title specified by id (=: id)
/ movie /: id / actorsReturns an array of objects containing links to the performers of the movie specified by id (=: id)
/ actorsReturns an array of objects containing performer links
/ actor /: idReturns one performer specified by id (=: id)
/ actor /: id / moviesReturns an array of objects containing links to the movie in which the performer specified by id (=: id) appears

Note: Even a simple data model contains as many as six endpoints that need to be maintained and explained in the future.

Suppose you are a client-side developer and you use the movies API to create a simple web page with HTML and jQuery. For that purpose, information on the movie and the actors / actresses is required. Now that you have all the features you need for the API, get the data.

Open a new terminal and do the following:

curl localhost:3000/movies

The following response will be returned.

[
  {
    "href": "http://localhost:3000/movie/1"
  },
  {
    "href": "http://localhost:3000/movie/2"
  },
  {
    "href": "http://localhost:3000/movie/3"
  },
  {
    "href": "http://localhost:3000/movie/4"
  },
  {
    "href": "http://localhost:3000/movie/5"
  }
]

The RESTful API returns an array of movie object links. Get the first movie at curl http: // localhost: 3000 / movie / 1 and get the second at curl http: // localhost: 3000 / movie / 2 .

Looking at the contents of app.js, there is a function that gets the information needed to fill in the content of the page.

const API_URL = 'http://localhost:3000/movies';
function fetchDataV1() {

  // 1 call to get the movie links
  $.get(API_URL, movieLinks => {
    movieLinks.forEach(movieLink => {

      // For each movie link, grab the movie object
      $.get(movieLink.href, movie => {
        $('#movies').append(buildMovieElement(movie))

        // One call (for each movie) to get the links to actors in this movie
        $.get(movie.actors, actorLinks => {
          actorLinks.forEach(actorLink => {

            // For each actor for each movie, grab the actor object
            $.get(actorLink.href, actor => {
              const selector = '#' + getMovieId(movie) + ' .actors';
              const actorElement = buildActorElement(actor);
              $(selector).append(actorElement);
            })
          })
        })
      })
    })
  })
}

I have made  1 + M + M + sum (Am) calls to the API asking for a response. Not ideal. M is the number of movies, and sum (Am) is the total number of performers in each of the M movies. Any app with a small amount of data is fine, but it is not suitable for large production projects.

The RESTful approach is inadequate. To improve the API, ask the backend development team to create / moviesAndActors endpoint to fill the page When you 're ready, you can make a 1 + M + M + sum (Am) network call with one request.

curl http://localhost:3000/moviesAndActors

The following response will be returned.

[
  {
    "id": 1,
    "title": "The Shawshank Redemption",
    "release_year": 1993,
    "tags": [
      "Crime",
      "Drama"
    ],
    "rating": 9.3,
    "actors": [
      {
        "id": 1,
        "name": "Tim Robbins",
        "dob": "10/16/1958",
        "num_credits": 73,
        "image": "https://images-na.ssl-images-amazon.com/images/M/MV5BMTI1OTYxNzAxOF5BMl5BanBnXkFtZTYwNTE5ODI4._V1_.jpg",
        "href": "http://localhost:3000/actor/1",
        "movies": "http://localhost:3000/actor/1/movies"
      },
      {
        "id": 2,
        "name": "Morgan Freeman",
        "dob": "06/01/1937",
        "num_credits": 120,
        "image": "https://images-na.ssl-images-amazon.com/images/M/MV5BMTc0MDMyMzI2OF5BMl5BanBnXkFtZTcwMzM2OTk1MQ@@._V1_UX214_CR0,0,214,317_AL_.jpg",
        "href": "http://localhost:3000/actor/2",
        "movies": "http://localhost:3000/actor/2/movies"
      }
    ],
    "image": "https://images-na.ssl-images-amazon.com/images/M/MV5BODU4MjU4NjIwNl5BMl5BanBnXkFtZTgwMDU2MjEyMDE@._V1_UX182_CR0,0,182,268_AL_.jpg",
    "href": "http://localhost:3000/movie/1"
  },
  ...
]

With just one request, I got all the data I needed to fill the page. If you look at app.js in the Client folder, you can see that the improvements have worked .

const MOVIES_AND_ACTORS_URL = 'http://localhost:3000/moviesAndActors';
function fetchDataV2() {
  $.get(MOVIES_AND_ACTORS_URL, movies => renderRoot(movies));
}
function renderRoot(movies) {
  movies.forEach(movie => {
    $('#movies').append(buildMovieElement(movie));
    movie.actors && movie.actors.forEach(actor => {
      const selector = '#' + getMovieId(movie) + ' .actors';
      const actorElement = buildActorElement(actor);
      $(selector).append(actorElement);
    })
  });
}

The improved app is much faster than the previous one, but it's still not perfect. Open http: // localhost: 4000 .

Demo App

This page uses movie titles and images, actor names and images. Here, only two out of eight fields in the movie and only two out of seven actors show that three-quarters of the requested information was wasted. Excessive use of the line not only reduces performance, but also rebounds in equipment costs.

A smart backend developer will laugh and take action immediately. The special query parameter "fields" takes an array of field names and dynamically determines which fields should be returned in the request.

For example, instead of curl http: // localhost: 3000 / moviesAndActors , use curl http: // localhost: 3000 / moviesAndActors? fields = title, image . Another special query parameter could be to have actor_fields to specify which actor's fields to include. Example: curl http: // localhost: 3000 / moviesAndActors? fields = title, image & actor_fields = name, image

We are approaching the optimal implementation. There remains a bad practice of creating custom endpoints for specific pages of client apps . This is a problem when creating iOS apps and Android apps that display information different from web pages.

I will introduce a general API that can explicitly display the entities of the data model and the relationships between the entities, and the performance can be solved in 1 + M + M + sum (Am) times.

Query by GraphQL

GraphQL will issue optimized queries in no time. Get all the information you need with a simple and intuitive query.

query MoviesAndActors {
  movies {
    title
    image
    actors {
      image
      name
    }
  }
}

To try it, open http: // localhost: 5000 in GraphQL, a good browser-based IDE for GraphQL, and run the above query.

Let's take a closer look.

GraphQL concept

GraphQL's API approach is different from REST. It has an intuitive and easy-to-understand query language and type system layer without relying on HTTP structures such as verbs and URIs. Depending on the system, there is a strong common convention of data types between the client and the server, and the query language allows client-side developers to efficiently get the data they need for every page.

To use GraphQL, it's easy to assume that the data is a "graph" of virtual information. Informational entities are called types, and the types are related through fields. The query finds the information you need by following the "graph" from the root.

A "graph" is represented by a schema. A schema represents a data model that makes up an API, such as types, interfaces, enums, and unions. GraphQL allows you to write API definitions in a convenient schema language. The following is the schema of this movie API.

schema {
    query: Query
}

type Query {
    movies: [Movie]
    actors: [Actor]
    movie(id: Int!): Movie
    actor(id: Int!): Actor
    searchMovies(term: String): [Movie]
    searchActors(term: String): [Actor]
}

type Movie {
    id: Int
    title: String
    image: String
    release_year: Int
    tags: [String]
    rating: Float
    actors: [Actor]
}

type Actor {
    id: Int
    name: String
    image: String
    dob: String
    num_credits: Int
    movies: [Movie]
}

The type system opens a great door to good tools and documentation, efficient apps and more. There's a lot to tell, but let's move on and show some examples of the differences between REST and GraphQL.

Differences between GraphQL and REST: version control

Just do a Google search and you'll find lots of information on how to version your REST API. Version control of the REST API is so difficult. This is one of the reasons why it is usually difficult to know what information is being used from which app or device.

Adding information is easy with both REST and GraphQL. If you add a field, it will flow to the REST client and GraphQL will be safely ignored unless you change the query. But if you delete or edit information, the story changes.

REST is difficult to know what information is used at the field level. Even if you know that endpoints / movies are used, you don't know if they are used for titles, images, or both. The workaround is to add a query parameter "fields" to identify the returned fields. Since the parameter is optional , prepare another endpoint / v2 / movies for endpoint level modification However, the entrance to the API is bloated, and it is a burden for developers to prepare documents while keeping the latest state consistent.

GraphQL versioning is completely different. GraphQL queries specify the requested field. You can get an accurate picture of the requested information. It is also possible to obtain information such as "who" and "how often". Primitive types are also available, so you can deprecate fields and explain why in the schema.

Versioning in GraphQL

GraphQL version control

Differences between GraphQL and REST: Data caching

REST caching is straightforward and efficient. The use of cash is one of the six cardinal rule of REST is a, is built into the RESTful design. All subsequent / movies / 1 requests will be cached if indicated to cache replies from the endpoint / movies / 1 . It's a simple mechanism.

GraphQL cache usage is slightly different. To cache the GraphQL API, give each object a unique ID. If the object has a unique ID, the client builds a normalized cache and securely stores, updates, and deletes the object based on the ID. When the client makes a downstream query that references that object, the cached object is returned. See here for how GraphQL uses cache .

Differences between GraphQL and REST: Developer Experience

Developer experience is an important part of app development and is why engineers spend so much time preparing the tool environment. Even if this comparison is subjective, it should be mentioned.

REST is a proven entity. It has a rich ecosystem and a wealth of tools for developers to document, test, inspect RESTful APIs, and more. However, as the REST API grows, developers are paying for it. The number of endpoints has grown too high and it has become difficult to maintain consistency, and version control remains difficult.

GraphQL is a typing mechanism, so you can use great tools such as the GraphQL IDE. The point is that the schema contains the document. You only need one endpoint, and instead of documenting the data you can use, secure typing languages ​​and autocomplete give you an overview of the API. It can be used in combination with today's mainstream front-end frameworks and tools such as React and Redux. If you're considering developing a React app, we recommend checking out Relay or Apollo client .

Finally

GraphQL has some pros and cons, but it's a powerful tool for developing highly efficient data-oriented apps. There are challenges in developing client-side apps with REST.

If you want to learn more , check out Scaphold.io's GraphQL backend as a service . You can deploy the GraphQL API on AWS in just minutes and modify and extend it to suit your business logic.

(Original: REST 2.0 Is Here and Its Name Is GraphQL )

[Translation: Takeshi Nishio / Editing: Livit ]

Copyright © 2017, Michael Paris All Rights Reserved.

Michael Paris

Michael Paris 

CEO and co-founder of scaphold.io, he likes to tackle difficult problems. scaphold.io was selected as an investment destination in the winter 2017 selection of Y Combinator (US venture capital).

0 コメント:

コメントを投稿