Get dynamic zone type in GraphQL - graphql

I have Strapi set up as a headless CMS and Gatsby on the frontend. In Strapi I have a "Single" type set up with a dynamic zone that the user can use to insert various components to it.
When querying directly from Strapi GraphQL, I can get the component type, like this:
{
inicio {
componentes {
__typename
}
}
}
Which returns:
{
"data": {
"inicio": {
"componentes": [
{
"__typename": "ComponentPaginasCitaBiblica"
},
{
"__typename": "ComponentPaginasAlerta"
},
{
"__typename": "ComponentPaginasTexto"
}
]
}
}
}
However in Gatsby, I get a different result:
query MyQuery {
strapiInicio {
componentes {
__typename
}
}
}
{
"data": {
"strapiInicio": {
"componentes": [
{
"__typename": "StrapiInicioComponentes"
},
{
"__typename": "StrapiInicioComponentes"
},
{
"__typename": "StrapiInicioComponentes"
}
]
}
},
"extensions": {}
}
I need to select different fields depending on the component type and be able to display them correctly on the page, however, __typename is always set to StrapiInicioComponentes. Is there another way to get this from Gatsby?
The GraphiQL explorer doesn't show anything else there:

There is an open bug about this. The fix has been merged, however, at the time of writing, it has only been added to an alpha release, so use at your own risk.
To install the latest alpha version of gatsby-source-strapi with npm, execute:
npm i gatsby-source-strapi#alpha
This adds the component type to strapi_component in the GraphQL.
Or as an alternative, you could try gatsby-source-rest-api, which exposes the component type under _xcomponent.

Related

How to translate multi files by Google translation API?

I'd like to translate multi .pptx files. I'm trying to use Google translate API
My request json file is below.
{
"source_language_code": "ja",
"target_language_codes": ["en"],
"input_configs": {
"gcsSource": {
"inputUri": "gs://project_name/1.pptx"
},
"gcsSource": {
"inputUri": "gs://project_name/2.pptx"
}
},
"output_config": {
"gcsDestination": {
"outputUriPrefix": "gs://project_name/ja-en/"
}
}
}
I got this error, when I request translation API.
"description": "Invalid value at 'input_configs' (oneof), oneof field 'source' is already set. Cannot set 'gcsSource'"
Then I changed second gcsSource to gcsSource1
{
"source_language_code": "ja",
"target_language_codes": ["en"],
"input_configs": {
"gcsSource": {
"inputUri": "gs://project_name/1.pptx"
},
"gcsSource1": {
"inputUri": "gs://project_name/2.pptx"
}
},
"output_config": {
"gcsDestination": {
"outputUriPrefix": "gs://project_name/ja-en/"
}
}
}
The result was below.
"description": "Invalid JSON payload received. Unknown name \"gcsSource1\" at 'input_configs': Cannot find field."
gcsSource1 was used 2 times in the document
How should I chagne request json file, for translate multi files by translation API?
Endpoint is this. "https://translation.googleapis.com/v3/projects/project_name/locations/us-central1:batchTranslateDocument"
Note
Single file translation works fine.
{
"source_language_code": "ja",
"target_language_codes": ["en"],
"input_configs": {
"gcsSource": {
"inputUri": "gs://project_name/1.pptx"
},
},
"output_config": {
"gcsDestination": {
"outputUriPrefix": "gs://project_name/ja-en/"
}
}
}
The issue is with the curly braces used within input_configs. Since you want to use multiple elements, input_configs should be an array. So you should switch the curly braces with square braces as follows:
"input_configs": [
{
"gcsSource": {
"inputUri": "gs://bucket_name/1.pptx"
}
},
{
"gcsSource": {
"inputUri": "gs://bucket_name/2.pptx"
}
}
]
Also, you cannot change the names of json keys, as the structure of request.json which will be passed to the endpoint should be as mentioned in the documentation. This is the reason that when you change the key to “gcsSource1”, it gives you an error with “Cannot find field”.

grpc/protobuffer ask for specific fields

GraphQL lets you ask for specific fields, the response contains only the fields that you had asked for. For example:
a graphql query like:
{
hero {
name
}
}
will return:
{
"data": {
"hero": {
"name": "R2-D2"
}
}
}
where as a graphQl query like:
{
hero {
name
friends {
name
}
}
}
would return:
{
"data": {
"hero": {
"name": "R2-D2",
"friends": [
{
"name": "Luke"
},
{
"name": "Han Solo"
},
{
"name": "Leia"
}
]
}
}
}
Is there a similar mechanism/library/pattern that can be used in gRPC to achieve the same?
FieldMask is similar in protobuf. It is a list of fields to retain, so the first example would be paths: "hero.name" and the second would be paths: ["hero.name", "hero.friends.name"].
It is probably most frequently used to specify which fields should be changed in an update. But it can equally be used to specify the fields that should be returned.
The server can either process the FieldMask directly (e.g., only using the listed fields in a SELECT SQL query), or it can retrieve all the information and filter the result using FieldMaskUtil.merge() to copy just the requested fields into a new proto message to return to the client.

GraphQL Query access all transformed json files within a folder located in subdirectories

