Skip to content

Commit 984288e

Browse files
authored
feat: add GraphQL endpoint support (#124)
1 parent 1f8da2c commit 984288e

5 files changed

Lines changed: 95 additions & 8 deletions

File tree

README.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,28 @@ file_revisions = crowdin.list_file_revisions(your_file_id, { limit: 10 }, your_p
134134
# Note: more examples you can find in spec folder
135135
```
136136

137+
### GraphQL API
138+
139+
The client can send GraphQL requests to Crowdin's default API host or to an Enterprise organization endpoint.
140+
141+
```ruby
142+
query = <<~GRAPHQL
143+
query Viewer {
144+
viewer {
145+
id
146+
}
147+
}
148+
GRAPHQL
149+
150+
response = crowdin.graphql({ query: query })
151+
```
152+
153+
You can also provide a custom endpoint URL for testing.
154+
155+
```ruby
156+
crowdin.graphql({ query: query }, url: 'http://localhost:3000/api/graphql')
157+
```
158+
137159
### Fetch all records
138160

139161
There is a possibility to fetch all records from paginatable methods using `fetch_all` method.

lib/crowdin-api.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ module Crowdin
2323
require 'crowdin-api/core/request'
2424
require 'crowdin-api/core/send_request'
2525
require 'crowdin-api/core/fetch_all_extensions'
26+
require 'crowdin-api/core/graphql_extensions'
2627

2728
# API modules
2829
Crowdin::API_RESOURCES_MODULES.each do |api_resource|

lib/crowdin-api/client/client.rb

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,10 @@ class Client
3131
end
3232

3333
include Web::FetchAllExtensions
34+
include Web::GraphqlExtensions
3435

35-
# Config instance that includes configuration options for the Client
36-
attr_reader :config
37-
# Instance with established connection through RestClient to the Crowdin API
38-
attr_reader :connection
39-
# Instance with options and headers for RestClient connection
40-
attr_reader :options
41-
# Logger instance
42-
attr_reader :logger
36+
# Client configuration, connection, request options, and logger instances
37+
attr_reader :config, :connection, :options, :logger
4338

4439
def initialize(&block)
4540
build_configuration(&block)
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# frozen_string_literal: true
2+
3+
module Crowdin
4+
module Web
5+
module GraphqlExtensions
6+
def graphql(query = nil, **request_options)
7+
url = request_options.delete(:url)
8+
graphql_query = query || request_options
9+
10+
response = ::RestClient::Request.execute(
11+
{
12+
method: :post,
13+
url: url || "#{config.base_url}/api/graphql",
14+
payload: graphql_query.to_json
15+
}.merge(options)
16+
) { |res, _, _| res }
17+
18+
response.body.empty? ? response.code : JSON.parse(response.body)
19+
end
20+
end
21+
end
22+
end

spec/unit/client_spec.rb

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,53 @@
9898
end
9999
end
100100

101+
describe 'Crowdin Client graphql' do
102+
let(:graphql_request) do
103+
{
104+
query: 'query Viewer { viewer { id } }',
105+
operationName: 'Viewer',
106+
variables: { projectId: 1, emptyValue: nil }
107+
}
108+
end
109+
let(:graphql_response) { { 'data' => { 'viewer' => { 'id' => 1 } } } }
110+
111+
it 'posts to the default GraphQL endpoint', :default do
112+
stub_request(:post, 'https://api.crowdin.com/api/graphql')
113+
.with(body: graphql_request.to_json)
114+
.to_return(body: graphql_response.to_json)
115+
116+
expect(@crowdin.graphql(graphql_request)).to eq(graphql_response)
117+
end
118+
119+
it 'posts to the Enterprise GraphQL endpoint', :enterprise do
120+
stub_request(:post, 'https://domain.api.crowdin.com/api/graphql')
121+
.with(body: graphql_request.to_json)
122+
.to_return(body: graphql_response.to_json)
123+
124+
expect(@crowdin.graphql(graphql_request)).to eq(graphql_response)
125+
end
126+
127+
it 'supports a custom GraphQL endpoint URL', :default do
128+
custom_url = 'http://localhost:3000/api/graphql'
129+
130+
stub_request(:post, custom_url)
131+
.with(body: graphql_request.to_json)
132+
.to_return(body: graphql_response.to_json)
133+
134+
expect(@crowdin.graphql(graphql_request, url: custom_url)).to eq(graphql_response)
135+
end
136+
137+
it 'returns parsed GraphQL error responses', :default do
138+
graphql_error_response = { 'errors' => [{ 'message' => 'Invalid query' }] }
139+
140+
stub_request(:post, 'https://api.crowdin.com/api/graphql')
141+
.with(body: graphql_request.to_json)
142+
.to_return(status: 400, body: graphql_error_response.to_json)
143+
144+
expect(@crowdin.graphql(graphql_request)).to eq(graphql_error_response)
145+
end
146+
end
147+
101148
describe 'connection' do
102149
subject(:connection) { crowdin_client.connection }
103150

0 commit comments

Comments
 (0)