How do I include linked entries when updating Algolia from Contentful? - algolia

I'm currently using a Contentful webhook to automatically update Algolia when a Contentful entry is published.
My content model on Contentful looks something like this:
MOVIE:
{ title: string,
director: reference }
DIRECTOR:
{ name: string }
I am sending content to Algolia via the Contentful webhook. Currently, the data I'm sending looks like this:
title: "Vertigo",
director: {
sys: {
type: "Link",
linkType: "Entry",
id: 123456789
}
}
Instead, I would like it to be:
title: "Vertigo",
director: {
name: "Alfred Hitchcock"
}
How can I include the full data from the linked entry, rather than just the ID? For the record, I'm using a custom webhook payload, which looks basically like this:
{
"title": "{ /payload/fields/title/en-US }",
"director": "{ /payload/fields/director }"
}

Per the documentation, to follow links, you're going to have to move beyond the out-of-the-box webhook and write your own connection.
Inclusion of referenced item data in webhooks Depending on your use
case you might want to index an entry and all the data that it links
because it it is a composition of different Contentful entities.
Reference entry data is not available in the webhook payload and it’s
recommended to write your own logic to feed Algolia then. The
Contentful client libraries provide a way to retrieve linked data.
Source: https://www.contentful.com/developers/docs/tutorials/general/enhancing-search-experience-with-algolia/

Related

How to connect to Actions builder project to update type entities?

I've got a project build migrated from AOG + Dialogflow to Actions Builder. I need to update (or insert new) type entries with the REST API.
To do that action I've found an endpoint, that gives the ability to update the whole project along with entities:
https://developers.google.com/assistant/actions/api/reference/rest/v2/projects.draft/write
However, I can't connect to that endpoint due to 401 error. Before that I've tried to emulate a similar request to another endpoint, which allows reading the project:
https://developers.google.com/assistant/actions/api/reference/rest/v2/projects.draft/read
Obviously, I've got the same error here.
Also, I've found this repo - https://github.com/actions-on-google/assistant-actions-nodejs
which adds a wrapper for easier manipulation with the REST API, but it also doesn't contain any information on how to properly authorize to get access to an app.
Can please somebody suggest how authorization should be done to start using this REST API?
Using Actions Builder, the type entities can be updated directly in your webhook calls rather than calling an API in parallel.
Look up the names of the types you want to override in Actions Builder and set the conv.session.typeOverrides field in your response.
Here's a code example of how it might be done:
const app = conversation()
// `app.middleware` will run on every invocation call
app.middleware(conv => {
// ...
// Obtain `trackTitles` and `trackGenres`
// ...
conv.session.typeOverrides = [{
name: 'track',
mode: Mode.TypeReplace,
synonym: {
entries: Array.from(trackTitles).map(title => ({
name: title,
synonyms: [title],
})),
},
}, {
name: 'genre',
mode: Mode.TypeReplace,
synonym: {
entries: Array.from(trackGenres).map(genre => ({
name: genre,
synonyms: [genre]
}))
}
}]
})

AWS Api Gateway Documentation - cant create schema

