MSON to describe object attributes in blueprint - apiblueprint

I have an issue similar to what is described here.
I have a JSON that looks like this:
{
"photos": [
{
"key": "y37dmj10jkwof/moOIUB8912JKVgh",
"caption": "A world of gamers.",
"tags": [
"game",
"japan"
],
"attributes": {
"copyright": true,
"use": [
"public",
"private"
]
}
}
]
}
and I am trying to describe the attributes using MSON, to render the blueprint. However, I am not successful at it. Here is my attempt:
+ Attributes (required, object)
+ photos (required, array)
+ (object)
+ key (required, string) - Photo key
+ caption (required, string) - Photo caption
+ tags (required, array)
+ game (string)
+ japan (string)
+ attributes (required, object)
+ (object)
+ copyright: true (required, boolean)
+ uses (required, array)
+ public (string)
+ private (string)
Ideas anyone?
Any input would be highly appreciated.

Here's an example that I think does what you want:
+ Attributes
+ photos (required, array)
+ (object)
+ key: y37dmj10jkwof/moOIUB8912JKVgh (required) - Photo key
+ caption: A world of gamers (required) - Photo caption
+ tags: game, japan (required, array)
+ attributes (required)
+ copyright: true (required, boolean)
+ use: public, private (required, array)
Note that you can put the sample values for the arrays as a comma separated list, and there's usually no need to explicitly state when the type is a string or object (unless it has no name). As for the attributes object, you can put the keys on it directly, no need to make another level with + (object)
Hope this helps!

Related

Using graphql playground to test Saleor productCreate, what's the correct syntax for adding a product description?

In the code example below, if I exclude the description field the product is created successfully. With the description field in place I get a GraphQL error.
The code:
productCreate(
input: {
category: "Q2F0ZWdvcnk6MQ==", # Category ID
name: "Delete Me!", # Product name
productType: "UHJvZHVjdFR5cGU6MQ==", # Product Type ID
chargeTaxes: true,
weight: "0.3", # in Kg
rating: 5,
description: {text:"some text"}, # nope
}
)
The error:
graphql.error.base.GraphQLError: Argument \"input\" has invalid value {category: \"Q2F0ZWdvcnk6MQ==\", name: \"Delete Me!\", productType: \"UHJvZHVjdFR5cGU6MQ==\", chargeTaxes: true, weight: \"0.3\", rating: 5, description: {text: \"some text\"}}.",
"In field \"description\": Expected type \"JSONString\", found {text: \"some text\"}."
It is a string, for rich text it is using https://editorjs.io/
You can inspect the network tab in the dashboard to learn how APIs are being used
JSON string means providing a JSON text converted to a string. This can be achieved by escaping quotation marks within the JSON.
For example, this JSON
{ "text": "some text" }
can be converted to String as below:
"{\"text\":\"sometext\"}"
As you notice that the text encapsulated inside quotation marks, to be a valid String.
You can use https://jsontostring.com/ for the conversion
Your final code should be like this:
mutation {
productCreate(
input: {
category: "Q2F0ZWdvcnk6MQ==" # Category ID
name: "Delete Me!" # Product name
productType: "UHJvZHVjdFR5cGU6MQ==" # Product Type ID
chargeTaxes: true
weight: "0.3" # in Kg
rating: 5
description: "{\"text\":\"sometext\"}" # nope
}
){
product{
id
}
}
}
Sorting out the description syntax wasn't straightforward. From my question here:
Saleor on Github
I got this answer:
{
"id": "UHJvZHVjdDo3Mg==",
"description": "{\"blocks\":[{\"type\":\"paragraph\",\"data\":{\"text\":\"New description\"}}]}"
}
which I then implemented like this:
query = gql(
"""
mutation (
$slug: String!,
$product_title: String!,
$description: JSONString!,
$weight_grams: WeightScalar!,
)
{
productCreate(
input:{
category: "Q2F0ZWdvcnk6NQ==",
name: $product_title,
productType: "UHJvZHVjdFR5cGU6MQ==",
slug: $slug,
description: $description,
weight: $weight_grams,
}
)
{
errors {
field
message
}
product {
id
name
productType {
id
}
slug
}
}
}
"""
)
params = {
"product_title": str(product_title),
"description": '{"blocks":[{"type":"paragraph","data":{"text":"'
+ str(product_title + " (" + csv_product_id + ")")
+ '"}}]}',
"slug": str(csv_sku_code),
"weight_grams": str(weight_grams),
}
result = client.execute(query, variable_values=params)
This works well for us.

