{"id":288062,"date":"2018-08-16T14:22:03","date_gmt":"2018-08-16T10:22:03","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=288062"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=288062","title":{"rendered":"GraphQL API (CRUD) \u043d\u0430 Go"},"content":{"rendered":"\n<div data-io-article-url=\"https:\/\/habr.com\/post\/418203\/\" class=\"post__text post__text-html js-mediator-article\">\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/f74\/bcd\/465\/f74bcd465f0e443b05c1d417b58c3a42.jpg\" alt=\"image\"><\/p>\n<p>  <\/p>\n<p>\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442! \u041e GraphQL \u043c\u043d\u043e\u0433\u043e \u0441\u0442\u0430\u0442\u0435\u0439 \u043d\u0430 \u0425\u0430\u0431\u0440\u0435, \u043d\u043e \u043f\u0440\u043e\u0431\u0435\u0436\u0430\u0432\u0448\u0438\u0441\u044c \u043f\u043e \u043d\u0438\u043c \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u043b, \u0447\u0442\u043e \u0432\u0441\u0435 \u043e\u043d\u0438 \u043e\u0431\u0445\u043e\u0434\u044f\u0442 \u0441\u0442\u043e\u0440\u043e\u043d\u043e\u0439 \u0442\u0430\u043a\u043e\u0439 \u0437\u0430\u043c\u0435\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u044f\u0437\u044b\u043a \u043a\u0430\u043a Go. \u0421\u0435\u0433\u043e\u0434\u043d\u044f \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u044e \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u044d\u0442\u043e \u043d\u0435\u0434\u043e\u0440\u0430\u0437\u0443\u043c\u0435\u043d\u0438\u0435. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0430\u043f\u0438\u0448\u0435\u043c API \u043d\u0430 Go \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c GraphQL.<a name=\"habracut\"><\/a><\/p>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u0441\u043e\u0432\u0441\u0435\u043c \u043a\u043e\u0440\u043e\u0442\u043a\u043e: GraphQL \u044d\u0442\u043e \u044f\u0437\u044b\u043a \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0434\u043b\u044f \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f API, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 \u0432 \u043a\u0430\u043a\u043e\u043c \u0432\u0438\u0434\u0435 \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044c \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 (\u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0430\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043d\u0430 \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u043c \u0440\u0435\u0441\u0443\u0440\u0441\u0435 <a href=\"http:\/\/graphql.github.io\/\">graphql.github.io<\/a> \u0438 <a href=\"https:\/\/habr.com\/post\/326986\/\">\u043d\u0430 \u0445\u0430\u0431\u0440\u0435<\/a>)<\/p>\n<p>  <\/p>\n<p>\u041f\u043e\u0441\u043f\u043e\u0440\u0438\u0442\u044c \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u043b\u0443\u0447\u0448\u0435 GraphQL \u0438\u043b\u0438 REST \u043c\u043e\u0436\u043d\u043e <a href=\"https:\/\/habr.com\/post\/335158\/\">\u0442\u0443\u0442<\/a><\/p>\n<p>  <\/p>\n<p>\u0423 \u043d\u0430\u0441 \u0431\u0443\u0434\u0435\u0442 \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0435 API: CRUD (Create, Read, Update, Delete) \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435, \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0442\u043e\u0432\u0430\u0440\u043e\u0432 \u0432 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442 \u043c\u0430\u0433\u0430\u0437\u0438\u043d\u0435.<br \/>  \u041d\u0430 \u0441\u0442\u043e\u0440\u043e\u043d\u0435 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0433\u043e\u0442\u043e\u0432\u0443\u044e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e GraphQL <a href=\"https:\/\/github.com\/graphql-go\/graphql\">graphql-go<\/a><\/p>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u043a\u0430\u0447\u0430\u0442\u044c graphql-go, \u044d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439<\/p>\n<p>  <\/p>\n<pre><code class=\"go\">go get github.com\/graphql-go\/graphql<\/code><\/pre>\n<p>  <\/p>\n<p>\u0414\u0430\u043b\u0435\u0435, \u043e\u043f\u0438\u0448\u0435\u043c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0442\u043e\u0432\u0430\u0440\u0430 (\u0432 \u0443\u043f\u0440\u043e\u0449\u0435\u043d\u043d\u043e\u043c \u0432\u0438\u0434\u0435) <\/p>\n<p>  <\/p>\n<pre><code class=\"go\">type Product struct {     ID       int64  `json:\"id\"`     Name     string `json:\"name\"`     Info     string `json:\"info,omitempty\"`     Price    float64 `json:\"price\"` }<\/code><\/pre>\n<p>  <\/p>\n<p><code>ID<\/code> \u2014 \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0439 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440, <code>Name<\/code> \u2014 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435, <code>Info<\/code> \u2014 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e \u0442\u043e\u0432\u0430\u0440\u0435, <code>Price<\/code> \u2014 \u0446\u0435\u043d\u0430<\/p>\n<p>  <\/p>\n<p>\u041f\u0435\u0440\u0432\u043e\u0435, \u0447\u0442\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c, \u044d\u0442\u043e \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434 <code>Do<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0432\u0445\u043e\u0434\u043d\u044b\u0445 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0441\u0445\u0435\u043c\u0443 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0437\u0430\u043f\u0440\u043e\u0441\u0430. \u0410 \u0432\u0435\u0440\u043d\u0435\u0442 \u043d\u0430\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0438\u0440\u0443\u044e\u0449\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 (\u0434\u043b\u044f \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u0439 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442)<\/p>\n<p>  <\/p>\n<pre><code class=\"go\">result := graphql.Do(graphql.Params{   Schema:        schema,   RequestString: query, })<\/code><\/pre>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u041f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u0434<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"go\">func executeQuery(query string, schema graphql.Schema) *graphql.Result {     result := graphql.Do(graphql.Params{         Schema:        schema,         RequestString: query,     })     if len(result.Errors) &gt; 0 {         fmt.Printf(\"errors: %v\", result.Errors)     }     return result }  func main() {     http.HandleFunc(\"\/product\", func(w http.ResponseWriter, r *http.Request) {         result := executeQuery(r.URL.Query().Get(\"query\"), schema)         json.NewEncoder(w).Encode(result)     })     http.ListenAndServe(\":8080\", nil) }<\/code><\/pre>\n<\/div>\n<\/div>\n<p>  <\/p>\n<p><code>Schema<\/code> \u2014 \u0441\u0445\u0435\u043c\u0430 \u0434\u0430\u043d\u043d\u044b\u0445, <code>RequestString<\/code> \u2014 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430 \u0441\u0442\u0440\u043e\u043a\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0430, \u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>query<\/code><\/p>\n<p>  <\/p>\n<h2 id=\"schema-shema\">Schema (\u0421\u0445\u0435\u043c\u0430)<\/h2>\n<p>  <\/p>\n<p>\u0421\u0445\u0435\u043c\u0430 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0434\u0432\u0430 \u043a\u043e\u0440\u043d\u0435\u0432\u044b\u0445 \u0442\u0438\u043f\u0430 \u0434\u0430\u043d\u043d\u044b\u0445: <code>Query<\/code> \u2014 \u043d\u0435\u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435, <code>Mutation<\/code> \u2014 \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435<\/p>\n<p>  <\/p>\n<pre><code class=\"go\">var schema, _ = graphql.NewSchema(     graphql.SchemaConfig{         Query:    queryType,         Mutation: mutationType,     }, )<\/code><\/pre>\n<p>  <\/p>\n<h2 id=\"query-zaprosy\">Query (\u0417\u0430\u043f\u0440\u043e\u0441\u044b)<\/h2>\n<p>  <\/p>\n<p><code>Query<\/code> \u0441\u043b\u0443\u0436\u0438\u0442 \u0434\u043b\u044f \u0447\u0442\u0435\u043d\u0438\u044f (\u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0442\u0435\u043d\u0438\u044f) \u0434\u0430\u043d\u043d\u044b\u0445. \u0421 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>Query<\/code> \u043c\u044b \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u043a\u0430\u043a\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0434\u043e\u043b\u0436\u0435\u043d \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0441\u0435\u0440\u0432\u0435\u0440.<br \/>  \u041d\u0430\u043f\u0438\u0448\u0435\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0442\u0438\u043f\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 <code>Query<\/code>, \u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043e\u043d \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u043f\u043e\u043b\u044f \u0441 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435\u043c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043e \u0435\u0434\u0438\u043d\u0438\u0447\u043d\u043e\u043c \u0442\u043e\u0432\u0430\u0440\u0435 (product) \u0438 \u0441\u043f\u0438\u0441\u043a\u0435 \u0442\u043e\u0432\u0430\u0440\u043e\u0432 (list)<\/p>\n<p>  <\/p>\n<pre><code class=\"go\">var queryType = graphql.NewObject(     graphql.ObjectConfig{         Name: \"Query\",         Fields: graphql.Fields{             \/* \u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u0430 \u043f\u043e ID                http:\/\/localhost:8080\/product?query={product(id:1){name,info,price}}             *\/             \"product\": &amp;graphql.Field{                 Type:        productType,                 Description: \"Get product by id\",                 \/\/ \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0441\u043f\u0438\u0441\u043e\u043a \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432, \u0434\u043b\u044f \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f                 Args: graphql.FieldConfigArgument{                     \/\/ \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c \u0442\u043e\u043b\u044c\u043a\u043e id                     \"id\": &amp;graphql.ArgumentConfig{                         Type: graphql.Int,                     },                 },                 Resolve: func(p graphql.ResolveParams) (interface{}, error) {                     id, ok := p.Args[\"id\"].(int)                     if ok {                         \/\/ \u041f\u043e\u0438\u0441\u043a \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u0430 \u0441 ID                         for _, product := range products {                             if int(product.ID) == id {                                 return product, nil                             }                         }                     }                     return nil, nil                 },             },             \/* \u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0441\u043f\u0438\u0441\u043a\u0430 \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u043e\u0432                http:\/\/localhost:8080\/product?query={list{id,name,info,price}}             *\/             \"list\": &amp;graphql.Field{                 Type:        graphql.NewList(productType),                 Description: \"Get product list\",                 Resolve: func(params graphql.ResolveParams) (interface{}, error) {                     return products, nil                 },             },         },     })<\/code><\/pre>\n<p>  <\/p>\n<p>\u0422\u0438\u043f queryType \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442\u044c \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043f\u043e\u043b\u044f <code>Name<\/code> \u0438 <code>Fields<\/code>, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043d\u0435\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0435 <code>Description<\/code> (\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438)<br \/>  \u0412 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043f\u043e\u043b\u0435 <code>Fields<\/code> \u0442\u0430\u043a\u0436\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u043f\u043e\u043b\u0435 <code>Type<\/code> \u0438 \u043d\u0435 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043f\u043e\u043b\u044f <code>Args<\/code>, <code>Resolve<\/code> \u0438 <code>Description<\/code><\/p>\n<p>  <\/p>\n<h2 id=\"args-argumenty\">Args (\u0410\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b)<\/h2>\n<p>  <\/p>\n<p>\u0410\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b \u2014 \u0441\u043f\u0438\u0441\u043e\u043a \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432, \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043d\u044b\u0445 \u0441 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440 \u0438 \u0432\u043b\u0438\u044f\u044e\u0449\u0438\u0435 \u043d\u0430 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445. \u0410\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b \u043f\u0440\u0438\u0432\u044f\u0437\u0430\u043d\u044b \u043a \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u043c\u0443 \u043f\u043e\u043b\u044e. \u041f\u0440\u0438\u0447\u0435\u043c \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u043a\u0430\u043a \u0432 <code>Query<\/code> \u0442\u0430\u043a \u0438 \u0432 <code>Mutation<\/code>.<\/p>\n<p>  <\/p>\n<pre><code class=\"go\">?query={product(id:1){name,info,price}}<\/code><\/pre>\n<p>  <\/p>\n<p>\u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442 <code>id<\/code> \u0434\u043b\u044f \u043f\u043e\u043b\u044f <code>product<\/code> \u0441\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c 1, \u0433\u043e\u0432\u043e\u0440\u0438\u0442 \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0442\u043e\u0432\u0430\u0440 \u0441 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u043c \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u043e\u043c.<br \/>  \u0414\u043b\u044f <code>list<\/code> \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b \u043e\u043f\u0443\u0449\u0435\u043d\u044b, \u043d\u043e \u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438 \u044d\u0442\u043e \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c, \u043a \u043f\u0440\u0438\u043c\u0435\u0440\u0443: <code>limit<\/code> \u0438 <code>offset<\/code>.<\/p>\n<p>  <\/p>\n<h2 id=\"resolve-raspoznavateli\">Resolve (\u0420\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u0442\u0435\u043b\u0438)<\/h2>\n<p>  <\/p>\n<p>\u0412\u0441\u044f \u043b\u043e\u0433\u0438\u043a\u0430 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043a \u0411\u0414, \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0438 \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u044f) \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u0445, \u0438\u043c\u0435\u043d\u043d\u043e \u043e\u043d\u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0442 \u0434\u0430\u043d\u043d\u044b\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u044b \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043e\u0442\u0432\u0435\u0442\u0430 \u043d\u0430 \u0437\u0430\u043f\u0440\u043e\u0441.<\/p>\n<p>  <\/p>\n<h2 id=\"type-sistema-tipov\">Type (\u0421\u0438\u0441\u0442\u0435\u043c\u0430 \u0442\u0438\u043f\u043e\u0432)<\/h2>\n<p>  <\/p>\n<p>GraphQL \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0441\u0432\u043e\u044e \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0442\u0438\u043f\u043e\u0432 \u0434\u043b\u044f \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445. \u041c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u0430\u043a \u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u0442\u0438\u043f\u044b <code>String<\/code>, <code>Int<\/code>, <code>Float<\/code>, <code>Boolean<\/code>, \u0442\u0430\u043a \u0438 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 (\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0435). \u0414\u043b\u044f \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0439 \u0442\u0438\u043f <code>Product<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u0432\u0441\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u0430<\/p>\n<p>  <\/p>\n<pre><code class=\"go\">var productType = graphql.NewObject(     graphql.ObjectConfig{         Name: \"Product\",         Fields: graphql.Fields{             \"id\": &amp;graphql.Field{                 Type: graphql.Int,             },             \"name\": &amp;graphql.Field{                 Type: graphql.String,             },             \"info\": &amp;graphql.Field{                 Type: graphql.String,             },             \"price\": &amp;graphql.Field{                 Type: graphql.Float,             },         },     }, )<\/code><\/pre>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043f\u043e\u043b\u044f \u0443\u043a\u0430\u0437\u0430\u043d \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u0442\u0438\u043f, \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u044d\u0442\u043e <code>graphql.Int<\/code>, <code>graphql.String<\/code>, <code>graphql.Float<\/code>.<br \/>  \u041a\u043e\u043b-\u0432\u043e \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0445 \u043f\u043e\u043b\u0435\u0439 \u043d\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043e, \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u0447\u0435\u043c\u0443 \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0433\u0440\u0430\u0444\u043e\u0432 \u043b\u044e\u0431\u043e\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f.<\/p>\n<p>  <\/p>\n<h2 id=\"mutation-mutacii\">Mutation (\u041c\u0443\u0442\u0430\u0446\u0438\u0438)<\/h2>\n<p>  <\/p>\n<p>\u041c\u0443\u0442\u0430\u0446\u0438\u0438 \u044d\u0442\u0438 \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435, \u043a \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0441\u044f: \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435, \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435. \u0412\u043e \u0432\u0441\u0435\u043c \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u043c \u043c\u0443\u0442\u0430\u0446\u0438\u0438 \u043e\u0447\u0435\u043d\u044c \u043f\u043e\u0445\u043e\u0436\u0438 \u043d\u0430 \u043e\u0431\u044b\u0447\u043d\u044b\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u044b: \u043e\u043d\u0438 \u0442\u0430\u043a\u0436\u0435 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0442 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b <code>Args<\/code> \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 <code>Resolve<\/code> \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043e\u0442\u0432\u0435\u0442\u0430 \u043d\u0430 \u0437\u0430\u043f\u0440\u043e\u0441.<\/p>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u043c\u0443\u0442\u0430\u0446\u0438\u0438 \u0434\u043b\u044f \u043d\u0430\u0448\u0438\u0445 \u0442\u043e\u0432\u0430\u0440\u043e\u0432<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"go\">  var mutationType = graphql.NewObject(graphql.ObjectConfig{     Name: \"Mutation\",     Fields: graphql.Fields{         \/* \u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u043e\u0432\u043e\u0433\u043e \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u0430            http:\/\/localhost:8080\/product?query=mutation+_{create(name:\"Tequila\",info:\"Alcohol\",price:99){id,name,info,price}}         *\/         \"create\": &amp;graphql.Field{             Type:        productType,             Description: \"Create new product\",             Args: graphql.FieldConfigArgument{                 \"name\": &amp;graphql.ArgumentConfig{                     Type: graphql.NewNonNull(graphql.String), \/\/ \u043f\u043e\u043b\u0435 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u0434\u043b\u044f \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f                 },                 \"info\": &amp;graphql.ArgumentConfig{                     Type: graphql.String, \/\/ \u043d\u0435 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u043f\u043e\u043b\u0435                 },                 \"price\": &amp;graphql.ArgumentConfig{                     Type: graphql.NewNonNull(graphql.Float),                 },             },             Resolve: func(params graphql.ResolveParams) (interface{}, error) {                 rand.Seed(time.Now().UnixNano())                 product := Product{                     ID:    int64(rand.Intn(100000)), \/\/ \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u044b\u0439 ID                     Name:  params.Args[\"name\"].(string),                     Info:  params.Args[\"info\"].(string),                     Price: params.Args[\"price\"].(float64),                 }                 products = append(products, product)                 return product, nil             },         },          \/* \u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u0430 \u043f\u043e id            http:\/\/localhost:8080\/product?query=mutation+_{update(id:1,price:195){id,name,info,price}}         *\/         \"update\": &amp;graphql.Field{             Type:        productType,             Description: \"Update product by id\",             Args: graphql.FieldConfigArgument{                 \"id\": &amp;graphql.ArgumentConfig{                     Type: graphql.NewNonNull(graphql.Int),                 },                 \"name\": &amp;graphql.ArgumentConfig{                     Type: graphql.String,                 },                 \"info\": &amp;graphql.ArgumentConfig{                     Type: graphql.String,                 },                 \"price\": &amp;graphql.ArgumentConfig{                     Type: graphql.Float,                 },             },             Resolve: func(params graphql.ResolveParams) (interface{}, error) {                 id, _ := params.Args[\"id\"].(int)                 name, nameOk := params.Args[\"name\"].(string)                 info, infoOk := params.Args[\"info\"].(string)                 price, priceOk := params.Args[\"price\"].(float64)                 product := Product{}                 for i, p := range products {                     \/\/ \u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u0443\u0435\u043c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u0435                     if int64(id) == p.ID {                         if nameOk {                             products[i].Name = name                         }                         if infoOk {                             products[i].Info = info                         }                         if priceOk {                             products[i].Price = price                         }                         product = products[i]                         break                     }                 }                 return product, nil             },         },          \/* \u0423\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u0430 \u043f\u043e id            http:\/\/localhost:8080\/product?query=mutation+_{delete(id:1){id,name,info,price}}         *\/         \"delete\": &amp;graphql.Field{             Type:        productType,             Description: \"Delete product by id\",             Args: graphql.FieldConfigArgument{                 \"id\": &amp;graphql.ArgumentConfig{                     Type: graphql.NewNonNull(graphql.Int),                 },             },             Resolve: func(params graphql.ResolveParams) (interface{}, error) {                 id, _ := params.Args[\"id\"].(int)                 product := Product{}                 for i, p := range products {                     if int64(id) == p.ID {                         product = products[i]                         \/\/ \u0423\u0434\u0430\u043b\u044f\u0435\u043c \u0438\u0437 \u0441\u043f\u0438\u0441\u043a\u0430 \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u043e\u0432                         products = append(products[:i], products[i+1:]...)                     }                 }                  return product, nil             },         },     },   })<\/code><\/pre>\n<\/div>\n<\/div>\n<p>  <\/p>\n<p>\u0412\u0441\u0435 \u043f\u043e \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0438 \u0441 <code>queryType<\/code>. \u0415\u0441\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u043d\u0430 \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0430\u044f \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u044c \u0442\u0438\u043f <code>graphql.NewNonNull(graphql.Int)<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043e\u043e\u0431\u0449\u0430\u0435\u0442 \u043d\u0430\u043c, \u0447\u0442\u043e \u0434\u0430\u043d\u043d\u043e\u0435 \u043f\u043e\u043b\u0435 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u0443\u0441\u0442\u044b\u043c (\u043f\u043e\u0445\u043e\u0436\u0435 \u043d\u0430 <code>NOT NULL<\/code> \u0432 MySQL)<\/p>\n<p>  <\/p>\n<p>\u0412\u0441\u0435. \u0422\u0435\u043f\u0435\u0440\u044c \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u043e\u0435 CRUD API \u043d\u0430 Go \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0442\u043e\u0432\u0430\u0440\u0430\u043c\u0438. \u041c\u044b \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 \u0431\u0430\u0437\u0443 \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043f\u0440\u0438\u043c\u0435\u0440\u0430, \u043d\u043e \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043b\u0438 \u043a\u0430\u043a \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043c\u043e\u0434\u0435\u043b\u044c \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u043c\u0430\u043d\u0438\u043f\u0443\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438\u043c\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u0443\u0442\u0430\u0446\u0438\u0439.<\/p>\n<p>  <\/p>\n<h2 id=\"primery\">\u041f\u0440\u0438\u043c\u0435\u0440\u044b<\/h2>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u0432\u044b \u0441\u043a\u0430\u0447\u0430\u043b\u0438 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0438 \u0447\u0435\u0440\u0435\u0437 <\/p>\n<p>  <\/p>\n<pre><code class=\"go\">go get github.com\/graphql-go\/graphql<\/code><\/pre>\n<p>  <\/p>\n<p>\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e \u0441 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u043c <\/p>\n<p>  <\/p>\n<pre><code class=\"go\">cd examples\/crud<\/code><\/pre>\n<p>  <\/p>\n<p>\u0438 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435<\/p>\n<p>  <\/p>\n<pre><code class=\"go\">go run main.go<\/code><\/pre>\n<p>  <\/p>\n<p><strong> \u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u044b:<\/strong><br \/>  \u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u0430 \u043f\u043e ID<br \/>  <code>http:\/\/localhost:8080\/product?query={product(id:1){name,info,price}}<\/code><\/p>\n<p>  <\/p>\n<p>\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0441\u043f\u0438\u0441\u043a\u0430 \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u043e\u0432<br \/>  <code>http:\/\/localhost:8080\/product?query={list{id,name,info,price}}<\/code><\/p>\n<p>  <\/p>\n<p>\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u043e\u0432\u043e\u0433\u043e \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u0430<br \/>  <code>http:\/\/localhost:8080\/product?query=mutation+_{create(name:\"Tequila\",info:\"Strong alcoholic beverage\",price:999){id,name,info,price}}<\/code><\/p>\n<p>  <\/p>\n<p>\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u0430<br \/>  <code>http:\/\/localhost:8080\/product?query=mutation+_{update(id:1,price:195){id,name,info,price}}<\/code><\/p>\n<p>  <\/p>\n<p>\u0423\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u0430 \u043f\u043e id<br \/>  <code>http:\/\/localhost:8080\/product?query=mutation+_{delete(id:1){id,name,info,price}}<\/code><\/p>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u0432\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0435 REST \u0441\u0442\u043e\u0438\u0442 \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u044c \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 GraphQL \u043a\u0430\u043a \u043d\u0430 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u0443\u044e \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u0443. \u0414\u0430, \u0441 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0432\u0437\u0433\u043b\u044f\u0434\u0430 \u044d\u0442\u043e \u043a\u0430\u0436\u0435\u0442\u0441\u044f \u0441\u043b\u043e\u0436\u043d\u0435\u0435, \u043d\u043e \u0441\u0442\u043e\u0438\u0442 \u043d\u0430\u0447\u0430\u0442\u044c \u0438 \u0437\u0430 \u043f\u0430\u0440\u0443 \u0434\u043d\u0435\u0439 \u0432\u044b \u043e\u0441\u0432\u043e\u0438\u0442\u0435 \u0434\u0430\u043d\u043d\u0443\u044e \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u044e. \u041a\u0430\u043a \u043c\u0438\u043d\u0438\u043c\u0443\u043c \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043b\u0435\u0437\u043d\u043e.<\/p>\n<\/div>\n<p>        <script class=\"js-mediator-script\">!function(e){function t(t,n){if(!(n in e)){for(var r,a=e.document,i=a.scripts,o=i.length;o--;)if(-1!==i[o].src.indexOf(t)){r=i[o];break}if(!r){r=a.createElement(\"script\"),r.type=\"text\/javascript\",r.async=!0,r.defer=!0,r.src=t,r.charset=\"UTF-8\";var d=function(){var e=a.getElementsByTagName(\"script\")[0];e.parentNode.insertBefore(r,e)};\"[object Opera]\"==e.opera?a.addEventListener?a.addEventListener(\"DOMContentLoaded\",d,!1):e.attachEvent(\"onload\",d):d()}}}t(\"\/\/mediator.mail.ru\/script\/2820404\/\",\"_mediator\")}(window);<\/script>     <br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/post\/418203\/\"> https:\/\/habr.com\/post\/418203\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"\n<div data-io-article-url=\"https:\/\/habr.com\/post\/418203\/\" class=\"post__text post__text-html js-mediator-article\">\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/f74\/bcd\/465\/f74bcd465f0e443b05c1d417b58c3a42.jpg\" alt=\"image\"><\/p>\n<p>  <\/p>\n<p>\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442! \u041e GraphQL \u043c\u043d\u043e\u0433\u043e \u0441\u0442\u0430\u0442\u0435\u0439 \u043d\u0430 \u0425\u0430\u0431\u0440\u0435, \u043d\u043e \u043f\u0440\u043e\u0431\u0435\u0436\u0430\u0432\u0448\u0438\u0441\u044c \u043f\u043e \u043d\u0438\u043c \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u043b, \u0447\u0442\u043e \u0432\u0441\u0435 \u043e\u043d\u0438 \u043e\u0431\u0445\u043e\u0434\u044f\u0442 \u0441\u0442\u043e\u0440\u043e\u043d\u043e\u0439 \u0442\u0430\u043a\u043e\u0439 \u0437\u0430\u043c\u0435\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u044f\u0437\u044b\u043a \u043a\u0430\u043a Go. \u0421\u0435\u0433\u043e\u0434\u043d\u044f \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u044e \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u044d\u0442\u043e \u043d\u0435\u0434\u043e\u0440\u0430\u0437\u0443\u043c\u0435\u043d\u0438\u0435. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0430\u043f\u0438\u0448\u0435\u043c API \u043d\u0430 Go \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c GraphQL.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-288062","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/288062","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=288062"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/288062\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=288062"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=288062"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=288062"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}