Today i got into swagger and swagger-ui to create the documentation of our API.
We are using AWS API Gateway with a Lambda function, since AWS is comming with an in-built option for documentation we are going with it.
Sadly, I am pretty limited with this option or I am doing it wrong.
As an example
responses:
'200':
description: 200 response
schema:
$ref: '#/definitions/Empty'
I can´t create an alternative schema, nor im able to edit the existing /Empty schema.
Is there a solution for my problem?
For example
... to not use an schema and just write the whole response in there?
... to show me how to create an alternative schema?
EDIT
For me it seems like an AWS problem, not my swagger file in generall. If someone reads over this i added more informations.
It doesnt matter if i use "create Documetation Part" --> Type = Response (Body) or i go to Ressources --> Method which i want to set the Response (Body) --> Method Response and set the Respone Body to an Modell.
My Modell looks like this
{
{
"$schema": "http://json-schema.org/draft-04/schema#",
"description" : "Example Promotion",
"title" : "Promotion",
"type" : "object",
"properties" : {
"Status" : { "type" : "string"}
}
}
}
It gives me no error, but if i go to "Publish Documentation" it seems to no put the Respone (Body) i set into the swagger.json on the Method Response part, nor on the Defenitions at the end of the file and set the schema path right.
I found it easier to not use $ref when I was starting out. After you have the knack how to write requests or response definitions, you can easily transition to referencing schemas using $ref.
What comes after schema statement? That depends on what you expect to be returned -- text, an array, a JSON object, or an array of JSON objects, etc. Typically it's the later two. So here is an example of each.
schema:
type: object
description: This is a JSON object
properties:
fullName:
type: string
age:
type: number
which defines: { fullName: "Jane Smith", age: 30 }
schema:
type: array
description: This is an array of JSON object
items:
type: object
properties:
carMake:
type: string
carModel:
type: string
which defines: [{ carMake: "Ford", carModel: "Mustang" } ... ]
Clone github's swagger-ui onto your computer and run it as a local server. Or you have free use of the SwaggerHub if you don't mind the API definition to be public (or, after a trial period, pay for your APIs to be private).
The specification has changed over the years, so its important to know whether you are dealing with swagger v2 or openapi v3. www.swagger.io has a good multi-page tutorial. And you can find several public API examples at the SwaggerHub website. I do not work for Smartbear, the originators of both the original swagger spec and swaggerhub tooling, but I've found them to be very helpful in the past. Some of their staff monitor this website and answer questions.
Good luck!

RESTful API design - how to handle foreign keys?

I'm designing a RESTful API and I'm trying to figure out how to show and update foreign keys for resources.
Let's I have an object User and it has an id, name and a foreign key (many-to-one relation) to entity: Computer.
What I see in most of the examples online:
GET /users/1
{
id: 1,
name: "Bob",
computer: "<url>/computers/5"
}
Which I can understand, it's a link to another resource. But what do you do when you want to pick another computer for bob?
PUT /users/1
{
name: "Bob",
computer: "<url>/computers/4"
}
This feels really weird.
I'm also thinking about the following case: Say the person that has to implement the API can choose a computer for Bob using a dropdown and the current one should be selected, I'd need the id to do that. Do I have to parse the url myself to chop off the id?
Is there a reason why I should not just do:
GET /users/1
{
id: 1,
name: "Bob",
computerId: 5
}
PUT /users/1
{
name: "Bob",
computerId: 4
}
I would be tempted to formalise the HATEOAS a little here and have:
GET /users/1
{
links: [
{ rel: "computer", href: "/users/1/computers/5" },
],
user: {
id: 1,
name: "Bob",
computer: 5,
}
}
PUT /users/1
{
name: "Bob",
computer: 4,
}
GET /users/1
{
links: [
{ rel: "computer", href: "/users/1/computers/4" },
],
user: {
id: 1,
name: "Bob",
computer: 4,
}
}
The link URLs can obviously be /computers/n if that's your preference.
This allows your representations to consistently be just data, AND the body of GETs to supply the URLs that your application can use. This way, if you change your URL hierarchy (i.e from /computers/n to /users/m/computers/n) you do not need to change any client code that manually constructs URLs.
By GET you have to use the link to meet with the HATEOAS constraint.
{
id: 1,
name: "Bob",
computer: {uri: "<url>/computers/5"}
}
By PUT you can use the id
{
name: "Bob",
computer: {id: 4}
}
The idea about this that the URIs (or URI templates) must be generated by the server. So the client does not have to know how to build an URI, which makes the service+client code DRY, or in other terms it loosens the coupling between the client and the service implementation.
(You can use a standard (or a draft) solution instead of your custom one to describe hyperlinks. For example: ATOM, XLink, RDF+Hydra, HAL, etc..)
If you're really embracing HATEOAS, you should just use the URI. The URI is your identifier, not the id field. I would remove that entirely. Sure, inside your application you'll have to parse the URI in the payload -- and you already have the parser, obviously -- but It's better for you to do that than asking the client to do.
If you or your clients are sending id fields other than URIs in the payload, or if you're asking the client to parse URIs and figure out semantics, you're defeating the purpose of using HATEOAS, as the client implementation will be coupled to that semantics. The best thing is to embrace URIs as the only identifiers you'll use to drive the interaction with clients.