Prisma graphql computed fields

I have this datamodel:
type Item {
id: ID! #unique
title: String!
description: String!
user: User!
pictures: [Picture]
basePrice: Int!
addons: [Addon]
}
I'm writing a query called parsedItem that takes the id from arguments and looks for the Item (using the default query for Item generated by Prisma), something like this:
const where = { id: args.id };
const item = await ctx.db.query.item({ where },
`{
id
title
...
I need to show on the frontend a computed value: "dynamicPrice" it depends on the quantity of the Addons that the Item has.
e.g:
Item #1 has 3 addons, each addons has a value of $5. This calculated value should be
dynamicPrice = basePrice + 3 * 5
The Addon relation could change, so I need to compute this in every request the frontend makes.
I'd like so much to do something like:
item.dynamicPrice = item.basePrice + (item.addons.length * 5)
and return this item in the resolver, but this doesn't work. That throw an error:
"message": "Cannot query field \"dynamicPrice\" on type \"Item\"."
(when I try to query the Item from the frontend)
This error message makes me think: Should I create dynamicPrice as a field on the datamodel? Can I then populate this field in the query resolver? I know I can, but is this a good approach?
This is an example, I need to create more computed values for this Item model.
What is the best scalable solution/workaround for this simple use case?
You need create field resolver for dynamicPrice field at Item type. It will looks like that:
const resolvers = {
Query: {
parsedItem: (parent, args, ctx, info) => {
...
}
...
},
Item: {
dynamicPrice: parent => parent.basePrice + parent.addons.length * 5
}
}
More details you can find at A Guide to Common Resolver Patterns.

How to reference enum value in API Blueprint(MSON)

I'm using API Blueprint and Agilo to render my API documentation. When using enum type, I'm observing a weird behavior. The response is not shown with the defined enum value whereas the schema is showing all the enum values (which is expected) along with the declared value ('Monday'- Refer Actual) as well.
Data Structure section
# Data Structures
## Days (enum[string])
+ `Monday`
+ `Tuesday`
+ `Wednesday`
+ `Thursday`
## ListEntry
- playOrder: 1 (number)
- Id: 37a21975a499494f03367 (string)
- programDay: `Tuesday` (Days)
## `sample-request-200`
- id: 58828b2941cc351348 (string)
- startDate: `2019-08-01T11:00:00.000Z` (string)
- endDate: `2019-08-05T11:55:59.000Z` (string)
- Language: `en-US` (string)
- entries: ListEntry (array[object])
API Request Doc section
+ Request
+ Headers
Content-Type: application/json
+ Attributes (sample-request-200)
Actual
---- JSON Body ----
{
"playOrder": 1,
"Id": "37a21975a499494f03367",
"programDay": "Hello, world!" // Agilo shows "Hello,World" when some error occurred
}
-----Generated Schema-----
"programDay": {
"type": "string",
"enum": [
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Monday"
]
}
Desired
---- JSON Body ----
{
"playOrder": 1,
"Id": "37a21975a499494f03367",
"programDay": "Monday"
}
-----Generated Schema-----
"programDay": {
"type": "string",
"enum": [
"Monday",
"Tuesday",
"Wednesday",
"Thursday"
]
}
Any idea on how to use the defined enum data structure in API blueprint (MSON). Not sure how to reference an enum value in the Object.
Is it right to use as below to reference an enum value?
- programDay: `Tuesday` (Days)
Structure:
# Data Structures
## Device (enum)
+ `mobile`
+ `desktop`
Use like this:
+ Request (multipart/form-data)
+ Attributes
+ `id`: abc (required)
+ `device` (Device)
Results:

MSON Array Object "undefined" Error in API Blueprint

We are developing a new API using HAL+JSON, leveraging Apiary.io's API Blueprint. We have been using JSON in our responses within the Blueprint itself. I'm testing a shift to using MSON instead, but am having an issue with an array object.
Here is the API Blueprint code. Everything works great, except for the curies array (toward the bottom), which contains one object.
FORMAT: 1A
# Content API
An API for retrieving content from NBC News Group.
# Group Root resource
The starting point for the Content API.
## Root Resource [/]
### Request root resource [GET]
+ Response 200 (application/hal+json)
+ Attributes (required, object)
+ _links (object) - Linked resources in HAL
+ self (required, object) - Self link to current document
+ href: / (required, string) - URI of this resource
+ profile: `http://domain.com/docs/profiles/root` (required, string) - URI to profile description for this resource
+ `nbng:content` (object) - Link relation to all content
+ href: `http://apiary-mock.com/content` (required, string) - URI to content
+ title: Browse all NBC News Group content (required, string) - title of the link relation
+ `nbcng:publishers` (object) - Link relation to all publishers
+ href: `http://apiary-mock.com/publishers` (required, string) - URI to publishers
+ title: Browse all NBC News Group publishers (required, string) - title of the link relation
+ `nbcng:publisher` (object) - Link relation to an individual publisher
+ href: `http://apiary-mock.com/publisher/{id}` (required, string) - URI to an individual publisher, with `{id}` query string param
+ templated: true (required, boolean) - Notes if the link has a URI template associated to it
+ title: Get a publisher by name (required, string) - title of the link relation
+ curies (required, array) - Link relation to documentation
+ (object)
+ href: `http://www.domain.com/docs/relation/nbcng/{rel}` (required, string) - URI to documentation
+ name: nbcng (required, string) - prefix of the link relation documentation is tied to
+ title: NBC News Group Link Relation (required, string) - title of the link relation
+ templated: true (required, boolean) - Notes if the link has a URI template associated to it
+ welcome: Welcome to the NBC News Group Content API (required, string) - Welcome message for resource
For that curies array, the API Blueprint output in JSON returns:
"curies": [
{
"undefined": null
}
]
When what is expected would be JSON that looks like this:
"curies": [
{
"href": "http://www.nbcnewsdigitaldev.com/docs/relation/nbcng/{rel}",
"name": "nbcng",
"title": "NBC News Group Link Relation",
"templated": true
}
]
Insofar as I can tell from the MSON specification, the syntax for the curies array and object are correct.
Would love any feedback from folks who've been on a similar MSON exploration.
I've run into a fair share of strange behavior with API Blueprint, MSON, and nested structures. In this case, you would assume what you did would work, or maybe specifying it as
+ curies (required, array) - Link relation to documentation
+ Attributes (object)
+ href: `http://www.domain.com/docs/relation/nbcng/{rel}` (required, string) - URI to documentation
+ name: nbcng (required, string) - prefix of the link relation documentation is tied to
+ title: NBC News Group Link Relation (required, string) - title of the link relation
+ templated: true (required, boolean) - Notes if the link has a URI template associated to it
That was still broken for me. But if you use Data Structures that seems to get it to render properly
FORMAT: 1A
# Content API
An API for retrieving content from NBC News Group.
# Group Root resource
The starting point for the Content API.
## Root Resource [/]
### Request root resource [GET]
+ Response 200 (application/hal+json)
+ Attributes (required, object)
+ _links (object) - Linked resources in HAL
+ self (required, object) - Self link to current document
+ href: / (required, string) - URI of this resource
+ profile: `http://domain.com/docs/profiles/root` (required, string) - URI to profile description for this resource
+ `nbng:content` (object) - Link relation to all content
+ href: `http://apiary-mock.com/content` (required, string) - URI to content
+ title: Browse all NBC News Group content (required, string) - title of the link relation
+ `nbcng:publishers` (object) - Link relation to all publishers
+ href: `http://apiary-mock.com/publishers` (required, string) - URI to publishers
+ title: Browse all NBC News Group publishers (required, string) - title of the link relation
+ `nbcng:publisher` (object) - Link relation to an individual publisher
+ href: `http://apiary-mock.com/publisher/{id}` (required, string) - URI to an individual publisher, with `{id}` query string param
+ templated: true (required, boolean) - Notes if the link has a URI template associated to it
+ title: Get a publisher by name (required, string) - title of the link relation
+ curies (required, array) - Link relation to documentation
+ Attributes (Cury)
+ welcome: Welcome to the NBC News Group Content API (required, string) - Welcome message for resource
# Data Structures
## Cury (object)
+ href: `http://www.domain.com/docs/relation/nbcng/{rel}` (required, string) - URI to documentation
+ name: nbcng (required, string) - prefix of the link relation documentation is tied to
+ title: NBC News Group Link Relation (required, string) - title of the link relation
+ templated: true (required, boolean) - Notes if the link has a URI template associated to it
Which rendered the endpoint with a response of
{
"_links": {
"self": {
"href": "/",
"profile": "http://domain.com/docs/profiles/root"
},
"nbng:content": {
"href": "http://apiary-mock.com/content",
"title": "Browse all NBC News Group content"
},
"nbcng:publishers": {
"href": "http://apiary-mock.com/publishers",
"title": "Browse all NBC News Group publishers"
},
"nbcng:publisher": {
"href": "http://apiary-mock.com/publisher/{id}",
"templated": true,
"title": "Get a publisher by name"
},
"curies": [
{
"href": "http://www.domain.com/docs/relation/nbcng/{rel}",
"name": "nbcng",
"title": "NBC News Group Link Relation",
"templated": true
}
]
},
"welcome": "Welcome to the NBC News Group Content API"
}

Couchbase CRUD operations with query language

Im using couchbase 4.0 beta version. And Im successfully able to save the objects into the bucket using rest service. Now I need to access the bucket and do GET, UPDATE and DELETE operations using queries.
This is the my sample object in bucket.
{
"id": "friend$43403778",
"domain": "FRIEND",
"profileId": 43403778,
"screenName": "49ers",
"name": "San Francisco 49ers",
"profileUrl": "http://twitter.com/49ers",
"description": "Official Twitter account of the five-time Super Bowl Champion San Francisco #49ers.",
"friendsCount": 121,
"followersCount": 964650,
"timeZone": "Pacific Time (US & Canada)",
"utcOffset": -25200,
"location": "Santa Clara, CA",
"profileCreated": 1243629277000
}
Now I want to get this object using id. But id value contains special character so my query doesn't works for it. How can I access it???
This is my code snippet which I tried to get this.It doesn't gives me the 300 error code syntax error.
String strQuery = "SELECT * FROM twitter WHERE id=" + id;
Bucket bucket = singletonBucket.getBucket();
QueryResult queryResult = bucket.query(Query.simple(strQuery));
List<QueryRow> result = Collections.emptyList();
if (!queryResult.finalSuccess()) {
log.error("Error occur while retrieving TwitterProfile document for id: {}",id);
String errorStr = "";
for (JsonObject error : queryResult.errors()) {
errorStr = error.toString() + ". ";
log.error("{}", error);
}
throw new DataAccessException(errorStr);
} else {
result = queryResult.allRows();
for(QueryRow row: result){
Object doc = row.value().get(AppConstants.BUCKET_NAME);
TwitterProfile twitterProfile = objectMapper.readValue(doc.toString(), TwitterProfile.class);
twitterProfileList.add(twitterProfile);
}
log.info("Successfully found {} TwitterProfile record for id {}",twitterProfileList.size(), id);
return twitterProfileList.size()>0 ?twitterProfileList.get(0):"";
}
If I tried to get the record using profileId It also doesnt work.
How can I write the simple queries for this bucket.
These are the queries which I tried. Also my bucket name is twitter
String strQuery = "SELECT * FROM twitter WHERE domain=" + AppConstants.DOMAIN_FRIEND;
String strQuery = "DELETE FROM twitter WHERE domain=" + AppConstants.DOMAIN_FRIEND;
Thanks in advance.
When building your query you have to use quotes to indicate your id is a string. Try adding quotes around your id when building your query:
String strQuery = "SELECT * FROM twitter WHERE id='" + id + "'";

Resources