I have a project structure like so:
-$PROJECT
--src
---data
----projects
-----project1
------project.json
------images
-------project1-preview.png
-----project2
------project.json
-------images
...
And so on, for however many projects. I could query these project.json files when they were named the title of the project and within a projects folder using allProjectsJson in graphQl, however now they are within subfolders within projects. I can only query them individually as allProject1Json and so on. Is there a way to query allProjectsJson so I get all the project.json files?
I can find my projects files by querying allFile with a filter for json files, however, these files are not transformed json so I can't access the elements.
In my gatsby-config file I am importing src/data as a source for files.
From my answer at https://github.com/gatsbyjs/gatsby/issues/20734:
Ahh, I see what you mean :)
luckily gatsby-transformer-json has a plugin option that will help get you unstuck!
It's the typeName option. You should be able to check for a field on each JSON node, and use that as the type name. Something like this:
{
resolve: `gatsby-transformer-json`,
options: {
typeName: ({ node, object, isArray }) =>
object.project ? `Project` : `Json`,
},
},
That way anything with the field project defined will show up as allProject { ... }, where any other json files will show up as allJson { ... }
{
allProject {
nodes {
project
}
}
}
{
"data": {
"allProject": {
"nodes": [
{
"project": "project1"
},
{
"project": "project2"
}
]
}
}
}
My project works very similarly. Here's how I have my gatsby-config.js setup:
module.exports = {
...
plugins: [
...,
{
resolve: 'gatsby-source-filesystem',
options: {
name: 'project', // Identifier. Will then be queried as `allProjectsJson`
path: './data', // Source folder containing the JSON files
},
},
...,
]
};
Example JSON file:
[
{
"title": "Hello",
"description": "World",
"url": "https://www.google.com",
"image": "./images/img1.jpg"
},
{
"title": "World",
"description": "Hello",
"url": "https://www.google.com",
"image": "./images/img2.jpg"
},
]
Example query:
query projects {
allProjectsJson {
edges {
node {
id
title
description
url
image {
childImageSharp {
fluid {
...GatsbyImageSharpFluid
}
}
}
}
}
}
}
Hope this helps!

GraphQL Github API formatting

I am wondering how to deal with the following problem. I am using GraphQL to query the v4 Github API with the following query:
{
viewer {
repositories(first: 30) {
edges {
node {
name
}
}
}
}
}
This gets me a response that looks like so:
{
"data": {
"viewer": {
"repositories": {
"edges": [
{
"node": {
"name": "test-repo"
}
},
{
"node": {
"name": "another-repo"
}
}
]
}
}
}
}
I am pretty new to GraphQL, I understand that in my query I need to provide the edges and nodes but I would rather get a response back in this kind of way because I am not interested to know about "edges" and "nodes" in my frontend:
{
"data": {
"viewer": {
"repositories": [
{
"name": "test-repo"
},
{
"name": "another-repo"
}
]
}
}
}
}
I am guessing this kind of response is normal for GraphQL but it would be pretty cumbersome to rewrite to response all the time for easier usage in my frontend. Is there some way to emit the "edges" and "nodes" and get the formatting that I would like or is this simply all up to me to deal with?
I have looked at some libraries like Apollo but I have no idea is this is a right fit to deal with things like this. Hopefully someone a bit more experienced with GraphQL could tell me something more.
Sometimes, services provides two endpoints: Relay endpoint (with edges and nodes) and simple endpoint.
Looks like GitHub only have a Relay endpoint. In this case, the only thing you can do is to manually format the response on your frontend.
Actually, such complex response structure is needed because we often need to do a pagination. Take a look at the example:
{
getArticle(id: "some-id") {
id
userId
user {
id
name
}
tags(first: 10, after: "opaqueCursor") {
edges {
node {
id
name
itemsCount
}
}
pageInfo {
hasNextPage
hasPreviousPage
endCursor
startCursor
}
}
}
}
pageInfo is located at the same level as edges.
So if you later will need to do a pagination, it would be better to keep the response format as is.
You can remove the edges query if you know you aren't searching along those relationships. Cursor-based pagination will work by checking the pageInfo value hasNextPage and using endCursor as the after query parameter:
viewer {
repositories(first: 30,after:"<CURSOR_STRING>") {
totalCount
pageInfo{
hasNextPage
endCursor
}
nodes{
name
}
}
}
returns
"viewer": {
"repositories": {
"totalCount": 38,
"pageInfo": {
"hasNextPage": true,
"endCursor": "Y3Vyc29yOnYyOpHOAl/5mw=="
},
"nodes": [
{
"name": "AllStarRoom"
},
{
"name": "shimsham"
},
{
"name": "Monitor-Docs"
}
]
}
}

How to return object type with union query results in GraphQL?

I'm building a GraphQL API. When returning a union / interface type field, is it possible to have the server tell me the object type? i.e. something like this
{
search(text: "an") {
... on Human {
__type
name
height
}
... on Droid {
__type
name
primaryFunction
}
... on Starship {
name
length
}
}
}
// or even better
{
search(text: "an") {
__type // <--- even though it's a Union query, everything has a type right? :/
... on Human {
name
height
}
... on Droid {
name
primaryFunction
}
... on Starship {
name
length
}
}
}
which would return
{
"data": {
"search": [
{
"__type": "Human",
"name": "Han Solo",
"height": 1.8
},
{
"__type": "Human",
"name": "Leia Organa",
"height": 1.5
},
{
"name": "TIE Advanced x1",
"length": 9.2
}
]
}
}
Obviously, I could manually add this functionality by adding "type" fields to objects as needed, but I imagine something like this is already built into GraphQL? Seeing as all of the objects already have names. Basically I'm trying to access introspection information as part of a normal query.
This is possible using the special meta field __typename, which is available on all Graphql objects and returns the object's Graphql type name. See http://graphql.org/learn/queries/#meta-fields for more info.
PS: it looks like __typename is the only meta field that can be called outside of an introspection query.
Used like:
{
search(text: "an") {
__typename
... on Human {
name
}
... on Droid {
name
}
... on Starship {
name
}
}
}

Resources