diff --git a/README.md b/README.md index 34db430d..1f1f5726 100644 --- a/README.md +++ b/README.md @@ -60,6 +60,117 @@ These are the default routes set up in the "starter" app. TODO +### Data fetching + +We use Apollo client which allows us to query data with GraphQL. We have setup CKAN API for the demo (it uses demo.ckan.org as DMS): + +http://portal.datopian1.now.sh/ + +Note that we don't have Apollo Server but we connect CKAN API using [`apollo-link-rest`](https://www.apollographql.com/docs/link/links/rest/) module. You can see how it works in [lib/apolloClient.ts](https://github.com/datopian/portal/blob/master/lib/apolloClient.ts) and then have a look at [pages/\_app.tsx](https://github.com/datopian/portal/blob/master/pages/_app.tsx). + +For development/debugging purposes, we suggest installing the Chrome extension - https://chrome.google.com/webstore/detail/apollo-client-developer-t/jdkknkkbebbapilgoeccciglkfbmbnfm. + +#### Pre-fetch data in the server-side + +When visiting a dataset page, you may want to fetch the dataset metadata in the server-side. To do so, you can use `getServerSideProps` function from NextJS: + +```javascript +import { GetServerSideProps } from 'next'; +import { initializeApollo } from '../lib/apolloClient'; +import gql from 'graphql-tag'; + +const QUERY = gql` + query dataset($id: String) { + dataset(id: $id) @rest(type: "Response", path: "package_show?{args}") { + result + } + } +`; + +... + +export const getServerSideProps: GetServerSideProps = async (context) => { + const apolloClient = initializeApollo(); + + await apolloClient.query({ + query: QUERY, + variables: { + id: 'my-dataset' + }, + }); + + return { + props: { + initialApolloState: apolloClient.cache.extract(), + }, + }; +}; +``` + +This would fetch the data from DMS and save it in the Apollo cache so that we can query it again from the components. + +#### Access data from a component + +Consider situation when rendering a component for org info on the dataset page. We already have pre-fetched dataset metadata that includes `organization` property with attributes such as `name`, `title` etc. We can now query only organization part for our `Org` component: + +```javascript +import { useQuery } from '@apollo/react-hooks'; +import gql from 'graphql-tag'; + +export const GET_ORG_QUERY = gql` + query dataset($id: String) { + dataset(id: $id) @rest(type: "Response", path: "package_show?{args}") { + result { + organization { + name + title + image_url + } + } + } + } +`; + +export default function Org({ variables }) { + const { loading, error, data } = useQuery( + GET_ORG_QUERY, + { + variables: { id: 'my-dataset' } + } + ); + + ... + + const { organization } = data.dataset.result; + + return ( + <> + {organization ? ( + <> + + + + {organization.title || organization.name} + + + + ) : ( + '' + )} + + ); +} +``` + +#### Add a new data source + +TODO + ## Developers ### Boot the local instance