
In the previous part, we set up the structure of the application, in this article we will set up the Strapi API and display a list of restaurants.
Note: The source code for the entire series of articles is available here .
We create restaurants
First of all, we need to display a list of restaurants in our application. Of course, we will manage this list through the Strapi API, so let's configure it.
Content Type
Content Type, (model
). Strapi API user
. , restaurant
( ).
:

Restaurant
.
! , . Restaurant .
Content Manager
, , .
-
Add New Restaurant
-
name
, description
image
.

— . API . restaurant
, Strapi api/restaurant
. , CRUD API. find
: http://localhost:1337/restaurants.
URL, 403 . : Strapi API .
, :
: authenticated
http://localhost:1337/restaurants, .

GraphQL
API REST . , GraphQL 10 ?
.
GraphQL Strapi, /backend
:
yarn strapi install graphql
#
npm run strapi install graphql
, .

{
restaurants {
id # _id MongoDB
name
}
}

, :
- GraphQL @nuxt-apollo
/frontend
yarn add @nuxtjs/apollo graphql
#
npm install @nuxtjs/apollo graphql
apollo nuxt.config.js
:
...
modules: [ '@nuxtjs/apollo',
],
apollo: { clientConfigs: { default: { httpEndpoint: 'http://localhost:1337/graphql' } }
},
...
. Nuxt ? .
./pages/restaurants/index.vue
:
<template>
<div>
//
<form class="uk-search uk-search-large uk-align-center uk-margin">
<span uk-search-icon></span>
<input class="uk-search-input" v-model="query" type="search" placeholder="Search...">
</form>
//
<div class="uk-card uk-card-default uk-grid-collapse uk-child-width-1-2@m uk-margin" v-for="restaurant in filteredList" v-bind:key="restaurant" uk-grid>
<div class="uk-card-media-left uk-cover-container">
<img :src="'http://localhost:1337/' + restaurant.image.url" alt="" uk-cover>
<canvas width="600" height="400"></canvas>
</div>
<div>
<div class="uk-card-body">
<h3 class="uk-card-title">{{ restaurant.name }}</h3>
<p>{{ restaurant.description }}</p>
//
<router-link :to="{ name: 'restaurants-id', params: { id: restaurant.id }}" tag="a" class="uk-button uk-button-primary">See dishes
</router-link>
</div>
</div>
</div>
//
<div class="uk-container uk-container-center uk-text-center" v-if="filteredList.length == 0">
<img src="https://assets-ouch.icons8.com/preview/19/52de2377-696e-4194-8c63-0a81aef60b4f.png" height="800" width="800">
<p>No restaurants found</p>
</div>
</div>
</template>
<script>
import restaurantsQuery from '~/apollo/queries/restaurant/restaurants'
export default {
data() {
return {
restaurants: [],
query: ''
}
},
apollo: {
restaurants: {
prefetch: true,
query: restaurantsQuery
}
},
computed: {
filteredList() {
return this.restaurants.filter(restaurant => {
return restaurant.name.toLowerCase().includes(this.query.toLowerCase())
})
},
}
}
</script>
?
— . Vue.js .
, Vue.js:
v-for
: (restaurants
).v-if
: .v-model
: . .vue-router
: .
.
GraphQL
, restaurantsQuery
GraphQL apollo :
...
apollo: { restaurants: { prefetch: true, query: restaurantsQuery }
},
...
Strapi API.
/frontend/apollo/queries/restaurant/restaurants.gql
:
query Restaurants {
restaurants {
id
name
description
image {
url
}
}
}
! !
.