API design : Need help for URLs

I'm designing a new website. Before i start to code, i'm learning a lot about api and nosql database (as i'm used to sql but i want to try with mongoDB).
In mongoDB, i'll have a 'user' document like that :
{
firstname: 'xxxxxxx',
lastname: 'xxxxxxx',
projects: [
{
name: 'project xxxxxxx',
participants: [], // array of friends into this project
operations: [
{ title: 'Title OP xxxxxxx', contributors: [] },
{ title: 'Title OP xxxxxxx', contributors: [] },
{ title: 'Title OP xxxxxxx', contributors: [] }
]
}
]
}
I was wondering two things :
Should projects.participantsand projects.operations.contributors be references to other users ?
For the API, should i do something like :
GET /users/:id_user
GET /users/:id_user/projects/:id_project
GET /users/:id_user/projects/:id_project/operations/:id_operation
(should my API always start with users ?)
If you ever have a better solution I will be glad to know.
Thanks
EDIT 1 : I'll work on NodeJS with Express and i would like to have a REST API.
yes, projects.participants and projects.operations.contributors can be reference to other documents in the same collection. Each of these should refer to valid _id in the same collection.
can you please put some more light on how exactly are you creating your APIs? I mean which framework you are using as a wrapper to access mongoDB? May be then I can try to help more.
ok great!!!
So, users is your collection name. Its absolutely not necessary to start your API name with users. In node.js you can create a router, which will route your request to a particular js file and you can name it anything you want. Example:
use case: You want to expose 3 API
1. To access all the users. (exposed using url - /getallusers)
2. To access all the participants of the project.(exposed using url - /getparticipantsbyproject)
3. To access all the contributors in the operations.(exposed using url - /getcontributorsbyproject).
You can write all these APIs in your file called myapi and expose them.
Now, you can very well call these APIs from browser using below urls:
http://host:port/myapi/getallusers
http://host:port/myapi/getparticipantsbyproject
http://host:port/myapi/getcontributorsbyproject
Its about RESTful API only. I mentioned 3 urls above which are nothing but RESTful API exposing different functionalities.

JsonLD+MongoDB: Store JsonLD in MongoDB

I am creating a Desktop application using Node-WebKit. The application is basically to create documents (details of an employee's daily work), any registered user can comment on these documents. The documents that I am creating will be split into sections. The users will comment on particular sections. I want to link these sections with the comments that the users post. The linking will be done using JsonLD. I am using MongoDB to store the data.
I am using sails.js in backend and AngularJs in frontend.
Usually we store our objects in this way:
module.exports = {
attributes: {
document: {
type: 'string'
},
comments: {
collection: 'Comments',
via: 'document'
}
project:{
model: 'Project'
}
}
};
I have done some RnD on JsonLD and according to what I know about JsonLD. This is how the JsonLD will be:
{
"#context":
{
"name": "http://xmlns.com/foaf/0.1/name",
"depiction":
{
"#id": "http://xmlns.com/foaf/0.1/depiction",
"#type": "#id"
},
"homepage":
{
"#id": "http://xmlns.com/foaf/0.1/homepage",
"#type": "#id"
},
}
}
I would like to know how I can store the JsonLD in MongoDB
JSON-LD is valid JSON, so you can store JSON-LD the same way you store JSON objects. What JSON-LD does is to map concepts to URLs but everything remains valid JSON and they look like regular JSON if the context property is used. You can find a good example in slides 22 - 23 of this presentation. Also you may find "JSON-LD and MongoDB" presentation interesting.
I am doing the same thing in a Java backend using the MongoDB java client and I just treat JSON-LD objects as regular JSON objects.