Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Providing Higher Order Functions for common getServerSideProps scenarios #7

Open
e1himself opened this issue Feb 2, 2022 · 3 comments

Comments

@e1himself
Copy link
Contributor

e1himself commented Feb 2, 2022

I had this idea with this package providing higher-order functions to provide extended context to the wrapped getServerSideProps function to simplify common scenarios.

An example using such approach with HTTP env headers and Prezly API client:

function withHttpEnv<Context extends GetServerSidePropsContext, Props>(
    getServerSideProps: (
        context: Context & { env: Env },
    ) => Props | Promise<Props>,
) {
    return function (context: Context) {
        const env = getEnvVariables(context.req);

        return getServerSideProps({ ...context, env });
    };
}
function withPrezlyApi<Context extends GetServerSidePropsContext, Props>(
    getServerSideProps: (
        context: Context & { api: PrezlyApi },
    ) => Props | Promise<Props>,
) {
    return withHttpEnv(function (context: Context) {
        const { PREZLY_ACCESS_TOKEN, PREZLY_NEWSROOM_UUID } = context.env;
        if (!PREZLY_ACCESS_TOKEN) {
           throw new Error('"PREZLY_ACCESS_TOKEN" is not set in env variables.');
        }
        if (!PREZLY_NEWSROOM_UUID) {
           throw new Error('"PREZLY_NEWSROOM_UUID" is not set in env variables.');
        }
    
        const api = new PrelzlyApi(PREZLY_ACCESS_TOKEN, PREZLY_NEWSROOM_UUID);
        
        return getServerSideProps({ ...context, api });
    });
}

and then the usage will be something like this:

export const getServerSideProps: GetServerSideProps<BasePageProps> = withPrezlyApi(async (context) => {
    const api = context.api; 
    const env = context.env;
    // use API and env
});

what do guys you think about this approach?

@riffbyte
Copy link
Contributor

riffbyte commented Feb 2, 2022

So basically it's just about converting the utility functions (getPrezlyApi and getEnvVariables) into HOC functions?
From what I see it would make the getNewsroomServerSideProps function a bit simpler, since it wouldn't need to initialize and return the api object anymore, using it from the context instead.

Are there any other improvements to the DX that we can make with these? 🤔

UPD: I see that it would help to make scenarios like this one a bit cleaner, so that sound like a great idea actually. Although I would still allow using the current getPrezlyApi and getEnvVariables methods as-is, since they are not actually dependent on Context (e.g. they are used in /api endpoints, which don't have the same context that pages do, so they wouldn't benefit from such HOC functions)

@e1himself
Copy link
Contributor Author

Are there any other improvements to the DX that we can make with these?

Anything. For example, typically fetched page props can be done with a HOF and passed to the wrapped function as a second argument (or alternatively within the context object):

export const getServerSideProps: GetServerSideProps<BasePageProps> = withStoryPageProps(async (context, props) => {
    const { story, translations, languages, newsroom, theme, preset } = props;
    const discourseUrl = ...;
     
   return {
      props: { 
          ...props,
          discourseUrl,
      };
   };
});

@riffbyte
Copy link
Contributor

This was kind of addressed in #31 (although not in a HOF way).
We'll need to see if the approach made in that PR would be good enough. If not, we can convert it to the proposed HOF approach, which should be a bit cleaner code-wise.

e1himself pushed a commit that referenced this issue Oct 17, 2023
Update Filipino translation
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants